aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2015-01-29 02:17:19 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-02-23 20:13:20 -0500
commitac833bbf7958bbdd416d6027b98763a231bc8f15 (patch)
tree27ab2f180df5d9de23267d45f5f388fd22841a25 /drivers/net/ethernet
parent748c434bfa956e3ac64793d14d3bdbe7befcb901 (diff)
i40evf: refactor reset
A recent change to the shutdown flow messed up the reset flow. Since i40evf_down now holds the critical section lock, we cannot call it from the reset handler, which also holds the lock. To do so causes a deadlock accompanied by wailing and gnashing of teeth. This is easily triggered by running an ethtool self-test on the PF device. Instead, we move the relevant portions of i40evf_down into the reset handler and bend them to our will. Additionally, we can optimize the reinit path by not deleting the MAC and VLAN filters and then adding them back again. Instead, we just set the 'add' flag and let the watchdog resynchronize the filter list with the PF driver. We also reword a few messages to make them more consistent with the rest of the driver. Change-ID: I03dd92ae736f7719fca3564b12a2cf9b98c6cb18 Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Tested-by: Jim Young <james.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index eb1ac2227681..1257577148ea 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -1480,9 +1480,11 @@ static void i40evf_reset_task(struct work_struct *work)
1480 struct i40evf_adapter *adapter = container_of(work, 1480 struct i40evf_adapter *adapter = container_of(work,
1481 struct i40evf_adapter, 1481 struct i40evf_adapter,
1482 reset_task); 1482 reset_task);
1483 struct net_device *netdev = adapter->netdev;
1483 struct i40e_hw *hw = &adapter->hw; 1484 struct i40e_hw *hw = &adapter->hw;
1484 int i = 0, err; 1485 struct i40evf_mac_filter *f;
1485 uint32_t rstat_val; 1486 uint32_t rstat_val;
1487 int i = 0, err;
1486 1488
1487 while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, 1489 while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
1488 &adapter->crit_section)) 1490 &adapter->crit_section))
@@ -1527,7 +1529,11 @@ static void i40evf_reset_task(struct work_struct *work)
1527 1529
1528 if (netif_running(adapter->netdev)) { 1530 if (netif_running(adapter->netdev)) {
1529 set_bit(__I40E_DOWN, &adapter->vsi.state); 1531 set_bit(__I40E_DOWN, &adapter->vsi.state);
1530 i40evf_down(adapter); 1532 i40evf_irq_disable(adapter);
1533 i40evf_napi_disable_all(adapter);
1534 netif_tx_disable(netdev);
1535 netif_tx_stop_all_queues(netdev);
1536 netif_carrier_off(netdev);
1531 i40evf_free_traffic_irqs(adapter); 1537 i40evf_free_traffic_irqs(adapter);
1532 i40evf_free_all_tx_resources(adapter); 1538 i40evf_free_all_tx_resources(adapter);
1533 i40evf_free_all_rx_resources(adapter); 1539 i40evf_free_all_rx_resources(adapter);
@@ -1559,22 +1565,37 @@ static void i40evf_reset_task(struct work_struct *work)
1559continue_reset: 1565continue_reset:
1560 adapter->flags &= ~I40EVF_FLAG_RESET_PENDING; 1566 adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
1561 1567
1562 i40evf_down(adapter); 1568 i40evf_irq_disable(adapter);
1569 i40evf_napi_disable_all(adapter);
1570
1571 netif_tx_disable(netdev);
1572
1573 netif_tx_stop_all_queues(netdev);
1574
1575 netif_carrier_off(netdev);
1563 adapter->state = __I40EVF_RESETTING; 1576 adapter->state = __I40EVF_RESETTING;
1564 1577
1565 /* kill and reinit the admin queue */ 1578 /* kill and reinit the admin queue */
1566 if (i40evf_shutdown_adminq(hw)) 1579 if (i40evf_shutdown_adminq(hw))
1567 dev_warn(&adapter->pdev->dev, 1580 dev_warn(&adapter->pdev->dev, "Failed to shut down adminq\n");
1568 "%s: Failed to destroy the Admin Queue resources\n", 1581 adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN;
1569 __func__);
1570 err = i40evf_init_adminq(hw); 1582 err = i40evf_init_adminq(hw);
1571 if (err) 1583 if (err)
1572 dev_info(&adapter->pdev->dev, "%s: init_adminq failed: %d\n", 1584 dev_info(&adapter->pdev->dev, "Failed to init adminq: %d\n",
1573 __func__, err); 1585 err);
1574 1586
1575 adapter->aq_pending = 0;
1576 adapter->aq_required = 0;
1577 i40evf_map_queues(adapter); 1587 i40evf_map_queues(adapter);
1588
1589 /* re-add all MAC filters */
1590 list_for_each_entry(f, &adapter->mac_filter_list, list) {
1591 f->add = true;
1592 }
1593 /* re-add all VLAN filters */
1594 list_for_each_entry(f, &adapter->vlan_filter_list, list) {
1595 f->add = true;
1596 }
1597 adapter->aq_required = I40EVF_FLAG_AQ_ADD_MAC_FILTER;
1598 adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
1578 clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); 1599 clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
1579 1600
1580 mod_timer(&adapter->watchdog_timer, jiffies + 2); 1601 mod_timer(&adapter->watchdog_timer, jiffies + 2);