Commit 9ba271b6 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Stefan Rauch

pcie-wb: Use threaded interrupts and avoid the kworker.

The interrupt service routine schedules a worker in order to perform the
main task including signaling userspace. This can lead to increased
latency since the worke is not sychronized with the interrupt handler
and be invoked "later" depending on the load on the system.

This can be avoided by using a threaded interrupt and invoking the work
directly in the threaded interrupt. There are still other places which
invoke wishbone_slave_ready() (and use the worker) in order to judge if
this is sane to do or not.

Use threaded interrupts and perform the work in the threaded interrupt.
Signed-off-by: 's avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: 's avatarKurt Kanzenbach <kurt@linutronix.de>
parent 4f853dbb
......@@ -289,7 +289,7 @@ static irqreturn_t irq_handler(int irq, void *dev_id)
}
pcie_int_enable(dev, 0); /* disable IRQ on Etherbone layer - Etherbone */
wishbone_slave_ready(&dev->wb);
wishbone_process_msi(&dev->wb);
return IRQ_HANDLED;
}
......@@ -462,7 +462,8 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto fail_msi;
}
if (request_irq(pdev->irq, irq_handler, IRQF_SHARED, "pcie_wb", dev) < 0) {
if (request_threaded_irq(pdev->irq, NULL, irq_handler, IRQF_SHARED | IRQF_ONESHOT,
"pcie_wb", dev) < 0) {
printk(KERN_ALERT PCIE_WB ": could not register interrupt handler\n");
goto fail_reg;
}
......
......@@ -111,17 +111,14 @@ static inline void eb_from_cpu(unsigned char* x, wb_data_t dat)
}
}
/* Called from the wb->msi_workqueue */
static void wishbone_dispatch_msi(struct work_struct *work)
void wishbone_process_msi(struct wishbone* wb)
{
struct wishbone* wb;
struct wishbone_request request;
struct etherbone_master_context *context;
unsigned long flags;
uint8_t *wptr;
int index;
wb = container_of(work, struct wishbone, msi_handler);
context = 0;
/* Hold this mutex for the whole handler */
......@@ -207,6 +204,16 @@ static void wishbone_dispatch_msi(struct work_struct *work)
mutex_unlock(&wb->msi_mutex);
}
EXPORT_SYMBOL(wishbone_process_msi);
/* Called from the wb->msi_workqueue */
static void wishbone_dispatch_msi(struct work_struct *work)
{
struct wishbone* wb;
wb = container_of(work, struct wishbone, msi_handler);
wishbone_process_msi(wb);
}
/* Must be called with context_mutex held */
static void claim_msi(struct etherbone_master_context* context)
......
......@@ -126,5 +126,6 @@ int wishbone_unregister(struct wishbone* wb); /* disable interrupts before calli
/* call when device has data pending. disable non-MSI interrupt generation before calling. */
void wishbone_slave_ready(struct wishbone* wb);
void wishbone_process_msi(struct wishbone* wb);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment