diff options
author | Keith Busch <keith.busch@intel.com> | 2015-03-26 20:49:33 +0100 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-03-31 18:36:06 +0200 |
commit | 6df3dbc83fb8043a5975d75970d296d6d14f7273 (patch) | |
tree | a26081013f618bc7ead04aa4f6035f7396a1e997 /drivers/block | |
parent | block, drbd: use mempool_create_slab_pool() (diff) | |
download | linux-6df3dbc83fb8043a5975d75970d296d6d14f7273.tar.xz linux-6df3dbc83fb8043a5975d75970d296d6d14f7273.zip |
NVMe: Freeze admin queue on device failure
This fixes a race accessing an invalid address when a controller's admin
queue is in use during a reset for failure or hot removal occurs. The
admin queue will be frozen to prevent new users from entering prior to
the doorbell queue being unmapped.
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/nvme-core.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index ceb32dd52a6c..ee83554c28ba 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1347,6 +1347,9 @@ static int nvme_suspend_queue(struct nvme_queue *nvmeq) nvmeq->cq_vector = -1; spin_unlock_irq(&nvmeq->q_lock); + if (!nvmeq->qid && nvmeq->dev->admin_q) + blk_mq_freeze_queue_start(nvmeq->dev->admin_q); + irq_set_affinity_hint(vector, NULL); free_irq(vector, nvmeq); @@ -1378,8 +1381,6 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid) adapter_delete_sq(dev, qid); adapter_delete_cq(dev, qid); } - if (!qid && dev->admin_q) - blk_mq_freeze_queue_start(dev->admin_q); spin_lock_irq(&nvmeq->q_lock); nvme_process_cq(nvmeq); |