sh_eth: Detach net device when stopping queue to resize DMA rings
authorBen Hutchings <ben.hutchings@codethink.co.uk>
Thu, 22 Jan 2015 12:40:25 +0000 (12:40 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 27 Jan 2015 00:13:15 +0000 (16:13 -0800)
We must only ever stop TX queues when they are full or the net device
is not 'ready' so far as the net core, and specifically the watchdog,
is concerned.  Otherwise, the watchdog may fire *immediately* if no
packets have been added to the queue in the last 5 seconds.

What's more, sh_eth_tx_timeout() will likely crash if called while
we're resizing the TX ring.

I could easily trigger this by running the loop:

   while ethtool -G eth0 rx 128 && ethtool -G eth0 rx 64; do echo -n .; done

Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/renesas/sh_eth.c

index 4ae22fc059181c8b001403240982aae0ec018b3c..fa8a7b775b4ac42180cd64f71476d7d1349369e3 100644 (file)
@@ -1968,6 +1968,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
                return -EINVAL;
 
        if (netif_running(ndev)) {
+               netif_device_detach(ndev);
                netif_tx_disable(ndev);
                /* Disable interrupts by clearing the interrupt mask. */
                sh_eth_write(ndev, 0x0000, EESIPR);
@@ -2001,7 +2002,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
                sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
                /* Setting the Rx mode will start the Rx process. */
                sh_eth_write(ndev, EDRRR_R, EDRRR);
-               netif_wake_queue(ndev);
+               netif_device_attach(ndev);
        }
 
        return 0;