mirror of
https://github.com/torvalds/linux.git
synced 2026-10-07 19:16:02 +02:00
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 <chenchangcheng@kylinos.cn> Acked-by: Narsimhulu Musini <nmusini@cisco.com> Link: https://patch.msgid.link/20260727073438.209673-1-chenchangcheng@kylinos.cn Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org> |
||
|---|---|---|
| .. | ||
| cq_desc.h | ||
| cq_enet_desc.h | ||
| Makefile | ||
| snic_attrs.c | ||
| snic_ctl.c | ||
| snic_debugfs.c | ||
| snic_disc.c | ||
| snic_disc.h | ||
| snic_fwint.h | ||
| snic_io.c | ||
| snic_io.h | ||
| snic_isr.c | ||
| snic_main.c | ||
| snic_res.c | ||
| snic_res.h | ||
| snic_scsi.c | ||
| snic_stats.h | ||
| snic_trc.c | ||
| snic_trc.h | ||
| snic.h | ||
| vnic_cq_fw.h | ||
| vnic_cq.c | ||
| vnic_cq.h | ||
| vnic_dev.c | ||
| vnic_dev.h | ||
| vnic_devcmd.h | ||
| vnic_intr.c | ||
| vnic_intr.h | ||
| vnic_resource.h | ||
| vnic_snic.h | ||
| vnic_stats.h | ||
| vnic_wq.c | ||
| vnic_wq.h | ||
| wq_enet_desc.h | ||