Hello! After further investigations. The bug was just in front of us...
ifconfig down in combination with the test for || !netif_running() can return a full quota and netif_rx_complete() done which causes the oops in net_rx_action. Of course the load must be high enough to fill the quota. I've found a bunch of drivers having this bug. Cheers. --ro Signed-off-by: Robert Olsson <[EMAIL PROTECTED]> diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index cf39473..f4137ad 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3947,6 +3947,10 @@ e1000_clean(struct napi_struct *napi, int budget) quit_polling: if (likely(adapter->itr_setting & 3)) e1000_set_itr(adapter); + + if(work_done == budget) + work_done--; + netif_rx_complete(poll_dev, napi); e1000_irq_enable(adapter); } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 4fd2e23..e43b5ca 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1408,6 +1408,9 @@ static int e1000_clean(struct napi_struct *napi, int budget) if ((!tx_cleaned && (work_done < budget)) || !netif_running(poll_dev)) { quit_polling: + if(work_done == budget) + work_done--; + if (adapter->itr_setting & 3) e1000_set_itr(adapter); netif_rx_complete(poll_dev, napi); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 3021234..e3064ef 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1783,6 +1783,10 @@ ixgb_clean(struct napi_struct *napi, int budget) /* if no Tx and not enough Rx work done, exit the polling mode */ if((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) { + + if(work_done == budget) + work_done--; + netif_rx_complete(netdev, napi); ixgb_irq_enable(adapter); } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 00bc525..204f5fa 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -579,6 +579,9 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) /* If no Tx and not enough Rx work done, exit the polling mode */ if ((work_done < budget) || !netif_running(netdev)) { quit_polling: + if(work_done == budget) + work_done--; + netif_rx_complete(netdev, napi); if (!test_bit(__IXGBE_DOWN, &adapter->state)) IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, @@ -1483,6 +1486,9 @@ static int ixgbe_clean(struct napi_struct *napi, int budget) if ((!tx_cleaned && (work_done < budget)) || !netif_running(adapter->netdev)) { quit_polling: + if(work_done == budget) + work_done--; + netif_rx_complete(netdev, napi); ixgbe_irq_enable(adapter); } diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 3dbaec6..c566491 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1998,6 +1998,10 @@ static int e100_poll(struct napi_struct *napi, int budget) /* If no Rx and Tx cleanup work was done, exit polling mode. */ if((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) { + + if(work_done == budget) + work_done--; + netif_rx_complete(netdev, napi); e100_enable_irq(nic); } - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html