On Sun, 22 Feb 2026 02:08:12 +0000 <[email protected]> wrote: > From: Ankit Agrawal <[email protected]> > > During creation of the VM's SRAT table, the generic initiator entries > are added. Currently the order in the entries are not controllable from > the qemu command. This is due to the fact that the code queries the > object tree which may not be in the order objects were inserted. > > As a fix the patch maintains a GPtrArray of generic initiator objects > that preserves their insertion order. Objects are automatically added > to the array when initialized and removed when finalized. When building > the SRAT table, objects are processed in the order they were first > inserted.
so question would be, why does it matter? Is ther a requirement in spec for SRAT entries being put in a particular order? > > E.g. for the following qemu command. > ... > -object acpi-generic-initiator,id=gi0,pci-dev=dev0,node=2 \ > -object acpi-generic-initiator,id=gi1,pci-dev=dev0,node=3 \ > -object acpi-generic-initiator,id=gi2,pci-dev=dev0,node=4 \ > -object acpi-generic-initiator,id=gi3,pci-dev=dev0,node=5 \ > -object acpi-generic-initiator,id=gi4,pci-dev=dev0,node=6 \ > -object acpi-generic-initiator,id=gi5,pci-dev=dev0,node=7 \ > -object acpi-generic-initiator,id=gi6,pci-dev=dev0,node=8 \ > -object acpi-generic-initiator,id=gi7,pci-dev=dev0,node=9 \ > ... > > Original PXM in the VM SRAT table: > [1A4h 0420 004h] Proximity Domain : 00000007 > [1C4h 0452 004h] Proximity Domain : 00000006 > [1E4h 0484 004h] Proximity Domain : 00000005 > [204h 0516 004h] Proximity Domain : 00000004 > [224h 0548 004h] Proximity Domain : 00000003 > [244h 0580 004h] Proximity Domain : 00000009 > [264h 0612 004h] Proximity Domain : 00000002 > [284h 0644 004h] Proximity Domain : 00000008 > [2A2h 0674 004h] Proximity Domain : 00000009 > > After the patch (preserves insertion order): > [1A4h 0420 004h] Proximity Domain : 00000002 > [1C4h 0452 004h] Proximity Domain : 00000003 > [1E4h 0484 004h] Proximity Domain : 00000004 > [204h 0516 004h] Proximity Domain : 00000005 > [224h 0548 004h] Proximity Domain : 00000006 > [244h 0580 004h] Proximity Domain : 00000007 > [264h 0612 004h] Proximity Domain : 00000008 > [284h 0644 004h] Proximity Domain : 00000009 > > cc: Shameer Kolothum <[email protected]> > Fixes: 0a5b5acdf2 ("hw/acpi: Implement the SRAT GI affinity structure") > Signed-off-by: Ankit Agrawal <[email protected]> > --- > hw/acpi/pci.c | 44 ++++++++++++++++++++++++++++++++------------ > 1 file changed, 32 insertions(+), 12 deletions(-) > > diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c > index 8c7ed10479..d97e6e9105 100644 > --- a/hw/acpi/pci.c > +++ b/hw/acpi/pci.c > @@ -88,18 +88,30 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(AcpiGenericInitiator, > acpi_generic_initiator, > > OBJECT_DECLARE_SIMPLE_TYPE(AcpiGenericInitiator, ACPI_GENERIC_INITIATOR) > > +static GPtrArray *acpi_generic_initiator_list; > + > static void acpi_generic_initiator_init(Object *obj) > { > AcpiGenericInitiator *gi = ACPI_GENERIC_INITIATOR(obj); > > gi->node = MAX_NODES; > gi->pci_dev = NULL; > + > + /* Initialize array on first use */ > + if (!acpi_generic_initiator_list) { > + acpi_generic_initiator_list = g_ptr_array_new(); > + } > + > + g_ptr_array_add(acpi_generic_initiator_list, gi); > } > > static void acpi_generic_initiator_finalize(Object *obj) > { > AcpiGenericInitiator *gi = ACPI_GENERIC_INITIATOR(obj); > > + if (acpi_generic_initiator_list) { > + g_ptr_array_remove(acpi_generic_initiator_list, gi); > + } > g_free(gi->pci_dev); > } > > @@ -145,20 +157,15 @@ static void > acpi_generic_initiator_class_init(ObjectClass *oc, const void *data) > "NUMA node associated with the PCI device"); > } > > -static int build_acpi_generic_initiator(Object *obj, void *opaque) > + > +static void build_acpi_generic_initiator(AcpiGenericInitiator *gi, > + GArray *table_data) > { > MachineState *ms = MACHINE(qdev_get_machine()); > - AcpiGenericInitiator *gi; > - GArray *table_data = opaque; > int32_t devfn; > uint8_t bus; > Object *o; > > - if (!object_dynamic_cast(obj, TYPE_ACPI_GENERIC_INITIATOR)) { > - return 0; > - } > - > - gi = ACPI_GENERIC_INITIATOR(obj); > if (gi->node >= ms->numa_state->num_nodes) { > error_printf("%s: Specified node %d is invalid.\n", > TYPE_ACPI_GENERIC_INITIATOR, gi->node); > @@ -178,8 +185,22 @@ static int build_acpi_generic_initiator(Object *obj, > void *opaque) > assert(devfn >= 0 && devfn < PCI_DEVFN_MAX); > > build_srat_pci_generic_initiator(table_data, gi->node, 0, bus, devfn); > +} > > - return 0; > +static void build_all_acpi_generic_initiators(GArray *table_data) > +{ > + AcpiGenericInitiator *gi; > + guint i; > + > + if (!acpi_generic_initiator_list) { > + return; > + } > + > + /* Iterate array in insertion order */ > + for (i = 0; i < acpi_generic_initiator_list->len; i++) { > + gi = g_ptr_array_index(acpi_generic_initiator_list, i); > + build_acpi_generic_initiator(gi, table_data); > + } > } > > typedef struct AcpiGenericPort { > @@ -295,9 +316,8 @@ static int build_acpi_generic_port(Object *obj, void > *opaque) > > void build_srat_generic_affinity_structures(GArray *table_data) > { > - object_child_foreach_recursive(object_get_root(), > - build_acpi_generic_initiator, > - table_data); > + build_all_acpi_generic_initiators(table_data); > + > object_child_foreach_recursive(object_get_root(), > build_acpi_generic_port, > table_data); > }
