From: Pierre Morel <pmorel@linux.ibm.com>
To: Nina Schoetterl-Glausch <nsg@linux.ibm.com>, qemu-s390x@nongnu.org
Cc: qemu-devel@nongnu.org, borntraeger@de.ibm.com,
pasic@linux.ibm.com, richard.henderson@linaro.org,
david@redhat.com, thuth@redhat.com, cohuck@redhat.com,
mst@redhat.com, pbonzini@redhat.com, kvm@vger.kernel.org,
ehabkost@redhat.com, marcel.apfelbaum@gmail.com,
eblake@redhat.com, armbru@redhat.com, seiden@linux.ibm.com,
nrb@linux.ibm.com, frankja@linux.ibm.com, berrange@redhat.com,
clg@kaod.org
Subject: Re: [PATCH v15 03/11] target/s390x/cpu topology: handle STSI(15) and build the SYSIB
Date: Mon, 6 Feb 2023 11:06:47 +0100 [thread overview]
Message-ID: <91372a70-660e-8b30-4062-ccbb50226c99@linux.ibm.com> (raw)
In-Reply-To: <7785ea2cb7530647fcc38321d81745ce16f8055f.camel@linux.ibm.com>
On 2/3/23 18:36, Nina Schoetterl-Glausch wrote:
> On Wed, 2023-02-01 at 14:20 +0100, Pierre Morel wrote:
>>> On interception of STSI(15.1.x) the System Information Block
>>> (SYSIB) is built from the list of pre-ordered topology entries.
>>>
>>> Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
>>> ---
>>> include/hw/s390x/cpu-topology.h | 22 +++
>>> include/hw/s390x/sclp.h | 1 +
>>> target/s390x/cpu.h | 72 +++++++
>>> hw/s390x/cpu-topology.c | 10 +
>>> target/s390x/kvm/cpu_topology.c | 335 ++++++++++++++++++++++++++++++++
>>> target/s390x/kvm/kvm.c | 5 +-
>>> target/s390x/kvm/meson.build | 3 +-
>>> 7 files changed, 446 insertions(+), 2 deletions(-)
>>> create mode 100644 target/s390x/kvm/cpu_topology.c
>>>
> [...]
>>>
>>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>>> index d654267a71..e1f6925856 100644
>>> --- a/target/s390x/cpu.h
>>> +++ b/target/s390x/cpu.h
> [...]
>>> +
>>> +/* CPU type Topology List Entry */
>>> +typedef struct SysIBTl_cpu {
>>> + uint8_t nl;
>>> + uint8_t reserved0[3];
>>> +#define SYSIB_TLE_POLARITY_MASK 0x03
>>> +#define SYSIB_TLE_DEDICATED 0x04
>>> + uint8_t entitlement;
>
> I would just call this flags, since it's multiple fields.
OK
>
>>> + uint8_t type;
>>> + uint16_t origin;
>>> + uint64_t mask;
>>> +} QEMU_PACKED QEMU_ALIGNED(8) SysIBTl_cpu;
>>> +QEMU_BUILD_BUG_ON(sizeof(SysIBTl_cpu) != 16);
>>>
>>> +
>>>
> [...]
>>> /**
>>> diff --git a/target/s390x/kvm/cpu_topology.c b/target/s390x/kvm/cpu_topology.c
>>> new file mode 100644
>>> index 0000000000..aba141fb66
>>> --- /dev/null
>>> +++ b/target/s390x/kvm/cpu_topology.c
>>>
> [...]
>>> +
>>> +/*
>>> + * Macro to check that the size of data after increment
>>> + * will not get bigger than the size of the SysIB.
>>> + */
>>> +#define SYSIB_GUARD(data, x) do { \
>>> + data += x; \
>>> + if (data > sizeof(SysIB)) { \
>>> + return -ENOSPC; \
>
> I would go with ENOMEM here.
Considering your comment of the length in insert_stsi_15_1_x(), I think
the best would be to return 0.
Because:
- We do not need to report any error reason.
- The value will be forwarded to insert_stsi_15_1_x() as the length of
the SYSIB to write
- On error we do not write the SYSIB (len = 0)
- In normal case the return value is always non zero and positive.
>
>>> + } \
>>> + } while (0)
>>> +
>>> +/**
>>> + * stsi_set_tle:
>>> + * @p: A pointer to the position of the first TLE
>>> + * @level: The nested level wanted by the guest
>>> + *
>>> + * Loop inside the s390_topology.list until the sentinelle entry
>
> s/sentinelle/sentinel/
OK, thx,
>
>>> + * is found and for each entry:
>>> + * - Check using SYSIB_GUARD() that the size of the SysIB is not
>>> + * reached.
>>> + * - Add all the container TLE needed for the level
>>> + * - Add the CPU TLE.
>
> I'd focus more on *what* the function does instead of *how*.
Right.
>
> Fill the SYSIB with the topology information as described in the PoP,
> nesting containers as appropriate, with the maximum nesting limited by @level.
>
> Or something similar.
Thanks, looks good to me .
>
>>> + *
>>> + * Return value:
>>> + * s390_top_set_level returns the size of the SysIB_15x after being
>
> You forgot to rename the function here, right?
> How about stsi_fill_topology_sysib or stsi_topology_fill_sysib, instead?
OK with stsi_topology_fill_sysib()
>
>>> + * filled with TLE on success.
>>> + * It returns -ENOSPC in the case we would overrun the end of the SysIB.
>
> You would have to change to ENOMEM here than also.
As discussed above, it seems to me that return 0 is even better.
>
>>> + */
>>> +static int stsi_set_tle(char *p, int level)
>>> +{
>>> + S390TopologyEntry *entry;
>>> + int last_drawer = -1;
>>> + int last_book = -1;
>>> + int last_socket = -1;
>>> + int drawer_id = 0;
>>> + int book_id = 0;
>>> + int socket_id = 0;
>>> + int n = sizeof(SysIB_151x);
>>> +
>>> + QTAILQ_FOREACH(entry, &s390_topology.list, next) {
>>> + int current_drawer = entry->id.drawer;
>>> + int current_book = entry->id.book;
>>> + int current_socket = entry->id.socket;
>
> This only saves two characters, so you could just use entry->id. ...
OK
>
>>> + bool drawer_change = last_drawer != current_drawer;
>>> + bool book_change = drawer_change || last_book != current_book;
>>> + bool socket_change = book_change || last_socket != current_socket;
>
> ... but keep it if it would make this line too long.
it is OK
> You could also rename entry, to current or cur, if you want to emphasize that.
>
>>> +
>>> + /* If we reach the guard get out */
>>> + if (entry->id.level5) {
>>> + break;
>>> + }
>>> +
>>> + if (level > 3 && drawer_change) {
>>> + SYSIB_GUARD(n, sizeof(SysIBTl_container));
>>> + p = fill_container(p, 3, drawer_id++);
>>> + book_id = 0;
>>> + }
>>> + if (level > 2 && book_change) {
>>> + SYSIB_GUARD(n, sizeof(SysIBTl_container));
>>> + p = fill_container(p, 2, book_id++);
>>> + socket_id = 0;
>>> + }
>>> + if (socket_change) {
>>> + SYSIB_GUARD(n, sizeof(SysIBTl_container));
>>> + p = fill_container(p, 1, socket_id++);
>>> + }
>>> +
>>> + SYSIB_GUARD(n, sizeof(SysIBTl_cpu));
>>> + p = fill_tle_cpu(p, entry);
>>> + last_drawer = entry->id.drawer;
>>> + last_book = entry->id.book;
>>> + last_socket = entry->id.socket;
>>> + }
>>> +
>>> + return n;
>>> +}
>>> +
>>> +/**
>>> + * setup_stsi:
>>> + * sysib: pointer to a SysIB to be filled with SysIB_151x data
>>> + * level: Nested level specified by the guest
>>> + *
>>> + * Setup the SysIB_151x header before calling stsi_set_tle with
>>> + * a pointer to the first TLE entry.
>
> Same thing here with regards to describing the what.
>
> Setup the SYSIB for STSI 15.1, the header as well as the description
> of the topology.
OK, thx
>
>>> + */
>>> +static int setup_stsi(SysIB_151x *sysib, int level)
>>> +{
>>> + sysib->mnest = level;
>>> + switch (level) {
>>> + case 4:
>>> + sysib->mag[S390_TOPOLOGY_MAG4] = current_machine->smp.drawers;
>>> + sysib->mag[S390_TOPOLOGY_MAG3] = current_machine->smp.books;
>>> + sysib->mag[S390_TOPOLOGY_MAG2] = current_machine->smp.sockets;
>>> + sysib->mag[S390_TOPOLOGY_MAG1] = current_machine->smp.cores;
>>> + break;
>>> + case 3:
>>> + sysib->mag[S390_TOPOLOGY_MAG3] = current_machine->smp.drawers *
>>> + current_machine->smp.books;
>>> + sysib->mag[S390_TOPOLOGY_MAG2] = current_machine->smp.sockets;
>>> + sysib->mag[S390_TOPOLOGY_MAG1] = current_machine->smp.cores;
>>> + break;
>>> + case 2:
>>> + sysib->mag[S390_TOPOLOGY_MAG2] = current_machine->smp.drawers *
>>> + current_machine->smp.books *
>>> + current_machine->smp.sockets;
>>> + sysib->mag[S390_TOPOLOGY_MAG1] = current_machine->smp.cores;
>>> + break;
>>> + }
>>> +
>>> + return stsi_set_tle(sysib->tle, level);
>>> +}
>>> +
>>> +/**
>>> + * s390_topology_add_cpu_to_entry:
>>> + * @entry: Topology entry to setup
>>> + * @cpu: the S390CPU to add
>>> + *
>>> + * Set the core bit inside the topology mask and
>>> + * increments the number of cores for the socket.
>>> + */
>>> +static void s390_topology_add_cpu_to_entry(S390TopologyEntry *entry,
>>> + S390CPU *cpu)
>>> +{
>>> + set_bit(63 - (cpu->env.core_id % 64), &entry->mask);
>>> +}
>>> +
>>> +/**
>>> + * s390_topology_new_entry:
>>> + * @id: s390_topology_id to add
>>> + * @cpu: the S390CPU to add
>>> + *
>>> + * Allocate a new entry and initialize it.
>>> + *
>>> + * returns the newly allocated entry.
>>> + */
>>> +static S390TopologyEntry *s390_topology_new_entry(s390_topology_id id,
>>> + S390CPU *cpu)
>
> This is used only once, right?
> I think I'd go ahead and inline it into s390_topology_insert, since I had
> to go back and check if new_entry calls add_cpu when reading s390_topology_insert.
OK
>
>>> +{
>>> + S390TopologyEntry *entry;
>>> +
>>> + entry = g_malloc0(sizeof(S390TopologyEntry));
>>> + entry->id.id = id.id;
>>> + s390_topology_add_cpu_to_entry(entry, cpu);
>>> +
>>> + return entry;
>>> +}
>>> +
>>> +/**
>>> + * s390_topology_from_cpu:
>>> + * @cpu: The S390CPU
>>> + *
>>> + * Initialize the topology id from the CPU environment.
>>> + */
>>> +static s390_topology_id s390_topology_from_cpu(S390CPU *cpu)
>>> +{
>>> + s390_topology_id topology_id = {0};
>>> +
>>> + topology_id.drawer = cpu->env.drawer_id;
>>> + topology_id.book = cpu->env.book_id;
>>> + topology_id.socket = cpu->env.socket_id;
>>> + topology_id.origin = cpu->env.core_id / 64;
>>> + topology_id.type = S390_TOPOLOGY_CPU_IFL;
>>> + topology_id.dedicated = cpu->env.dedicated;
>>> +
>>> + if (s390_topology.polarity == POLARITY_VERTICAL) {
>>> + /*
>>> + * Vertical polarity with dedicated CPU implies
>>> + * vertical high entitlement.
>>> + */
>>> + if (topology_id.dedicated) {
>>> + topology_id.polarity |= POLARITY_VERTICAL_HIGH;
>>> + } else {
>>> + topology_id.polarity |= cpu->env.entitlement;
>>> + }
>>> + }
>>> +
>>> + return topology_id;
>>> +}
>>> +
>>> +/**
>>> + * s390_topology_insert:
>>> + * @cpu: s390CPU insert.
>>> + *
>>> + * Parse the topology list to find if the entry already
>>> + * exist and add the core in it.
>>> + * If it does not exist, allocate a new entry and insert
>>> + * it in the queue from lower id to greater id.
>>> + */
>>> +static void s390_topology_insert(S390CPU *cpu)
>>> +{
>>> + s390_topology_id id = s390_topology_from_cpu(cpu);
>>> + S390TopologyEntry *entry = NULL;
>>> + S390TopologyEntry *tmp = NULL;
>>> +
>>> + QTAILQ_FOREACH(tmp, &s390_topology.list, next) {
>>> + if (id.id == tmp->id.id) {
>>> + s390_topology_add_cpu_to_entry(tmp, cpu);
>>> + return;
>>> + } else if (id.id < tmp->id.id) {
>>> + entry = s390_topology_new_entry(id, cpu);
>>> + QTAILQ_INSERT_BEFORE(tmp, entry, next);
>>> + return;
>>> + }
>>> + }
>>> +}
>>> +
>>> +/**
>>> + * s390_order_tle:
>>> + *
>>> + * Loop over all CPU and insert it at the right place
>>> + * inside the TLE entry list.
>>> + */
>
> Suggestion:
>
> s390_topology_fill_list_sorted
>
> Fill the S390Topology list with entries according to the order specified
> by the PoP.
OK
>
>>> +static void s390_order_tle(void)
>>> +{
>>> + CPUState *cs;
>>> +
>>> + CPU_FOREACH(cs) {
>>> + s390_topology_insert(S390_CPU(cs));
>>> + }
>>> +}
>>> +
>>> +/**
>>> + * s390_free_tle:
>>> + *
>>> + * Loop over all TLE entries and free them.
>>> + * Keep the sentinelle which is the only one with level5 != 0
>
> s/sentinelle/sentinel/
yes, thx
>
>>> + */
>
> Suggestion:
> s390_topology_empty_list
>
> Clear all entries in the S390Topology list except the sentinel.
>
>>> +static void s390_free_tle(void)
>>> +{
>>> + S390TopologyEntry *entry = NULL;
>>> + S390TopologyEntry *tmp = NULL;
>>> +
>>> + QTAILQ_FOREACH_SAFE(entry, &s390_topology.list, next, tmp) {
>>> + if (!entry->id.level5) {
>>> + QTAILQ_REMOVE(&s390_topology.list, entry, next);
>>> + g_free(entry);
>>> + }
>>> + }
>>> +}
>>> +
>>> +/**
>>> + * insert_stsi_15_1_x:
>>> + * cpu: the CPU doing the call for which we set CC
>>> + * sel2: the selector 2, containing the nested level
>>> + * addr: Guest logical address of the guest SysIB
>>> + * ar: the access register number
>>> + *
>>> + * Reserve a zeroed SysIB, let setup_stsi to fill it and
>>> + * copy the SysIB to the guest memory.
>>> + *
>>> + * In case of overflow set CC(3) and no copy is done.
>
> Suggestion:
>
> Emulate STSI 15.1.x, that is, perform all necessary checks and fill the SYSIB.
> In case the topology description is too long to fit into the SYSIB,
> set CC=3 and abort without writing the SYSIB.
OK, better thanks.
>
>>> + */
>>> +void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar)
>>> +{
>>> + SysIB sysib = {0};
>>> + int len;
>>> +
>>> + if (!s390_has_topology() || sel2 < 2 || sel2 > SCLP_READ_SCP_INFO_MNEST) {
>>> + setcc(cpu, 3);
>>> + return;
>>> + }
>>> +
>>> + s390_order_tle();
>>> +
>>> + len = setup_stsi(&sysib.sysib_151x, sel2);
>>> +
>>> + if (len < 0) {
>
> I stumbled a bit over this, maybe rename len to r.
Why ? it is the length used to fill the length field of the SYSIB.
May be it would be clearer if we give back the length to write and 0 on
error then we have here:
if (!len) {
setcc(cpu, 3);
return;
}
>
>>> + setcc(cpu, 3);
>>> + return;
>>> + }
>>> +
>>> + sysib.sysib_151x.length = cpu_to_be16(len);
>>> + s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, len);
>>> + setcc(cpu, 0);
>>> +
>>> + s390_free_tle();
>>> +}
Thanks for the comments.
If there are only comments and cosmetic changes will I get your RB if I
change them according to your wishes?
Regards,
Pierre
--
Pierre Morel
IBM Lab Boeblingen
next prev parent reply other threads:[~2023-02-06 10:07 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-01 13:20 [PATCH v15 00/11] s390x: CPU Topology Pierre Morel
2023-02-01 13:20 ` [PATCH v15 01/11] s390x/cpu topology: adding s390 specificities to CPU topology Pierre Morel
2023-02-02 10:44 ` Thomas Huth
2023-02-02 13:15 ` Pierre Morel
2023-02-02 16:05 ` Nina Schoetterl-Glausch
2023-02-03 9:39 ` Pierre Morel
2023-02-03 11:21 ` Thomas Huth
2023-02-08 17:50 ` Nina Schoetterl-Glausch
2023-02-10 14:19 ` Pierre Morel
2023-02-01 13:20 ` [PATCH v15 02/11] s390x/cpu topology: add topology entries on CPU hotplug Pierre Morel
2023-02-02 16:42 ` Nina Schoetterl-Glausch
2023-02-03 9:21 ` Pierre Morel
2023-02-03 13:22 ` Nina Schoetterl-Glausch
2023-02-03 14:40 ` Pierre Morel
2023-02-03 15:38 ` Nina Schoetterl-Glausch
2023-02-01 13:20 ` [PATCH v15 03/11] target/s390x/cpu topology: handle STSI(15) and build the SYSIB Pierre Morel
2023-02-03 17:36 ` Nina Schoetterl-Glausch
2023-02-06 10:06 ` Pierre Morel [this message]
2023-02-06 10:32 ` Nina Schoetterl-Glausch
2023-02-06 11:24 ` Thomas Huth
2023-02-06 12:57 ` Pierre Morel
2023-02-09 16:39 ` Nina Schoetterl-Glausch
2023-02-10 14:16 ` Pierre Morel
2023-02-01 13:20 ` [PATCH v15 04/11] s390x/sclp: reporting the maximum nested topology entries Pierre Morel
2023-02-06 10:13 ` Thomas Huth
2023-02-06 10:19 ` Pierre Morel
2023-02-01 13:20 ` [PATCH v15 05/11] s390x/cpu topology: resetting the Topology-Change-Report Pierre Morel
2023-02-06 11:05 ` Thomas Huth
2023-02-06 12:50 ` Pierre Morel
2023-02-06 17:52 ` Nina Schoetterl-Glausch
2023-02-07 9:24 ` Pierre Morel
2023-02-07 10:50 ` Nina Schoetterl-Glausch
2023-02-07 12:19 ` Pierre Morel
2023-02-07 13:37 ` Nina Schoetterl-Glausch
2023-02-07 14:08 ` Pierre Morel
2023-02-01 13:20 ` [PATCH v15 06/11] s390x/cpu topology: interception of PTF instruction Pierre Morel
2023-02-06 11:38 ` Thomas Huth
2023-02-06 13:02 ` Pierre Morel
2023-02-06 18:34 ` Nina Schoetterl-Glausch
2023-02-07 9:59 ` Pierre Morel
2023-02-07 11:27 ` Nina Schoetterl-Glausch
2023-02-07 13:03 ` Pierre Morel
2023-02-01 13:20 ` [PATCH v15 07/11] target/s390x/cpu topology: activating CPU topology Pierre Morel
2023-02-06 11:57 ` Thomas Huth
2023-02-06 13:19 ` Pierre Morel
2023-02-01 13:20 ` [PATCH v15 08/11] qapi/s390x/cpu topology: x-set-cpu-topology monitor command Pierre Morel
2023-02-06 12:21 ` Thomas Huth
2023-02-06 14:03 ` Pierre Morel
2023-02-07 14:59 ` Pierre Morel
2023-02-08 18:40 ` Nina Schoetterl-Glausch
2023-02-09 13:14 ` Pierre Morel
2023-02-01 13:20 ` [PATCH v15 09/11] machine: adding s390 topology to query-cpu-fast Pierre Morel
2023-02-06 12:38 ` Thomas Huth
2023-02-06 14:12 ` Pierre Morel
2023-02-06 12:41 ` Thomas Huth
2023-02-06 12:49 ` Daniel P. Berrangé
2023-02-06 13:09 ` Thomas Huth
2023-02-06 14:50 ` Daniel P. Berrangé
2023-02-07 10:10 ` Thomas Huth
2023-02-06 14:16 ` Pierre Morel
2023-02-07 18:26 ` Nina Schoetterl-Glausch
2023-02-08 9:11 ` Pierre Morel
2023-02-01 13:20 ` [PATCH v15 10/11] qapi/s390x/cpu topology: CPU_POLARITY_CHANGE qapi event Pierre Morel
2023-02-08 17:35 ` Nina Schoetterl-Glausch
2023-02-08 19:23 ` Markus Armbruster
2023-02-09 12:28 ` Nina Schoetterl-Glausch
2023-02-09 13:00 ` Pierre Morel
2023-02-09 14:50 ` Nina Schoetterl-Glausch
2023-02-09 10:04 ` Daniel P. Berrangé
2023-02-09 12:12 ` Nina Schoetterl-Glausch
2023-02-09 12:15 ` Daniel P. Berrangé
2023-02-01 13:20 ` [PATCH v15 11/11] docs/s390x/cpu topology: document s390x cpu topology Pierre Morel
2023-02-08 16:22 ` Nina Schoetterl-Glausch
2023-02-09 17:14 ` [PATCH v15 00/11] s390x: CPU Topology Nina Schoetterl-Glausch
2023-02-10 13:23 ` Pierre Morel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=91372a70-660e-8b30-4062-ccbb50226c99@linux.ibm.com \
--to=pmorel@linux.ibm.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=borntraeger@de.ibm.com \
--cc=clg@kaod.org \
--cc=cohuck@redhat.com \
--cc=david@redhat.com \
--cc=eblake@redhat.com \
--cc=ehabkost@redhat.com \
--cc=frankja@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=nrb@linux.ibm.com \
--cc=nsg@linux.ibm.com \
--cc=pasic@linux.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=seiden@linux.ibm.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox