diff options
| author | Ben Hutchings <bhutchings@solarflare.com> | 2009-04-14 22:47:46 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-04-14 22:47:46 -0400 |
| commit | 718cff1eec595ce6ab0635b8160a51ee37d9268d (patch) | |
| tree | ee512c3d6d6370586b3219e92e5451475a7413b7 | |
| parent | 2690f8d62e98779c71625dba9a0fd525d8b2263d (diff) | |
sfc: Match calls to netif_napi_add() and netif_napi_del()
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.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/sfc/efx.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index dee23b159df2..7269a426051c 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
| @@ -448,9 +448,6 @@ static void efx_init_channels(struct efx_nic *efx) | |||
| 448 | 448 | ||
| 449 | WARN_ON(channel->rx_pkt != NULL); | 449 | WARN_ON(channel->rx_pkt != NULL); |
| 450 | efx_rx_strategy(channel); | 450 | efx_rx_strategy(channel); |
| 451 | |||
| 452 | netif_napi_add(channel->napi_dev, &channel->napi_str, | ||
| 453 | efx_poll, napi_weight); | ||
| 454 | } | 451 | } |
| 455 | } | 452 | } |
| 456 | 453 | ||
| @@ -1321,6 +1318,8 @@ static int efx_init_napi(struct efx_nic *efx) | |||
| 1321 | 1318 | ||
| 1322 | efx_for_each_channel(channel, efx) { | 1319 | efx_for_each_channel(channel, efx) { |
| 1323 | channel->napi_dev = efx->net_dev; | 1320 | channel->napi_dev = efx->net_dev; |
| 1321 | netif_napi_add(channel->napi_dev, &channel->napi_str, | ||
| 1322 | efx_poll, napi_weight); | ||
| 1324 | } | 1323 | } |
| 1325 | return 0; | 1324 | return 0; |
| 1326 | } | 1325 | } |
| @@ -1330,6 +1329,8 @@ static void efx_fini_napi(struct efx_nic *efx) | |||
| 1330 | struct efx_channel *channel; | 1329 | struct efx_channel *channel; |
| 1331 | 1330 | ||
| 1332 | efx_for_each_channel(channel, efx) { | 1331 | efx_for_each_channel(channel, efx) { |
| 1332 | if (channel->napi_dev) | ||
| 1333 | netif_napi_del(&channel->napi_str); | ||
| 1333 | channel->napi_dev = NULL; | 1334 | channel->napi_dev = NULL; |
| 1334 | } | 1335 | } |
| 1335 | } | 1336 | } |
