IRQ races during change of mtu - NAPI poll must be enabled prior to IRQ activation or the IRQ handler will not know what to do with an incoming packet; - rtl8169_down() needs to try twice to sync with the IRQ handler when it is not issued under !netif_running() protection.
Both changes make it safe to request a change of mtu on a live device. Signed-off-by: Francois Romieu <[EMAIL PROTECTED]> diff -puN drivers/net/r8169.c~r8169-450 drivers/net/r8169.c --- a/drivers/net/r8169.c~r8169-450 2005-02-23 21:35:21.112521942 +0100 +++ b/drivers/net/r8169.c 2005-02-23 21:35:21.117521120 +0100 @@ -1648,10 +1648,10 @@ static int rtl8169_change_mtu(struct net if (ret < 0) goto out; - rtl8169_hw_start(dev); - netif_poll_enable(dev); + rtl8169_hw_start(dev); + rtl8169_request_timer(dev); out: @@ -2352,6 +2352,7 @@ static void rtl8169_down(struct net_devi { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; + unsigned int poll_locked = 0; rtl8169_delete_timer(dev); @@ -2359,6 +2360,7 @@ static void rtl8169_down(struct net_devi flush_scheduled_work(); +core_down: spin_lock_irq(&tp->lock); /* Stop the chip's Tx and Rx DMA processes. */ @@ -2375,11 +2377,28 @@ static void rtl8169_down(struct net_devi synchronize_irq(dev->irq); - netif_poll_disable(dev); + if (!poll_locked) { + netif_poll_disable(dev); + poll_locked++; + } /* Give a racing hard_start_xmit a few cycles to complete. */ synchronize_kernel(); + /* + * And now for the 50k$ question: are IRQ disabled or not ? + * + * Two paths lead here: + * 1) dev->close + * -> netif_running() is available to sync the current code and the + * IRQ handler. See rtl8169_interrupt for details. + * 2) dev->change_mtu + * -> rtl8169_poll can not be issued again and re-enable the + * interruptions. Let's simply issue the IRQ down sequence again. + */ + if (RTL_R16(IntrMask)) + goto core_down; + rtl8169_tx_clear(tp); rtl8169_rx_clear(tp); _ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/