]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
sfc: Match calls to netif_napi_add() and netif_napi_del()
authorBen Hutchings <bhutchings@solarflare.com>
Wed, 15 Apr 2009 00:39:03 +0000 (01:39 +0100)
committerChris Wright <chrisw@sous-sol.org>
Mon, 27 Apr 2009 17:37:01 +0000 (10:37 -0700)
upstream commit: 718cff1eec595ce6ab0635b8160a51ee37d9268d

sfc could call netif_napi_add() multiple times for the same
napi_struct, corrupting the list of napi_structs for the associated
device and leading to a busy-loop on device removal.  Move the call to
netif_napi_add() and add a call to netif_napi_del() in the obvious
places.

[bhutchings: backport to 2.6.29]
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
drivers/net/sfc/efx.c

index ab0e09bf154d1f1fe2fdab401465e31cccdb2918..655e9b253ab02b098e9440e0a209178ce9bf6a11 100644 (file)
@@ -424,10 +424,6 @@ static void efx_start_channel(struct efx_channel *channel)
 
        EFX_LOG(channel->efx, "starting chan %d\n", channel->channel);
 
-       if (!(channel->efx->net_dev->flags & IFF_UP))
-               netif_napi_add(channel->napi_dev, &channel->napi_str,
-                              efx_poll, napi_weight);
-
        /* The interrupt handler for this channel may set work_pending
         * as soon as we enable it.  Make sure it's cleared before
         * then.  Similarly, make sure it sees the enabled flag set. */
@@ -1273,6 +1269,8 @@ static int efx_init_napi(struct efx_nic *efx)
 
        efx_for_each_channel(channel, efx) {
                channel->napi_dev = efx->net_dev;
+               netif_napi_add(channel->napi_dev, &channel->napi_str,
+                              efx_poll, napi_weight);
                rc = efx_lro_init(&channel->lro_mgr, efx);
                if (rc)
                        goto err;
@@ -1289,6 +1287,8 @@ static void efx_fini_napi(struct efx_nic *efx)
 
        efx_for_each_channel(channel, efx) {
                efx_lro_fini(&channel->lro_mgr);
+               if (channel->napi_dev)
+                       netif_napi_del(&channel->napi_str);
                channel->napi_dev = NULL;
        }
 }