Skip to content

Commit 7edaa46

Browse files
Keith Buschjfvogel
authored andcommitted
nvme-pci: fix rapid add remove sequence
A surprise removal may fail to tear down request queues if it is racing with the initial asynchronous probe. If that happens, the remove path won't see the queue resources to tear down, and the controller reset path may create a new request queue on a removed device, but will not be able to make forward progress, deadlocking the pci removal. Protect setting up non-blocking resources from a shutdown by holding the same mutex, and transition to the CONNECTING state after these resources are initialized so the probe path may see the dead controller state before dispatching new IO. Link: https://bugzilla.kernel.org/show_bug.cgi?id=202081 Reported-by: Alex Gagniuc <[email protected]> Signed-off-by: Keith Busch <[email protected]> Tested-by: Alex Gagniuc <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> (cherry picked from commit 5c959d7) Orabug: 29933720 Signed-off-by: Alan Adamson <[email protected]> Reviewed-by: John Donnelly <[email protected]>
1 parent 9550edd commit 7edaa46

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

drivers/nvme/host/pci.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,16 +2268,7 @@ static void nvme_reset_work(struct work_struct *work)
22682268
if (dev->ctrl.ctrl_config & NVME_CC_ENABLE)
22692269
nvme_dev_disable(dev, false);
22702270

2271-
/*
2272-
* Introduce CONNECTING state from nvme-fc/rdma transports to mark the
2273-
* initializing procedure here.
2274-
*/
2275-
if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) {
2276-
dev_warn(dev->ctrl.device,
2277-
"failed to mark controller CONNECTING\n");
2278-
goto out;
2279-
}
2280-
2271+
mutex_lock(&dev->shutdown_lock);
22812272
result = nvme_pci_enable(dev);
22822273
if (result)
22832274
goto out;
@@ -2296,6 +2287,17 @@ static void nvme_reset_work(struct work_struct *work)
22962287
*/
22972288
dev->ctrl.max_hw_sectors = NVME_MAX_KB_SZ << 1;
22982289
dev->ctrl.max_segments = NVME_MAX_SEGS;
2290+
mutex_unlock(&dev->shutdown_lock);
2291+
2292+
/*
2293+
* Introduce CONNECTING state from nvme-fc/rdma transports to mark the
2294+
* initializing procedure here.
2295+
*/
2296+
if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) {
2297+
dev_warn(dev->ctrl.device,
2298+
"failed to mark controller CONNECTING\n");
2299+
goto out;
2300+
}
22992301

23002302
result = nvme_init_identify(&dev->ctrl);
23012303
if (result)

0 commit comments

Comments
 (0)