Skip to content

Commit fa46c6f

Browse files
keithbuschaxboe
authored andcommitted
nvme/pci: move cqe check after device shutdown
Many users have reported nvme triggered irq_startup() warnings during shutdown. The driver uses the nvme queue's irq to synchronize scanning for completions, and enabling an interrupt affined to only offline CPUs triggers the alarming warning. Move the final CQE check to after disabling the device and all registered interrupts have been torn down so that we do not have any IRQ to synchronize. Link: https://bugzilla.kernel.org/show_bug.cgi?id=206509 Reviewed-by: Sagi Grimberg <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Keith Busch <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 97b2512 commit fa46c6f

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

drivers/nvme/host/pci.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,23 @@ static void nvme_disable_admin_queue(struct nvme_dev *dev, bool shutdown)
14011401
nvme_poll_irqdisable(nvmeq, -1);
14021402
}
14031403

1404+
/*
1405+
* Called only on a device that has been disabled and after all other threads
1406+
* that can check this device's completion queues have synced. This is the
1407+
* last chance for the driver to see a natural completion before
1408+
* nvme_cancel_request() terminates all incomplete requests.
1409+
*/
1410+
static void nvme_reap_pending_cqes(struct nvme_dev *dev)
1411+
{
1412+
u16 start, end;
1413+
int i;
1414+
1415+
for (i = dev->ctrl.queue_count - 1; i > 0; i--) {
1416+
nvme_process_cq(&dev->queues[i], &start, &end, -1);
1417+
nvme_complete_cqes(&dev->queues[i], start, end);
1418+
}
1419+
}
1420+
14041421
static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues,
14051422
int entry_size)
14061423
{
@@ -2235,11 +2252,6 @@ static bool __nvme_disable_io_queues(struct nvme_dev *dev, u8 opcode)
22352252
if (timeout == 0)
22362253
return false;
22372254

2238-
/* handle any remaining CQEs */
2239-
if (opcode == nvme_admin_delete_cq &&
2240-
!test_bit(NVMEQ_DELETE_ERROR, &nvmeq->flags))
2241-
nvme_poll_irqdisable(nvmeq, -1);
2242-
22432255
sent--;
22442256
if (nr_queues)
22452257
goto retry;
@@ -2428,6 +2440,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
24282440
nvme_suspend_io_queues(dev);
24292441
nvme_suspend_queue(&dev->queues[0]);
24302442
nvme_pci_disable(dev);
2443+
nvme_reap_pending_cqes(dev);
24312444

24322445
blk_mq_tagset_busy_iter(&dev->tagset, nvme_cancel_request, &dev->ctrl);
24332446
blk_mq_tagset_busy_iter(&dev->admin_tagset, nvme_cancel_request, &dev->ctrl);

0 commit comments

Comments
 (0)