[PATCH v3 2/2] scsi: elx: efct: destroy the mailbox pools when setup fails
From: Ali Ahmet Memis
Date: Thu Aug 06 2026 - 17:07:30 EST
efct_hw_setup() creates two mempools and then calls sli_setup(). Its error
paths return without destroying what it already created:
hw->cmd_ctx_pool = mempool_create_kmalloc_pool(...);
if (!hw->cmd_ctx_pool)
return -EIO;
hw->mbox_rqst_pool = mempool_create_kmalloc_pool(...);
if (!hw->mbox_rqst_pool)
return -EIO;
...
if (sli_setup(&hw->sli, hw->os, pdev, ((struct efct *)os)->reg))
return -EIO;
mempool_destroy() for these two runs only in efct_hw_teardown(), which is
not reached here. efct_hw_setup() is called from
efct_device_interrupts_required() and from efct_xport_attach(). On the
probe path it is the first of those that runs, and when it fails
efct_pci_probe() unwinds through efct_device_free(), freeing the struct
efct that held the only pointers to the pools.
Destroy them on the way out, and clear hw_setup_called, which the function
sets before the first allocation, so that a later call does not take the
early return and hand the caller a half configured hw.
Reproduced by binding the driver to a PCI device that is not an SLI-4
adapter, so sli_setup() fails, and repeating the probe 61 times. Before,
with CONFIG_DEBUG_KMEMLEAK:
unreferenced object 0xffff888008449680 (size 96):
comm "init", pid 1
backtrace:
__kmalloc_cache_node_noprof+0x3b9/0x430
mempool_create_node_noprof+0x78/0xe0
efct_hw_setup+0x1db/0xb50
efct_pci_probe+0x3cb/0x6dd
local_pci_probe+0xd4/0x170
1566 objects in total, every one of them from efct_hw_setup(). After the
change the same run reports none, and the probe still fails the same way.
Fixes: 4df84e846624 ("scsi: elx: efct: Driver initialization routines")
Signed-off-by: Ali Ahmet Memis <ali@xxxxxxxxxxxxxx>
---
drivers/scsi/elx/efct/efct_hw.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/elx/efct/efct_hw.c b/drivers/scsi/elx/efct/efct_hw.c
index cc600220168a..20f4821078aa 100644
--- a/drivers/scsi/elx/efct/efct_hw.c
+++ b/drivers/scsi/elx/efct/efct_hw.c
@@ -256,7 +256,7 @@ efct_hw_setup(struct efct_hw *hw, void *os, struct pci_dev *pdev)
sizeof(struct efct_command_ctx));
if (!hw->cmd_ctx_pool) {
efc_log_err(hw->os, "failed to allocate mailbox buffer pool\n");
- return -EIO;
+ goto not_setup;
}
/* Create mailbox request ctx pool for library callback */
@@ -264,7 +264,7 @@ efct_hw_setup(struct efct_hw *hw, void *os, struct pci_dev *pdev)
sizeof(struct efct_mbox_rqst_ctx));
if (!hw->mbox_rqst_pool) {
efc_log_err(hw->os, "failed to allocate mbox request pool\n");
- return -EIO;
+ goto free_cmd_ctx_pool;
}
spin_lock_init(&hw->io_lock);
@@ -277,7 +277,7 @@ efct_hw_setup(struct efct_hw *hw, void *os, struct pci_dev *pdev)
hw->config.speed = SLI4_LINK_SPEED_AUTO_16_8_4;
if (sli_setup(&hw->sli, hw->os, pdev, ((struct efct *)os)->reg)) {
efc_log_err(hw->os, "SLI setup failed\n");
- return -EIO;
+ goto free_mbox_rqst_pool;
}
efct_hw_link_event_init(hw);
@@ -313,6 +313,17 @@ efct_hw_setup(struct efct_hw *hw, void *os, struct pci_dev *pdev)
(void)efct_hw_read_max_dump_size(hw);
return 0;
+
+free_mbox_rqst_pool:
+ mempool_destroy(hw->mbox_rqst_pool);
+ hw->mbox_rqst_pool = NULL;
+free_cmd_ctx_pool:
+ mempool_destroy(hw->cmd_ctx_pool);
+ hw->cmd_ctx_pool = NULL;
+not_setup:
+ hw->hw_setup_called = false;
+
+ return -EIO;
}
static void
--
2.55.0