s390x/cpu topology: add topology entries on CPU hotplug

The topology information are attributes of the CPU and are
specified during the CPU device creation.

On hot plug we:
- calculate the default values for the topology for drawers,
  books and sockets in the case they are not specified.
- verify the CPU attributes
- check that we have still room on the desired socket

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 advantage of the CPU topology.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Message-ID: <20231016183925.2384704-4-nsg@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
Pierre Morel 2023-10-16 20:39:07 +02:00 committed by Thomas Huth
parent 5de1aff255
commit c809bbc8e9
5 changed files with 340 additions and 2 deletions

View file

@ -45,6 +45,7 @@
#include "target/s390x/kvm/pv.h"
#include "migration/blocker.h"
#include "qapi/visitor.h"
#include "hw/s390x/cpu-topology.h"
static Error *pv_mig_blocker;
@ -309,10 +310,18 @@ static void s390_cpu_plug(HotplugHandler *hotplug_dev,
{
MachineState *ms = MACHINE(hotplug_dev);
S390CPU *cpu = S390_CPU(dev);
ERRP_GUARD();
g_assert(!ms->possible_cpus->cpus[cpu->env.core_id].cpu);
ms->possible_cpus->cpus[cpu->env.core_id].cpu = OBJECT(dev);
if (s390_has_topology()) {
s390_topology_setup_cpu(ms, cpu, errp);
if (*errp) {
return;
}
}
if (dev->hotplugged) {
raise_irq_cpu_hotplug();
}
@ -562,11 +571,20 @@ static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
sizeof(CPUArchId) * max_cpus);
ms->possible_cpus->len = max_cpus;
for (i = 0; i < ms->possible_cpus->len; i++) {
CpuInstanceProperties *props = &ms->possible_cpus->cpus[i].props;
ms->possible_cpus->cpus[i].type = ms->cpu_type;
ms->possible_cpus->cpus[i].vcpus_count = 1;
ms->possible_cpus->cpus[i].arch_id = i;
ms->possible_cpus->cpus[i].props.has_core_id = true;
ms->possible_cpus->cpus[i].props.core_id = i;
props->has_core_id = true;
props->core_id = i;
props->has_socket_id = true;
props->socket_id = s390_std_socket(i, &ms->smp);
props->has_book_id = true;
props->book_id = s390_std_book(i, &ms->smp);
props->has_drawer_id = true;
props->drawer_id = s390_std_drawer(i, &ms->smp);
}
return ms->possible_cpus;