blob: 938af3f6f90f29e879916385b4064c12da9f63d0 [file] [log] [blame]
From 99a854d96a633b15db61824dfdd12ee816974c05 Mon Sep 17 00:00:00 2001
From: Darren Hart <dvhltc@us.ibm.com>
Date: Tue, 18 May 2010 14:33:07 -0700
Subject: [PATCH] net: ehea: make rx irq handler non-threaded (IRQF_NODELAY)
commit 44b341ae13557f646061530d281fbc19c5ae9111 in tip.
The underlying hardware is edge triggered but presented by XICS as level
triggered. The edge triggered interrupts are not reissued after masking. This
is not a problem in mainline which does not mask the interrupt (relying on the
EOI mechanism instead). The threaded interrupts in PREEMPT_RT do mask the
interrupt, and can lose interrupts that occurred while masked, resulting in a
hung ethernet interface.
The receive handler simply calls napi_schedule(), as such, there is no
significant additional overhead in making this non-threaded, since we either
wakeup the threaded irq handler to call napi_schedule(), or just call
napi_schedule() directly to wakeup the softirqs. As the receive handler is
lockless, there is no need to convert any of the ehea spinlock_t's to
raw_spinlock_t's.
Without this patch, a simple scp file copy loop would fail quickly (usually
seconds). We have over two hours of sustained scp activity with the patch
applied.
Credit goes to Will Schmidt for lots of instrumentation and tracing which
clarified the scenario and to Thomas Gleixner for the incredibly simple
solution.
Signed-off-by: Darren Hart <dvhltc@us.ibm.com>
Acked-by: Will Schmidt <will_schmidt@vnet.ibm.com>
Cc: Jan-Bernd Themann <themann@de.ibm.com>
Cc: Nivedita Singhvi <niv@us.ibm.com>
Cc: Brian King <bjking1@us.ibm.com>
Cc: Michael Ellerman <ellerman@au1.ibm.com>
Cc: Doug Maxey <doug.maxey@us.ibm.com>
LKML-Reference: <4BF30793.5070300@us.ibm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
drivers/net/ehea/ehea_main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 809ccc9..9239e96 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -1265,8 +1265,8 @@ static int ehea_reg_interrupts(struct net_device *dev)
"%s-queue%d", dev->name, i);
ret = ibmebus_request_irq(pr->eq->attr.ist1,
ehea_recv_irq_handler,
- IRQF_DISABLED, pr->int_send_name,
- pr);
+ IRQF_DISABLED | IRQF_NODELAY,
+ pr->int_send_name, pr);
if (ret) {
ehea_error("failed registering irq for ehea_queue "
"port_res_nr:%d, ist=%X", i,
--
1.7.0.4