aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-07-27 15:50:52 -0400
committerBen Hutchings <bhutchings@solarflare.com>2012-08-24 15:10:22 -0400
commit7153f623ea47f3feb54209d75b80ed09a497cd4a (patch)
treef444625483bfffac8144c44e58440461078961af /drivers/net/ethernet/sfc
parentb812f8b7a9b657367eaacab8c34e6711a657a48b (diff)
sfc: Fix reset vs probe/remove/PM races involving efx_nic::state
We try to defer resets while the device is not READY, but we're not doing this quite correctly. In particular, changes to efx_nic::state are documented as serialised by the RTNL lock, but they aren't. 1. We check whether a reset was requested during probe (suggesting broken hardware) before we allow requested resets to be scheduled. This leaves a window where a requested reset would be deferred indefinitely. 2. Although we cancel the reset work item during device removal, there are still later operations that can cause it to be scheduled again. We need to check the state before scheduling it. 3. Since the state can change between scheduling and running of the work item, we still need to check it there, and we need to do so *after* acquiring the RTNL lock which serialises state changes. 4. We must cancel the reset work item during device removal, if the state could ever have been READY. This wasn't done in some of the failure paths from efx_pci_probe(). Move the cancellation to efx_pci_remove_main(). Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc')
-rw-r--r--drivers/net/ethernet/sfc/efx.c84
1 files changed, 43 insertions, 41 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 5555e9f98162..d0653406058b 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -2112,6 +2112,19 @@ static int efx_register_netdev(struct efx_nic *efx)
2112 2112
2113 rtnl_lock(); 2113 rtnl_lock();
2114 2114
2115 /* Enable resets to be scheduled and check whether any were
2116 * already requested. If so, the NIC is probably hosed so we
2117 * abort.
2118 */
2119 efx->state = STATE_READY;
2120 smp_mb(); /* ensure we change state before checking reset_pending */
2121 if (efx->reset_pending) {
2122 netif_err(efx, probe, efx->net_dev,
2123 "aborting probe due to scheduled reset\n");
2124 rc = -EIO;
2125 goto fail_locked;
2126 }
2127
2115 rc = dev_alloc_name(net_dev, net_dev->name); 2128 rc = dev_alloc_name(net_dev, net_dev->name);
2116 if (rc < 0) 2129 if (rc < 0)
2117 goto fail_locked; 2130 goto fail_locked;
@@ -2141,14 +2154,14 @@ static int efx_register_netdev(struct efx_nic *efx)
2141 2154
2142 return 0; 2155 return 0;
2143 2156
2157fail_registered:
2158 rtnl_lock();
2159 unregister_netdevice(net_dev);
2144fail_locked: 2160fail_locked:
2161 efx->state = STATE_UNINIT;
2145 rtnl_unlock(); 2162 rtnl_unlock();
2146 netif_err(efx, drv, efx->net_dev, "could not register net dev\n"); 2163 netif_err(efx, drv, efx->net_dev, "could not register net dev\n");
2147 return rc; 2164 return rc;
2148
2149fail_registered:
2150 unregister_netdev(net_dev);
2151 return rc;
2152} 2165}
2153 2166
2154static void efx_unregister_netdev(struct efx_nic *efx) 2167static void efx_unregister_netdev(struct efx_nic *efx)
@@ -2171,7 +2184,11 @@ static void efx_unregister_netdev(struct efx_nic *efx)
2171 2184
2172 strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); 2185 strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name));
2173 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); 2186 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type);
2174 unregister_netdev(efx->net_dev); 2187
2188 rtnl_lock();
2189 unregister_netdevice(efx->net_dev);
2190 efx->state = STATE_UNINIT;
2191 rtnl_unlock();
2175} 2192}
2176 2193
2177/************************************************************************** 2194/**************************************************************************
@@ -2309,13 +2326,15 @@ static void efx_reset_work(struct work_struct *data)
2309 if (!pending) 2326 if (!pending)
2310 return; 2327 return;
2311 2328
2312 /* If we're not READY then don't reset. Leave the reset_pending
2313 * flags set so that efx_pci_probe_main will be retried */
2314 if (efx->state != STATE_READY)
2315 return;
2316
2317 rtnl_lock(); 2329 rtnl_lock();
2318 (void)efx_reset(efx, fls(pending) - 1); 2330
2331 /* We checked the state in efx_schedule_reset() but it may
2332 * have changed by now. Now that we have the RTNL lock,
2333 * it cannot change again.
2334 */
2335 if (efx->state == STATE_READY)
2336 (void)efx_reset(efx, fls(pending) - 1);
2337
2319 rtnl_unlock(); 2338 rtnl_unlock();
2320} 2339}
2321 2340
@@ -2341,6 +2360,13 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
2341 } 2360 }
2342 2361
2343 set_bit(method, &efx->reset_pending); 2362 set_bit(method, &efx->reset_pending);
2363 smp_mb(); /* ensure we change reset_pending before checking state */
2364
2365 /* If we're not READY then just leave the flags set as the cue
2366 * to abort probing or reschedule the reset later.
2367 */
2368 if (ACCESS_ONCE(efx->state) != STATE_READY)
2369 return;
2344 2370
2345 /* efx_process_channel() will no longer read events once a 2371 /* efx_process_channel() will no longer read events once a
2346 * reset is scheduled. So switch back to poll'd MCDI completions. */ 2372 * reset is scheduled. So switch back to poll'd MCDI completions. */
@@ -2485,6 +2511,12 @@ static void efx_fini_struct(struct efx_nic *efx)
2485 */ 2511 */
2486static void efx_pci_remove_main(struct efx_nic *efx) 2512static void efx_pci_remove_main(struct efx_nic *efx)
2487{ 2513{
2514 /* Flush reset_work. It can no longer be scheduled since we
2515 * are not READY.
2516 */
2517 BUG_ON(efx->state == STATE_READY);
2518 cancel_work_sync(&efx->reset_work);
2519
2488#ifdef CONFIG_RFS_ACCEL 2520#ifdef CONFIG_RFS_ACCEL
2489 free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap); 2521 free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap);
2490 efx->net_dev->rx_cpu_rmap = NULL; 2522 efx->net_dev->rx_cpu_rmap = NULL;
@@ -2510,11 +2542,8 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
2510 2542
2511 /* Mark the NIC as fini, then stop the interface */ 2543 /* Mark the NIC as fini, then stop the interface */
2512 rtnl_lock(); 2544 rtnl_lock();
2513 efx->state = STATE_UNINIT;
2514 dev_close(efx->net_dev); 2545 dev_close(efx->net_dev);
2515 efx_stop_interrupts(efx, false); 2546 efx_stop_interrupts(efx, false);
2516
2517 /* Allow any queued efx_resets() to complete */
2518 rtnl_unlock(); 2547 rtnl_unlock();
2519 2548
2520 efx_sriov_fini(efx); 2549 efx_sriov_fini(efx);
@@ -2522,12 +2551,6 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
2522 2551
2523 efx_mtd_remove(efx); 2552 efx_mtd_remove(efx);
2524 2553
2525 /* Wait for any scheduled resets to complete. No more will be
2526 * scheduled from this point because efx_stop_all() has been
2527 * called, we are no longer registered with driverlink, and
2528 * the net_device's have been removed. */
2529 cancel_work_sync(&efx->reset_work);
2530
2531 efx_pci_remove_main(efx); 2554 efx_pci_remove_main(efx);
2532 2555
2533 efx_fini_io(efx); 2556 efx_fini_io(efx);
@@ -2686,30 +2709,9 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
2686 goto fail2; 2709 goto fail2;
2687 2710
2688 rc = efx_pci_probe_main(efx); 2711 rc = efx_pci_probe_main(efx);
2689
2690 /* Serialise against efx_reset(). No more resets will be
2691 * scheduled since efx_stop_all() has been called, and we have
2692 * not and never have been registered.
2693 */
2694 cancel_work_sync(&efx->reset_work);
2695
2696 if (rc) 2712 if (rc)
2697 goto fail3; 2713 goto fail3;
2698 2714
2699 /* If there was a scheduled reset during probe, the NIC is
2700 * probably hosed anyway.
2701 */
2702 if (efx->reset_pending) {
2703 netif_err(efx, probe, efx->net_dev,
2704 "aborting probe due to scheduled reset\n");
2705 rc = -EIO;
2706 goto fail4;
2707 }
2708
2709 /* Switch to the READY state before we expose the device to the OS,
2710 * so that dev_open()|efx_start_all() will actually start the device */
2711 efx->state = STATE_READY;
2712
2713 rc = efx_register_netdev(efx); 2715 rc = efx_register_netdev(efx);
2714 if (rc) 2716 if (rc)
2715 goto fail4; 2717 goto fail4;