Re: [PATCH v3 2/4] scsi: host: allocate struct Scsi_Host on the NUMA node of the host adapter
From: John Garry <john.g.garry@oracle.com>
Date: 2026-06-09 13:05:50
Also in:
linux-block, linux-hyperv, linux-scsi, target-devel, virtualization, xen-devel
On 09/06/2026 13:18, Sumit Saxena wrote:
scsi_host_alloc() used kzalloc(), which always picks an arbitrary node.
Extend the function to accept a 'struct device *dev' parameter and use
kzalloc_node() with dev_to_node(dev) so the Scsi_Host struct lands on
the same NUMA node as the HBA, mirroring the treatment already applied
to struct scsi_device, struct scsi_target, and shost_data.
When dev is NULL (legacy ISA/platform drivers without a dma_dev) the
allocation falls back to NUMA_NO_NODE, preserving existing behaviour.
Update all in-tree callers:
- PCI-based HBA drivers pass &pdev->dev (or the equivalent struct
member such as &phba->pcidev->dev, &h->pdev->dev, &ha->pdev->dev)
so their host struct is placed on the adapter's node.
- Non-PCI drivers (ISA, Amiga, ARM PCMCIA, virtio, Hyper-V, PS3, …)
pass NULL.
- libfc's libfc_host_alloc() inline helper passes NULL; FC drivers
that want NUMA awareness can open-code the call with their pdev.
Suggested-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: Sumit Saxena <sumit.saxena@broadcom.com>Wow ... I was not expecting such a large change, but admittedly I did not consider the implementation. I did mention that pci-based adapters should already be effectively doing kzalloc_node() since the adapter driver is probed on the local NUMA node (and kmalloc first tries local NUMA allocations).
---
quoted hunk ↗ jump to hunk
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index e047747d4ecf..e1f42be79729 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c@@ -403,12 +403,14 @@ static const struct device_type scsi_host_type = { * Return value: * Pointer to a new Scsi_Host **/ -struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int privsize) +struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int privsize, + struct device *dev) { struct Scsi_Host *shost; int index; - shost = kzalloc(sizeof(struct Scsi_Host) + privsize, GFP_KERNEL); + shost = kzalloc_node(sizeof(struct Scsi_Host) + privsize, GFP_KERNEL, + dev ? dev_to_node(dev) : NUMA_NO_NODE); if (!shost) return NULL;
-extern struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *, int); +extern struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, + int privsize, struct device *dev); extern int __must_check scsi_add_host_with_dma(struct Scsi_Host *, struct device *, struct device *);
scsi_add_host_with_dma() and scsi_add_host() do assignment of shost->dma_dev, so I think that could be moved to scsi_host_alloc(). I can imagine that we always know dev and dma_dev at Scsi_Host alloc time (and not just scsi_add_host()) time. However those would be very intrusive changes. Let me consider this more. Maybe we can have a platform device version of shost alloc, as I can't imagine that we care about much more. Thanks!