Re: [PATCH] scsi: snic: Fix scsi host leak on workqueue allocation failure

"Narsimhulu Musini (nmusini)" <[email protected]>
Newsgroups org.kernel.vger.linux-scsi,org.kernel.vger.linux-kernel
Message-ID <IA0PR11MB7281FD7F32AB31000E83427BABCC2@IA0PR11MB7281.namprd11.prod.outlook.com>

________________________________________
From: Chen Changcheng <[email protected]>
Sent: 27 July 2026 12:34 AM
To: Karan Tilak Kumar (kartilak) <[email protected]>; Narsimhulu Musini (nmusini) <[email protected]>; Sesidhar Baddela (sebaddel) <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>
Cc: [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Chen Changcheng <[email protected]>
Subject: [PATCH] scsi: snic: Fix scsi host leak on workqueue allocation failure
 
In snic_add_host(), if scsi_add_host() succeeds but
alloc_ordered_workqueue() fails, the function returns -ENOMEM
with shost->work_q left as NULL. The caller's error path then
calls snic_del_host(), which returns early when !shost->work_q
without calling scsi_remove_host(). The Scsi_Host remains
registered in sysfs as a zombie device even after the probe
has failed. This causes:

 - The leaked host remains visible in /sys/class/scsi_host/
   after probe failure, with state "running".
 - Subsequent SCSI host numbering is permanently shifted
   (the leaked host ID from ida_alloc() is never reclaimed).
 - Memory leak: the Scsi_Host allocation can never be freed
   because device_add() took a reference that can only be
   released by device_del() inside scsi_remove_host().

Fix by adding scsi_remove_host() in the workqueue allocation
failure path inside snic_add_host(), undoing the successful
scsi_add_host() before returning the error. This is cleaner
than modifying snic_del_host() because snic_del_host() is
called from a shared error label that also serves paths where
snic_add_host() was never invoked.

Reproducer (requires no real SNIC hardware):
 - Build CONFIG_SCSI_SNIC=y (built-in)
 - Add snic.test_mode=1 snic.inject_wq_fail=1 to kernel cmdline
 - Boot with a PCI device matching the snic driver (e.g. QEMU
   edu device, PCI ID 0x1234:0x11e8, temporarily added to the
   driver's PCI ID table)

Before the fix:
  # /sys/class/scsi_host/ contains a zombie host0:
  $ cat /sys/class/scsi_host/host0/proc_name
  snic_scsi
  $ cat /sys/class/scsi_host/host0/state
  running
  # ata_piix gets host1, host2 (host0 stuck):
  scsi host1: ata_piix
  scsi host2: ata_piix

After the fix:
  # host0 is properly freed and reused by ata_piix:
  scsi host0: ata_piix
  scsi host1: ata_piix
  # No zombie host in /sys/class/scsi_host/

Signed-off-by: Chen Changcheng <[email protected]>
Acked-by: Narsimhulu Musini <[email protected]>
---
 drivers/scsi/snic/snic_main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c
index 82953e6a0915..cd638b4a4d7b 100644
--- a/drivers/scsi/snic/snic_main.c
+++ b/drivers/scsi/snic/snic_main.c
@@ -305,6 +305,7 @@ snic_add_host(struct Scsi_Host *shost, struct pci_dev *pdev)
         if (!shost->work_q) {
                 SNIC_HOST_ERR(shost, "Failed to Create ScsiHost wq.\n");
 
+               scsi_remove_host(shost);
                 ret = -ENOMEM;
         }
 
--
2.25.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.