Re: [PATCH v3 2/4] scsi: host: allocate struct Scsi_Host on the NUMA node of the host adapter
John Garry <[email protected]> Tue, 9 Jun 2026 14:03:45 +0100
| Newsgroups | org.kernel.vger.target-devel,dev.linux.lists.virtualization,org.kernel.vger.linux-block,org.kernel.vger.linux-hyperv,org.kernel.vger.linux-scsi,org.ozlabs.lists.linuxppc-dev,org.xenproject.lists.xen-devel |
|---|---|
| Organization | Oracle Corporation |
| Message-ID | <[email protected]> |
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 <[email protected]> > Signed-off-by: Sumit Saxena <[email protected]> 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). > --- > 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!