Re: [PATCH v14 02/11] s390x/cpu topology: add topology entries on CPU hotplug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 1/10/23 14:00, Thomas Huth wrote:
On 05/01/2023 15.53, Pierre Morel wrote:
The topology information are attributes of the CPU and are
specified during the CPU device creation.

On hot plug, we gather the topology information on the core,
creates a list of topology entries, each entry contains a single
core mask of each core with identical topology and finaly we
orders the list in topological order.
The topological order is, from higher to lower priority:
- physical topology
     - drawer
     - book
     - socket
     - core origin, offset in 64bit increment from core 0.
- modifier attributes
     - CPU type
     - polarization entitlement
     - dedication

The possibility to insert a CPU in a mask is dependent on the
number of cores allowed in a socket, a book or a drawer, the
checking is done during the hot plug of the CPU to have an
immediate answer.

If the complete topology is not specified, the core is added
in the physical topology based on its core ID and it gets
defaults values for the modifier attributes.

This way, starting QEMU without specifying the topology can
still get some adventage of the CPU topology.

s/adventage/advantage/

Signed-off-by: Pierre Morel <pmorel@xxxxxxxxxxxxx>
---
  include/hw/s390x/cpu-topology.h |  48 ++++++
  hw/s390x/cpu-topology.c         | 293 ++++++++++++++++++++++++++++++++
  hw/s390x/s390-virtio-ccw.c      |  10 ++
  hw/s390x/meson.build            |   1 +
  4 files changed, 352 insertions(+)
  create mode 100644 hw/s390x/cpu-topology.c

diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h
index d945b57fc3..b3fd752d8d 100644
--- a/include/hw/s390x/cpu-topology.h
+++ b/include/hw/s390x/cpu-topology.h
@@ -10,7 +10,11 @@
  #ifndef HW_S390X_CPU_TOPOLOGY_H
  #define HW_S390X_CPU_TOPOLOGY_H
+#include "qemu/queue.h"
+#include "hw/boards.h"
+
  #define S390_TOPOLOGY_CPU_IFL   0x03
+#define S390_TOPOLOGY_MAX_ORIGIN ((63 + S390_MAX_CPUS) / 64)
  #define S390_TOPOLOGY_POLARITY_HORIZONTAL      0x00
  #define S390_TOPOLOGY_POLARITY_VERTICAL_LOW    0x01
@@ -20,4 +24,48 @@
  #define S390_TOPOLOGY_SHARED    0x00
  #define S390_TOPOLOGY_DEDICATED 0x01
+typedef union s390_topology_id {
+    uint64_t id;
+    struct {
+        uint64_t level_6:8; /* byte 0 BE */
+        uint64_t level_5:8; /* byte 1 BE */
+        uint64_t drawer:8;  /* byte 2 BE */
+        uint64_t book:8;    /* byte 3 BE */
+        uint64_t socket:8;  /* byte 4 BE */
+        uint64_t rsrv:5;
+        uint64_t d:1;
+        uint64_t p:2;       /* byte 5 BE */
+        uint64_t type:8;    /* byte 6 BE */
+        uint64_t origin:2;
+        uint64_t core:6;    /* byte 7 BE */
+    };
+} s390_topology_id;

Bitmasks are OK for code that will definitely only ever work with KVM ... but this will certainly fail completely if we ever try to get it running with TCG later. Do we care? ... if so, you should certainly avoid a bitfield here. Especially since most of the fields are 8-bit anyway and could easily be represented by a "uint8_t" variable. Otherwise, just ignore my comment.

The goal of using a bit mask here is not to use it with KVM but to have an easy way to order the TLE using the natural order of the placement of the fields in the uint64_t However, if I remove the two unused levels 5 and 6 I can use uint8_t for all the entries.

I doubt we use the levels 5 and 6 in a short future.

So I switch on 1 uint8_t for each entry.

...

diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c
new file mode 100644
index 0000000000..438055c612
--- /dev/null
+++ b/hw/s390x/cpu-topology.c
@@ -0,0 +1,293 @@
+/*
+ * CPU Topology
+ *
+ * Copyright IBM Corp. 2022

Want to update to 2023 now?

+ * Author(s): Pierre Morel <pmorel@xxxxxxxxxxxxx>
+
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "hw/qdev-properties.h"
+#include "hw/boards.h"
+#include "qemu/typedefs.h"
+#include "target/s390x/cpu.h"
+#include "hw/s390x/s390-virtio-ccw.h"
+#include "hw/s390x/cpu-topology.h"
+
+/*
+ * s390_topology is used to keep the topology information.
+ * .list: queue the topology entries inside which
+ *        we keep the information on the CPU topology.
+ *
+ * .smp: keeps track of the machine topology.
+ *
+ * .socket: tracks information on the count of cores per socket.
+ *
+ */
+S390Topology s390_topology = {
+    .list = QTAILQ_HEAD_INITIALIZER(s390_topology.list),
+    .sockets = NULL, /* will be initialized after the cpu model is realized */
+};
+
+/**
+ * s390_socket_nb:
+ * @id: s390_topology_id
+ *
+ * Returns the socket number used inside the socket array.
+ */
+static int s390_socket_nb(s390_topology_id id)
+{
+    return (id.socket + 1) * (id.book + 1) * (id.drawer + 1); > +}
I think there might be an off-by-one error in here - you likely need a "- 1" at the very end.

For example, assume that we have one socket, one book and one drawer, so id.socket, id.book and id.drawer would all be 0. The function then returns 1 ...

hum, I fear it is even more false than that but thanks for pointing this error.

 /o\

    return (id.drawer * s390_topology.smp.books + id.book) *
           s390_topology.smp.sockets + id.socket;



+static void s390_topology_init(MachineState *ms)
+{
+    CpuTopology *smp = &ms->smp;
+
+    s390_topology.smp = smp;
+    if (!s390_topology.sockets) {
+        s390_topology.sockets = g_new0(uint8_t, smp->sockets *
+                                       smp->books * smp->drawers);

... but here you only allocated one byte. So you later access s390_topology.sockets[s390_socket_nb(id)], i.e. s390_topology.sockets[1] which is out of bounds.

Yes, thanks.

Regards,
Pierre


--
Pierre Morel
IBM Lab Boeblingen



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux