Re: [PATCH v6 12/24] iommu/amd: Store per-segment iommu_dev_data in an xarray
From: Vasant Hegde
Date: Mon Oct 19 2026 - 09:43:31 EST
On 9/30/2026 2:53 PM, Suravee Suthikulpanit wrote:
> Replace the per-segment llist of iommu_dev_data with an xarray keyed
> by devid so lookup is O(1). These objects stay immortal for the life
> of the PCI segment: amd_iommu_release_device() keeps them for replug,
> and IRQ/DTE paths look them up locklessly via xa_load().
>
> Same-devid intern on xa_cmpxchg() covers replug and racing
> find_dev_data(). Aliases still get separate keys. Intern remains
> local to iommu.c; only the lookup table changes.
>
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx>
> ---
> drivers/iommu/amd/amd_iommu_types.h | 6 ++---
> drivers/iommu/amd/init.c | 4 +++-
> drivers/iommu/amd/iommu.c | 34 +++++++++++++++--------------
> 3 files changed, 24 insertions(+), 20 deletions(-)
.../...
> + * Allocate an immortal per-devid object stored in pci_seg->dev_data_xa.
> + * These are never erased: amd_iommu_release_device() keeps them for
> + * replug, and IRQ/DTE paths look them up locklessly via xa_load().
> + */
> static struct iommu_dev_data *alloc_dev_data(struct amd_iommu *iommu, u16 devid)
> {
> - struct iommu_dev_data *dev_data;
> + struct iommu_dev_data *dev_data, *old;
> struct amd_iommu_pci_seg *pci_seg = iommu->pci_seg;
>
> dev_data = kzalloc_obj(*dev_data);
> @@ -404,26 +409,23 @@ static struct iommu_dev_data *alloc_dev_data(struct amd_iommu *iommu, u16 devid)
> dev_data->devid = devid;
> ratelimit_default_init(&dev_data->rs);
>
> - llist_add(&dev_data->dev_data_list, &pci_seg->dev_data_list);
> + old = xa_cmpxchg(&pci_seg->dev_data_xa, devid, NULL, dev_data,
> + GFP_KERNEL);
> + if (xa_is_err(old)) {> + kfree(dev_data);
> + return NULL;
> + }
> + if (old) {
If old is valid means someone is already using devid. Allocation should fails if
xa_array is not empty.
-Vasant