Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Michael Buesch
Date: Saturday, May 23, 2009 - 2:24 am

On Saturday 23 May 2009 03:29:34 David Dillow wrote:

Thanks a lot, Dave! This fixes the issue on my chip.
You can add my:

Tested-by: Michael Buesch <mb@bu3sch.de>



Here's a patch that cleanly applies to 2.6.29.4:

Index: linux-2.6.29/drivers/net/r8169.c
===================================================================
--- linux-2.6.29.orig/drivers/net/r8169.c	2009-05-23 11:06:22.000000000 +0200
+++ linux-2.6.29/drivers/net/r8169.c	2009-05-23 11:08:17.000000000 +0200
@@ -3554,54 +3554,64 @@
 	int handled = 0;
 	int status;
 
+	/* loop handling interrupts until we have no new ones or
+	 * we hit a invalid/hotplug case.
+	 */
 	status = RTL_R16(IntrStatus);
+	while (status && status != 0xffff) {
+		handled = 1;
 
-	/* hotplug/major error/no more work/shared irq */
-	if ((status == 0xffff) || !status)
-		goto out;
-
-	handled = 1;
+		/* Handle all of the error cases first. These will reset
+		 * the chip, so just exit the loop.
+		 */
+		if (unlikely(!netif_running(dev))) {
+			rtl8169_asic_down(ioaddr);
+			break;
+		}
 
-	if (unlikely(!netif_running(dev))) {
-		rtl8169_asic_down(ioaddr);
-		goto out;
-	}
+		/* Work around for rx fifo overflow */
+		if (unlikely(status & RxFIFOOver) &&
+	    	(tp->mac_version == RTL_GIGA_MAC_VER_11)) {
+			netif_stop_queue(dev);
+			rtl8169_tx_timeout(dev);
+			break;
+		}
 
-	status &= tp->intr_mask;
-	RTL_W16(IntrStatus,
-		(status & RxFIFOOver) ? (status | RxOverflow) : status);
+		if (unlikely(status & SYSErr)) {
+			rtl8169_pcierr_interrupt(dev);
+			break;
+		}
 
-	if (!(status & tp->intr_event))
-		goto out;
+		if (status & LinkChg)
+			rtl8169_check_link_status(dev, tp, ioaddr);
 
-	/* Work around for rx fifo overflow */
-	if (unlikely(status & RxFIFOOver) &&
-	    (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
-		netif_stop_queue(dev);
-		rtl8169_tx_timeout(dev);
-		goto out;
-	}
+		/* We need to see the lastest version of tp->intr_mask to
+		 * avoid ignoring an MSI interrupt and having to wait for
+		 * another event which may never come.
+		 */
+		smp_rmb();
+		if (status & tp->intr_mask & tp->napi_event) {
+			RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+			tp->intr_mask = ~tp->napi_event;
+
+			if (likely(netif_rx_schedule_prep(&tp->napi)))
+				__netif_rx_schedule(&tp->napi);
+			else if (netif_msg_intr(tp)) {
+				printk(KERN_INFO "%s: interrupt %04x in poll\n",
+			       	dev->name, status);
+			}
+		}
 
-	if (unlikely(status & SYSErr)) {
-		rtl8169_pcierr_interrupt(dev);
-		goto out;
+		/* We only get a new MSI interrupt when all active irq
+		 * sources on the chip have been acknowledged. So, ack
+		 * everything we've seen and check if new sources have become
+		 * active to avoid blocking all interrupts from the chip.
+		 */
+		RTL_W16(IntrStatus,
+			(status & RxFIFOOver) ? (status | RxOverflow) : status);
+		status = RTL_R16(IntrStatus);
 	}
 
-	if (status & LinkChg)
-		rtl8169_check_link_status(dev, tp, ioaddr);
-
-	if (status & tp->napi_event) {
-		RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
-		tp->intr_mask = ~tp->napi_event;
-
-		if (likely(netif_rx_schedule_prep(&tp->napi)))
-			__netif_rx_schedule(&tp->napi);
-		else if (netif_msg_intr(tp)) {
-			printk(KERN_INFO "%s: interrupt %04x in poll\n",
-			       dev->name, status);
-		}
-	}
-out:
 	return IRQ_RETVAL(handled);
 }
 
@@ -3617,13 +3627,15 @@
 
 	if (work_done < budget) {
 		netif_rx_complete(napi);
-		tp->intr_mask = 0xffff;
-		/*
-		 * 20040426: the barrier is not strictly required but the
-		 * behavior of the irq handler could be less predictable
-		 * without it. Btw, the lack of flush for the posted pci
-		 * write is safe - FR
+
+		/* We need for force the visibility of tp->intr_mask
+		 * for other CPUs, as we can loose an MSI interrupt
+		 * and potentially wait for a retransmit timeout if we don't.
+		 * The posted write to IntrMask is safe, as it will
+		 * eventually make it to the chip and we won't loose anything
+		 * until it does.
 		 */
+		tp->intr_mask = 0xffff;
 		smp_wmb();
 		RTL_W16(IntrMask, tp->intr_event);
 	}


-- 
Greetings, Michael.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, David Dillow, (Fri May 22, 6:29 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Buesch, (Sat May 23, 2:24 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Riepe, (Sat May 23, 7:35 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Buesch, (Sat May 23, 7:44 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Riepe, (Sat May 23, 8:01 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Riepe, (Sat May 23, 9:12 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Buesch, (Sat May 23, 9:40 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Buesch, (Sat May 23, 9:45 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Buesch, (Sat May 23, 9:50 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Riepe, (Sat May 23, 9:53 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, David Dillow, (Sat May 23, 10:03 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Francois Romieu, (Sun May 24, 2:15 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, David Miller, (Mon May 25, 10:55 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Buesch, (Tue May 26, 11:22 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Riepe, (Tue May 26, 3:40 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Buesch, (Wed May 27, 9:19 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Fri Aug 21, 1:57 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michael Riepe, (Fri Aug 21, 2:22 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Fri Aug 21, 5:24 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Sat Aug 22, 4:48 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Sat Aug 22, 5:07 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Jarek Poplawski, (Sun Aug 23, 10:17 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Michal Soltys, (Sun Aug 23, 10:43 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Jarek Poplawski, (Sun Aug 23, 10:54 am)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Sun Aug 23, 7:37 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Mon Aug 24, 5:51 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Tue Aug 25, 1:22 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Tue Aug 25, 2:24 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Tue Aug 25, 2:37 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Francois Romieu, (Tue Aug 25, 3:19 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Francois Romieu, (Tue Aug 25, 4:11 pm)
Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts, Eric W. Biederman, (Tue Aug 25, 8:47 pm)
[PATCH] r8169: Reduce looping in the interrupt handler., Eric W. Biederman, (Wed Aug 26, 12:58 am)
Re: [PATCH] r8169: Reduce looping in the interrupt handler., Eric W. Biederman, (Wed Aug 26, 1:02 pm)
Re: [PATCH] r8169: Reduce looping in the interrupt handler., Francois Romieu, (Wed Aug 26, 2:30 pm)
Re: [PATCH] r8169: Reduce looping in the interrupt handler., Eric W. Biederman, (Wed Aug 26, 2:40 pm)
Re: [PATCH] r8169: Reduce looping in the interrupt handler., Francois Romieu, (Wed Aug 26, 10:24 pm)
Re: [PATCH] r8169: Reduce looping in the interrupt handler., Eric W. Biederman, (Wed Aug 26, 10:38 pm)
Re: [PATCH] r8169: Reduce looping in the interrupt handler., Francois Romieu, (Thu Aug 27, 4:20 pm)
Re: [PATCH] r8169: Reduce looping in the interrupt handler., Eric W. Biederman, (Thu Aug 27, 6:17 pm)
Re: [PATCH] r8169: Reduce looping in the interrupt handler., Francois Romieu, (Sun Aug 30, 1:37 pm)
Re: [PATCH] r8169: Reduce looping in the interrupt handler., Eric W. Biederman, (Sun Aug 30, 1:53 pm)