Re: [PATCH v2 1/3] scsi: scan: allocate sdev and starget on the NUMA node of the host adapter

John Garry
2026-04-20T12:10:33Z

On 20/04/2026 12:38, Sumit Saxena wrote:
> From: James Rizzo <james.rizzo@broadcom.com>
>
> When a host adapter is attached to a specific NUMA node, allocating
> scsi_device and scsi_target via kzalloc() may place them on a remote
> node. All hot-path I/O accesses to these structures then cross the NUMA
> interconnect, adding latency and consuming inter-node bandwidth.
>
> Use kzalloc_node() with dev_to_node(shost->dma_dev) so allocations land
> on the same node as the HBA, reducing cross-node traffic and improving
> I/O performance on NUMA systems.

I suppose that this makes sense. We already do this sort of thing in
scsi_mq_setup_tags() (in setting numa node) and
scsi_realloc_sdev_budget_map() ->
sbitmap_init_node(sdev->request_queue->numa_node)

For the actual shost allocation, we still use kzalloc() in
scsi_host_alloc(). However, shost associated device is often a pci
device, and we probe pci devices in the same NUMA node it exists, and we
try NUMA local allocations by default, so nothing is needed to change
for the shost allocation - is this right?

>
> Signed-off-by: James Rizzo <james.rizzo@broadcom.com>
> Signed-off-by: Sumit Saxena <sumit.saxena@broadcom.com>
> ---
> drivers/scsi/scsi_scan.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
> index ef22a4228b85..9749a8dbe964 100644
> --- a/drivers/scsi/scsi_scan.c
> +++ b/drivers/scsi/scsi_scan.c
> @@ -34,6 +34,7 @@
> #include <linux/kthread.h>
> #include <linux/spinlock.h>
> #include <linux/async.h>
> +#include <linux/topology.h>f
> #include <linux/slab.h>
> #include <linux/unaligned.h>
>
> @@ -286,9 +287,10 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
> int display_failure_msg = 1, ret;
> struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
> struct queue_limits lim;
> + int node = dev_to_node(shost->dma_dev);

this variable is only used once, so we can use
dev_to_node(shost->dma_dev) directly

>
> - sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size,
> - GFP_KERNEL);
> + sdev = kzalloc_node(sizeof(*sdev) + shost->transportt->device_size,
> + GFP_KERNEL, node);
> if (!sdev)
> goto out;
>
> @@ -501,8 +503,9 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
> struct scsi_target *starget;
> struct scsi_target *found_target;
> int error, ref_got;
> + int node = dev_to_node(shost->dma_dev);

same as above

>
> - starget = kzalloc(size, GFP_KERNEL);
> + starget = kzalloc_node(size, GFP_KERNEL, node);
> if (!starget) {
> printk(KERN_ERR "%s: allocation failure\n", __func__);
> return NULL;