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);
>  }


Reply via email to