| From: Darren Hart <dvhltc@us.ibm.com> |
| Date: Tue, 18 May 2010 14:33:07 -0700 |
| Subject: drivers: net: ehea: Make rx irq handler non-threaded (IRQF_NO_THREAD) |
| |
| 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> |
| |
| --- |
| drivers/net/ethernet/ibm/ehea/ehea_main.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| Index: linux-stable/drivers/net/ethernet/ibm/ehea/ehea_main.c |
| =================================================================== |
| --- linux-stable.orig/drivers/net/ethernet/ibm/ehea/ehea_main.c |
| +++ linux-stable/drivers/net/ethernet/ibm/ehea/ehea_main.c |
| @@ -1308,7 +1308,7 @@ static int ehea_reg_interrupts(struct ne |
| "%s-queue%d", dev->name, i); |
| ret = ibmebus_request_irq(pr->eq->attr.ist1, |
| ehea_recv_irq_handler, |
| - IRQF_DISABLED, pr->int_send_name, |
| + IRQF_NO_THREAD, pr->int_send_name, |
| pr); |
| if (ret) { |
| netdev_err(dev, "failed registering irq for ehea_queue port_res_nr:%d, ist=%X\n", |