public inbox for linux-block@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] nvme: always return IRQ_HANDLED
@ 2017-08-17 19:32 Jens Axboe
  2017-08-17 20:15 ` Keith Busch
  0 siblings, 1 reply; 6+ messages in thread
From: Jens Axboe @ 2017-08-17 19:32 UTC (permalink / raw)
  To: linux-nvme@lists.infradead.org
  Cc: linux-block@vger.kernel.org, Keith Busch, Christoph Hellwig

We currently have an issue with nvme when polling is used. Just
ran some testing on 4.13-rc5, and it's trivial to trigger an IRQ
disable ala:

[   52.412851] irq 77: nobody cared (try booting with the "irqpoll" option)
[   52.415310] irq 70: nobody cared (try booting with the "irqpoll" option)

when running a few processes polling. The reason is pretty obvious - if
we're effective at polling, the triggered IRQ will never find any
events. If this happens enough times in a row, the kernel disables our
IRQ since we keep returning IRQ_NONE.

Question is, what's the best way to solve this. Ideally we should not be
triggering an IRQ at all, but that's still not in mainline. Can we
safely just return IRQ_HANDLED always? That should work except for the
case where we happen to run into an IRQ flood where DO want to turn off
the nvme irq. For now, I think that's small price to pay, since the
current issue is much worse and leaves the device in a weird non-working
state where some queue interrupts are turned off.

Signed-off-by: Jens Axboe <axboe@kernel.dk>

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 74a124a06264..21a35faff86f 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -160,7 +160,6 @@ struct nvme_queue {
 	u16 cq_head;
 	u16 qid;
 	u8 cq_phase;
-	u8 cqe_seen;
 	u32 *dbbuf_sq_db;
 	u32 *dbbuf_cq_db;
 	u32 *dbbuf_sq_ei;
@@ -830,22 +829,19 @@ static void nvme_process_cq(struct nvme_queue *nvmeq)
 		consumed++;
 	}
 
-	if (consumed) {
+	if (consumed)
 		nvme_ring_cq_doorbell(nvmeq);
-		nvmeq->cqe_seen = 1;
-	}
 }
 
 static irqreturn_t nvme_irq(int irq, void *data)
 {
-	irqreturn_t result;
 	struct nvme_queue *nvmeq = data;
+
 	spin_lock(&nvmeq->q_lock);
 	nvme_process_cq(nvmeq);
-	result = nvmeq->cqe_seen ? IRQ_HANDLED : IRQ_NONE;
-	nvmeq->cqe_seen = 0;
 	spin_unlock(&nvmeq->q_lock);
-	return result;
+
+	return IRQ_HANDLED;
 }
 
 static irqreturn_t nvme_irq_check(int irq, void *data)

-- 
Jens Axboe

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-08-18  7:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-17 19:32 [RFC PATCH] nvme: always return IRQ_HANDLED Jens Axboe
2017-08-17 20:15 ` Keith Busch
2017-08-17 20:17   ` Jens Axboe
2017-08-17 20:29     ` Keith Busch
2017-08-17 20:25       ` Jens Axboe
2017-08-18  7:14         ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox