@@ -2196,24 +2196,22 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
struct pci_dev *pdev = to_pci_dev(dev->dev);
mutex_lock(&dev->shutdown_lock);
- if (pci_is_enabled(pdev)) {
+ if (dev->ctrl.ctrl_config & NVME_CC_ENABLE &&
+ (dev->ctrl.state == NVME_CTRL_LIVE ||
+ dev->ctrl.state == NVME_CTRL_RESETTING)) {
u32 csts = readl(dev->bar + NVME_REG_CSTS);
- if (dev->ctrl.state == NVME_CTRL_LIVE ||
- dev->ctrl.state == NVME_CTRL_RESETTING)
- nvme_start_freeze(&dev->ctrl);
+ nvme_start_freeze(&dev->ctrl);
dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) ||
- pdev->error_state != pci_channel_io_normal);
+ pci_channel_offline(pdev) || !pci_is_enabled(pdev));
}
/*
* Give the controller a chance to complete all entered requests if
* doing a safe shutdown.
*/
- if (!dead) {
- if (shutdown)
- nvme_wait_freeze_timeout(&dev->ctrl, NVME_IO_TIMEOUT);
- }
+ if (!dead && shutdown)
+ nvme_wait_freeze_timeout(&dev->ctrl, NVME_IO_TIMEOUT);
nvme_stop_queues(&dev->ctrl);
@@ -2227,8 +2225,8 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
if (dev->host_mem_descs)
nvme_set_host_mem(dev, 0);
nvme_disable_io_queues(dev);
- nvme_disable_admin_queue(dev, shutdown);
}
+ nvme_disable_admin_queue(dev, shutdown);
for (i = dev->ctrl.queue_count - 1; i >= 0; i--)
nvme_suspend_queue(&dev->queues[i]);
The driver had been relying on the pci_dev to maintain the state of the pci device to know when starting a freeze would be appropriate. The blktests block/011 however shows us that users may alter the state of pci_dev out from under drivers and break the criteria we had been using. This patch uses the private nvme controller struct to track the enabling/disabling state. Since we're relying on that now, the reset will unconditionally disable the device on reset. This is necessary anyway on a controller failure reset, and was already being done in the reset during admin bring up, and is not harmful to do a second time. Signed-off-by: Keith Busch <keith.busch@intel.com> --- drivers/nvme/host/pci.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)