summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Hart <dvhltc@us.ibm.com>2010-05-18 14:33:07 -0700
committerThomas Gleixner <tglx@linutronix.de>2010-05-19 15:55:29 +0200
commit44b341ae13557f646061530d281fbc19c5ae9111 (patch)
treea86aae48d91bab5af7d8dfb63be6d538aebc1472
parente5ff5cc39f4d882daf51bcbbda4dfb11a224c017 (diff)
downloadlinux-rt-44b341ae13557f646061530d281fbc19c5ae9111.tar.gz
net: ehea: make rx irq handler non-threaded (IRQF_NODELAY)
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>
-rw-r--r--drivers/net/ehea/ehea_main.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 7b62336e6736..ec2d6d497029 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -1264,8 +1264,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,