* [PATCH] dmaengine: idxd: fix misc interrupt completion
@ 2021-01-15 21:52 Dave Jiang
2021-01-17 6:51 ` Vinod Koul
0 siblings, 1 reply; 2+ messages in thread
From: Dave Jiang @ 2021-01-15 21:52 UTC (permalink / raw)
To: vkoul; +Cc: Nikhil Rao, dmaengine
Nikhil reported the misc interrupt handler can sometimes miss handling
the command interrupt when an error interrupt happens near the same time.
Have the irq handling thread continue to process the misc interrupts until
all interrupts are processed. This is a low usage interrupt and is not
expected to handle high volume traffic. Therefore there is no concern of
this thread running for a long time.
Fixes: 0d5c10b4c84d ("dmaengine: idxd: add work queue drain support")
Reported-by: Nikhil Rao <nikhil.rao@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/dma/idxd/irq.c | 36 +++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c
index 593a2f6ed16c..5d48f9b1b3aa 100644
--- a/drivers/dma/idxd/irq.c
+++ b/drivers/dma/idxd/irq.c
@@ -111,19 +111,14 @@ irqreturn_t idxd_irq_handler(int vec, void *data)
return IRQ_WAKE_THREAD;
}
-irqreturn_t idxd_misc_thread(int vec, void *data)
+static int process_misc_interrupts(struct idxd_device *idxd, u32 cause)
{
- struct idxd_irq_entry *irq_entry = data;
- struct idxd_device *idxd = irq_entry->idxd;
struct device *dev = &idxd->pdev->dev;
union gensts_reg gensts;
- u32 cause, val = 0;
+ u32 val = 0;
int i;
bool err = false;
- cause = ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET);
- iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET);
-
if (cause & IDXD_INTC_ERR) {
spin_lock_bh(&idxd->dev_lock);
for (i = 0; i < 4; i++)
@@ -181,7 +176,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
val);
if (!err)
- goto out;
+ return 0;
/*
* This case should rarely happen and typically is due to software
@@ -211,10 +206,33 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
gensts.reset_type == IDXD_DEVICE_RESET_FLR ?
"FLR" : "system reset");
spin_unlock_bh(&idxd->dev_lock);
+ return -ENXIO;
}
}
- out:
+ return 0;
+}
+
+irqreturn_t idxd_misc_thread(int vec, void *data)
+{
+ struct idxd_irq_entry *irq_entry = data;
+ struct idxd_device *idxd = irq_entry->idxd;
+ int rc;
+ u32 cause;
+
+ cause = ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET);
+ if (cause)
+ iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET);
+
+ while (cause) {
+ rc = process_misc_interrupts(idxd, cause);
+ if (rc < 0)
+ break;
+ cause = ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET);
+ if (cause)
+ iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET);
+ }
+
idxd_unmask_msix_vector(idxd, irq_entry->id);
return IRQ_HANDLED;
}
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] dmaengine: idxd: fix misc interrupt completion
2021-01-15 21:52 [PATCH] dmaengine: idxd: fix misc interrupt completion Dave Jiang
@ 2021-01-17 6:51 ` Vinod Koul
0 siblings, 0 replies; 2+ messages in thread
From: Vinod Koul @ 2021-01-17 6:51 UTC (permalink / raw)
To: Dave Jiang; +Cc: Nikhil Rao, dmaengine
On 15-01-21, 14:52, Dave Jiang wrote:
> Nikhil reported the misc interrupt handler can sometimes miss handling
> the command interrupt when an error interrupt happens near the same time.
> Have the irq handling thread continue to process the misc interrupts until
> all interrupts are processed. This is a low usage interrupt and is not
> expected to handle high volume traffic. Therefore there is no concern of
> this thread running for a long time.
Applied, thanks
--
~Vinod
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-01-17 6:52 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-01-15 21:52 [PATCH] dmaengine: idxd: fix misc interrupt completion Dave Jiang
2021-01-17 6:51 ` Vinod Koul
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox