aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2010-12-07 14:47:34 -0500
committerBen Hutchings <bhutchings@solarflare.com>2010-12-07 15:04:22 -0500
commite8f149924a3111015d16dfbbb4816cfc75ba53cd (patch)
tree69bbe1b466ba31ecaa105f6c330bf80f633b93ff /drivers/net
parent94dec6a2d20a26a779b63bb584e48db5fb0ddb53 (diff)
sfc: Fix NAPI list corruption during ring reallocation
Call netif_napi_{add,del}() on the NAPI contexts in the new and old channels, respectively. Since efx_init_napi() cannot fail, make its return type void. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/sfc/efx.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index d06cb742164b..fb83cdd94643 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -197,7 +197,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
197 197
198static void efx_remove_channels(struct efx_nic *efx); 198static void efx_remove_channels(struct efx_nic *efx);
199static void efx_remove_port(struct efx_nic *efx); 199static void efx_remove_port(struct efx_nic *efx);
200static void efx_init_napi(struct efx_nic *efx);
200static void efx_fini_napi(struct efx_nic *efx); 201static void efx_fini_napi(struct efx_nic *efx);
202static void efx_fini_napi_channel(struct efx_channel *channel);
201static void efx_fini_struct(struct efx_nic *efx); 203static void efx_fini_struct(struct efx_nic *efx);
202static void efx_start_all(struct efx_nic *efx); 204static void efx_start_all(struct efx_nic *efx);
203static void efx_stop_all(struct efx_nic *efx); 205static void efx_stop_all(struct efx_nic *efx);
@@ -430,6 +432,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
430 432
431 *channel = *old_channel; 433 *channel = *old_channel;
432 434
435 channel->napi_dev = NULL;
433 memset(&channel->eventq, 0, sizeof(channel->eventq)); 436 memset(&channel->eventq, 0, sizeof(channel->eventq));
434 437
435 rx_queue = &channel->rx_queue; 438 rx_queue = &channel->rx_queue;
@@ -740,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
740 if (rc) 743 if (rc)
741 goto rollback; 744 goto rollback;
742 745
746 efx_init_napi(efx);
747
743 /* Destroy old channels */ 748 /* Destroy old channels */
744 for (i = 0; i < efx->n_channels; i++) 749 for (i = 0; i < efx->n_channels; i++) {
750 efx_fini_napi_channel(other_channel[i]);
745 efx_remove_channel(other_channel[i]); 751 efx_remove_channel(other_channel[i]);
752 }
746out: 753out:
747 /* Free unused channel structures */ 754 /* Free unused channel structures */
748 for (i = 0; i < efx->n_channels; i++) 755 for (i = 0; i < efx->n_channels; i++)
@@ -1601,7 +1608,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
1601 * 1608 *
1602 **************************************************************************/ 1609 **************************************************************************/
1603 1610
1604static int efx_init_napi(struct efx_nic *efx) 1611static void efx_init_napi(struct efx_nic *efx)
1605{ 1612{
1606 struct efx_channel *channel; 1613 struct efx_channel *channel;
1607 1614
@@ -1610,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx)
1610 netif_napi_add(channel->napi_dev, &channel->napi_str, 1617 netif_napi_add(channel->napi_dev, &channel->napi_str,
1611 efx_poll, napi_weight); 1618 efx_poll, napi_weight);
1612 } 1619 }
1613 return 0; 1620}
1621
1622static void efx_fini_napi_channel(struct efx_channel *channel)
1623{
1624 if (channel->napi_dev)
1625 netif_napi_del(&channel->napi_str);
1626 channel->napi_dev = NULL;
1614} 1627}
1615 1628
1616static void efx_fini_napi(struct efx_nic *efx) 1629static void efx_fini_napi(struct efx_nic *efx)
1617{ 1630{
1618 struct efx_channel *channel; 1631 struct efx_channel *channel;
1619 1632
1620 efx_for_each_channel(channel, efx) { 1633 efx_for_each_channel(channel, efx)
1621 if (channel->napi_dev) 1634 efx_fini_napi_channel(channel);
1622 netif_napi_del(&channel->napi_str);
1623 channel->napi_dev = NULL;
1624 }
1625} 1635}
1626 1636
1627/************************************************************************** 1637/**************************************************************************
@@ -2343,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
2343 if (rc) 2353 if (rc)
2344 goto fail1; 2354 goto fail1;
2345 2355
2346 rc = efx_init_napi(efx); 2356 efx_init_napi(efx);
2347 if (rc)
2348 goto fail2;
2349 2357
2350 rc = efx->type->init(efx); 2358 rc = efx->type->init(efx);
2351 if (rc) { 2359 if (rc) {
@@ -2376,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx)
2376 efx->type->fini(efx); 2384 efx->type->fini(efx);
2377 fail3: 2385 fail3:
2378 efx_fini_napi(efx); 2386 efx_fini_napi(efx);
2379 fail2:
2380 efx_remove_all(efx); 2387 efx_remove_all(efx);
2381 fail1: 2388 fail1:
2382 return rc; 2389 return rc;