Couldn't we do something like the incremental patch below to avoid duplicating the CQ processing? With that this patch could probably go away entirely and we could fold the change into the other nvme patch. diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 061f0b1cb0ec3..ce69e9666caac 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1059,9 +1059,8 @@ static inline void nvme_update_cq_head(struct nvme_queue *nvmeq) } } -static inline int nvme_process_cq(struct nvme_queue *nvmeq) +static inline int nvme_poll_cq(struct nvme_queue *nvmeq, struct io_batch *iob) { - DEFINE_IO_BATCH(iob); int found = 0; while (nvme_cqe_pending(nvmeq)) { @@ -1071,15 +1070,23 @@ static inline int nvme_process_cq(struct nvme_queue *nvmeq) * the cqe requires a full read memory barrier */ dma_rmb(); - nvme_handle_cqe(nvmeq, &iob, nvmeq->cq_head); + nvme_handle_cqe(nvmeq, iob, nvmeq->cq_head); nvme_update_cq_head(nvmeq); } - if (found) { - if (iob.req_list) - nvme_pci_complete_batch(&iob); + if (found) nvme_ring_cq_doorbell(nvmeq); - } + return found; +} + +static inline int nvme_process_cq(struct nvme_queue *nvmeq) +{ + DEFINE_IO_BATCH(iob); + int found; + + found = nvme_poll_cq(nvmeq, &iob); + if (iob.req_list) + nvme_pci_complete_batch(&iob); return found; } @@ -1116,27 +1123,6 @@ static void nvme_poll_irqdisable(struct nvme_queue *nvmeq) enable_irq(pci_irq_vector(pdev, nvmeq->cq_vector)); } -static inline int nvme_poll_cq(struct nvme_queue *nvmeq, struct io_batch *iob) -{ - int found = 0; - - while (nvme_cqe_pending(nvmeq)) { - found++; - /* - * load-load control dependency between phase and the rest of - * the cqe requires a full read memory barrier - */ - dma_rmb(); - nvme_handle_cqe(nvmeq, iob, nvmeq->cq_head); - nvme_update_cq_head(nvmeq); - } - - if (found) - nvme_ring_cq_doorbell(nvmeq); - return found; -} - - static int nvme_poll(struct blk_mq_hw_ctx *hctx, struct io_batch *iob) { struct nvme_queue *nvmeq = hctx->driver_data;