Re: [RFC PATCH 3/3] nvme-pci: defer completions when rescheduling is needed

From: Naman Jain

Date: Mon Oct 12 2026 - 02:51:19 EST




On 10/9/2026 9:00 PM, Keith Busch wrote:
On Fri, Oct 09, 2026 at 05:05:56AM +0000, Naman Jain wrote:
static irqreturn_t nvme_irq(int irq, void *data)
{
struct nvme_queue *nvmeq = data;
DEFINE_IO_COMP_BATCH(iob);
+ if (unlikely(test_and_clear_bit(NVMEQ_IRQ_POLL_HANDOFF,
+ &nvmeq->flags))) {
+ if (!nvme_cqe_pending(nvmeq))
+ return IRQ_HANDLED;
+ }
+ if (unlikely(test_bit(NVMEQ_IRQ_POLL_PAUSED, &nvmeq->flags) &&
+ (!test_bit(NVMEQ_IRQ_POLL_INIT, &nvmeq->flags) ||
+ test_bit(NVMEQ_IRQ_POLL_MASKED, &nvmeq->flags) ||
+ READ_ONCE(to_pci_dev(nvmeq->dev->dev)->error_state) !=
+ pci_channel_io_normal)))
+ return IRQ_HANDLED;
+
+ if (unlikely(in_hardirq() &&
+ test_bit(NVMEQ_IRQ_POLL_INIT, &nvmeq->flags) &&
+ !test_bit(NVMEQ_IRQ_POLL_PAUSED, &nvmeq->flags) &&
+ need_resched() && nvme_cqe_pending(nvmeq) &&
+ !test_and_set_bit_lock(NVMEQ_IRQ_POLL, &nvmeq->flags))) {
+ set_bit(NVMEQ_IRQ_POLL_MASKED, &nvmeq->flags);
+ disable_irq_nosync(irq);
+ irq_poll_sched(&nvmeq->iopoll);
+ return IRQ_HANDLED;
+ }

The disable_irq_nosync still does non-posted transactions for msi and
msi-x. NVMe has a shortcut for msi, but there's currently nothing for
msi-x. For that case, I have a prep patch I consulted with Thomas, and
the result is below. I'm delayed sending it out while catching up from
travel, but I think this will be even more efficient.


Thanks for sharing. I'll give it a try. IIUC, after your patch goes in, I should be using disable_irq_nowait() in above and see better performance. Please correct me if I am wrong. I'll monitor your patch in LKML for future versions.

Regards,
Naman