]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
NVMe: reap completion entries when deleting queue
authorKeith Busch <keith.busch@intel.com>
Fri, 20 Nov 2015 15:38:13 +0000 (08:38 -0700)
committerChuck Anderson <chuck.anderson@oracle.com>
Wed, 6 Jul 2016 23:32:06 +0000 (16:32 -0700)
Make sure that there are no unprocesssed entries on a completion
queue before deleting it, and check for validity of the CQ
door bell before writing completions to it.

This fixes problems with doing a sysfs reset of the device while
it's handling IO.

Tested-by: Jon Derrick <jonathan.derrick@intel.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
(cherry picked from commit 604e8c8da8854351496215d269c3fa93859e3fee)

Orabug: 22620486
Signed-off-by: Jason Luo <zhangqing.luo@oracle.com>
drivers/nvme/host/pci.c

index 0ac79280bc4325c4fc3789562b263a67a93510fd..78f8b22d8d3e084ac9d74ae091a159450ec6efd8 100644 (file)
@@ -980,7 +980,8 @@ static int nvme_process_cq(struct nvme_queue *nvmeq)
        if (head == nvmeq->cq_head && phase == nvmeq->cq_phase)
                return 0;
 
-       writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
+       if (likely(nvmeq->cq_vector >= 0))
+               writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
        nvmeq->cq_head = head;
        nvmeq->cq_phase = phase;
 
@@ -2651,6 +2652,10 @@ static void nvme_del_queue_end(struct nvme_queue *nvmeq)
 {
        struct nvme_delq_ctx *dq = nvmeq->cmdinfo.ctx;
        nvme_put_dq(dq);
+
+       spin_lock_irq(&nvmeq->q_lock);
+       nvme_process_cq(nvmeq);
+       spin_unlock_irq(&nvmeq->q_lock);
 }
 
 static int adapter_async_del_queue(struct nvme_queue *nvmeq, u8 opcode,