summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2015-06-19 11:56:30 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-06-26 05:51:31 -0400
commit67c818a1d58c7897b8a6f531684516f9c236fe1b (patch)
tree49083ecd685152bd7774a8ba95d155ac076997ad /drivers/net
parent352f8ead753402d6c0496cb83b902128925459eb (diff)
i40evf: fix panic during MTU change
Down was requesting queue disables, but then exited immediately without waiting for the queues to actually disable. This could allow any function called after i40evf_down to run immediately, including i40evf_up, and causes a memory leak. Removing the whole reinit_locked function is the best way to go about this, and allows for the driver to handle the state changes by requesting reset from the periodic timer. Also, add a couple WARN_ONs in slow path to help us recognize if we re-introduce this issue or missed any cases. Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.c4
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf.h1
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c6
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c108
4 files changed, 54 insertions, 65 deletions
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index f54996f19629..395f32f226c0 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -484,6 +484,8 @@ int i40evf_setup_tx_descriptors(struct i40e_ring *tx_ring)
484 if (!dev) 484 if (!dev)
485 return -ENOMEM; 485 return -ENOMEM;
486 486
487 /* warn if we are about to overwrite the pointer */
488 WARN_ON(tx_ring->tx_bi);
487 bi_size = sizeof(struct i40e_tx_buffer) * tx_ring->count; 489 bi_size = sizeof(struct i40e_tx_buffer) * tx_ring->count;
488 tx_ring->tx_bi = kzalloc(bi_size, GFP_KERNEL); 490 tx_ring->tx_bi = kzalloc(bi_size, GFP_KERNEL);
489 if (!tx_ring->tx_bi) 491 if (!tx_ring->tx_bi)
@@ -644,6 +646,8 @@ int i40evf_setup_rx_descriptors(struct i40e_ring *rx_ring)
644 struct device *dev = rx_ring->dev; 646 struct device *dev = rx_ring->dev;
645 int bi_size; 647 int bi_size;
646 648
649 /* warn if we are about to overwrite the pointer */
650 WARN_ON(rx_ring->rx_bi);
647 bi_size = sizeof(struct i40e_rx_buffer) * rx_ring->count; 651 bi_size = sizeof(struct i40e_rx_buffer) * rx_ring->count;
648 rx_ring->rx_bi = kzalloc(bi_size, GFP_KERNEL); 652 rx_ring->rx_bi = kzalloc(bi_size, GFP_KERNEL);
649 if (!rx_ring->rx_bi) 653 if (!rx_ring->rx_bi)
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h
index 1b98c25b3092..fea3b75a9a35 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf.h
+++ b/drivers/net/ethernet/intel/i40evf/i40evf.h
@@ -264,7 +264,6 @@ extern const char i40evf_driver_version[];
264 264
265int i40evf_up(struct i40evf_adapter *adapter); 265int i40evf_up(struct i40evf_adapter *adapter);
266void i40evf_down(struct i40evf_adapter *adapter); 266void i40evf_down(struct i40evf_adapter *adapter);
267void i40evf_reinit_locked(struct i40evf_adapter *adapter);
268void i40evf_reset(struct i40evf_adapter *adapter); 267void i40evf_reset(struct i40evf_adapter *adapter);
269void i40evf_set_ethtool_ops(struct net_device *netdev); 268void i40evf_set_ethtool_ops(struct net_device *netdev);
270void i40evf_update_stats(struct i40evf_adapter *adapter); 269void i40evf_update_stats(struct i40evf_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index f4e77665bc54..2b53c870e7f1 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -267,8 +267,10 @@ static int i40evf_set_ringparam(struct net_device *netdev,
267 adapter->tx_desc_count = new_tx_count; 267 adapter->tx_desc_count = new_tx_count;
268 adapter->rx_desc_count = new_rx_count; 268 adapter->rx_desc_count = new_rx_count;
269 269
270 if (netif_running(netdev)) 270 if (netif_running(netdev)) {
271 i40evf_reinit_locked(adapter); 271 adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
272 schedule_work(&adapter->reset_task);
273 }
272 274
273 return 0; 275 return 0;
274} 276}
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 7c53aca4b5a6..5c73374c7f22 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -170,7 +170,8 @@ static void i40evf_tx_timeout(struct net_device *netdev)
170 struct i40evf_adapter *adapter = netdev_priv(netdev); 170 struct i40evf_adapter *adapter = netdev_priv(netdev);
171 171
172 adapter->tx_timeout_count++; 172 adapter->tx_timeout_count++;
173 if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING)) { 173 if (!(adapter->flags & (I40EVF_FLAG_RESET_PENDING |
174 I40EVF_FLAG_RESET_NEEDED))) {
174 adapter->flags |= I40EVF_FLAG_RESET_NEEDED; 175 adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
175 schedule_work(&adapter->reset_task); 176 schedule_work(&adapter->reset_task);
176 } 177 }
@@ -1470,8 +1471,8 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter)
1470 i40e_flush(hw); 1471 i40e_flush(hw);
1471} 1472}
1472 1473
1473#define I40EVF_RESET_WAIT_MS 100 1474#define I40EVF_RESET_WAIT_MS 10
1474#define I40EVF_RESET_WAIT_COUNT 200 1475#define I40EVF_RESET_WAIT_COUNT 500
1475/** 1476/**
1476 * i40evf_reset_task - Call-back task to handle hardware reset 1477 * i40evf_reset_task - Call-back task to handle hardware reset
1477 * @work: pointer to work_struct 1478 * @work: pointer to work_struct
@@ -1495,10 +1496,17 @@ static void i40evf_reset_task(struct work_struct *work)
1495 &adapter->crit_section)) 1496 &adapter->crit_section))
1496 usleep_range(500, 1000); 1497 usleep_range(500, 1000);
1497 1498
1499 i40evf_misc_irq_disable(adapter);
1498 if (adapter->flags & I40EVF_FLAG_RESET_NEEDED) { 1500 if (adapter->flags & I40EVF_FLAG_RESET_NEEDED) {
1499 dev_info(&adapter->pdev->dev, "Requesting reset from PF\n"); 1501 adapter->flags &= ~I40EVF_FLAG_RESET_NEEDED;
1502 /* Restart the AQ here. If we have been reset but didn't
1503 * detect it, or if the PF had to reinit, our AQ will be hosed.
1504 */
1505 i40evf_shutdown_adminq(hw);
1506 i40evf_init_adminq(hw);
1500 i40evf_request_reset(adapter); 1507 i40evf_request_reset(adapter);
1501 } 1508 }
1509 adapter->flags |= I40EVF_FLAG_RESET_PENDING;
1502 1510
1503 /* poll until we see the reset actually happen */ 1511 /* poll until we see the reset actually happen */
1504 for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) { 1512 for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) {
@@ -1507,10 +1515,10 @@ static void i40evf_reset_task(struct work_struct *work)
1507 if ((rstat_val != I40E_VFR_VFACTIVE) && 1515 if ((rstat_val != I40E_VFR_VFACTIVE) &&
1508 (rstat_val != I40E_VFR_COMPLETED)) 1516 (rstat_val != I40E_VFR_COMPLETED))
1509 break; 1517 break;
1510 msleep(I40EVF_RESET_WAIT_MS); 1518 usleep_range(500, 1000);
1511 } 1519 }
1512 if (i == I40EVF_RESET_WAIT_COUNT) { 1520 if (i == I40EVF_RESET_WAIT_COUNT) {
1513 adapter->flags &= ~I40EVF_FLAG_RESET_PENDING; 1521 dev_info(&adapter->pdev->dev, "Never saw reset\n");
1514 goto continue_reset; /* act like the reset happened */ 1522 goto continue_reset; /* act like the reset happened */
1515 } 1523 }
1516 1524
@@ -1518,11 +1526,12 @@ static void i40evf_reset_task(struct work_struct *work)
1518 for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) { 1526 for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) {
1519 rstat_val = rd32(hw, I40E_VFGEN_RSTAT) & 1527 rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
1520 I40E_VFGEN_RSTAT_VFR_STATE_MASK; 1528 I40E_VFGEN_RSTAT_VFR_STATE_MASK;
1521 if ((rstat_val == I40E_VFR_VFACTIVE) || 1529 if (rstat_val == I40E_VFR_VFACTIVE)
1522 (rstat_val == I40E_VFR_COMPLETED))
1523 break; 1530 break;
1524 msleep(I40EVF_RESET_WAIT_MS); 1531 msleep(I40EVF_RESET_WAIT_MS);
1525 } 1532 }
1533 /* extra wait to make sure minimum wait is met */
1534 msleep(I40EVF_RESET_WAIT_MS);
1526 if (i == I40EVF_RESET_WAIT_COUNT) { 1535 if (i == I40EVF_RESET_WAIT_COUNT) {
1527 struct i40evf_mac_filter *f, *ftmp; 1536 struct i40evf_mac_filter *f, *ftmp;
1528 struct i40evf_vlan_filter *fv, *fvtmp; 1537 struct i40evf_vlan_filter *fv, *fvtmp;
@@ -1534,11 +1543,10 @@ static void i40evf_reset_task(struct work_struct *work)
1534 1543
1535 if (netif_running(adapter->netdev)) { 1544 if (netif_running(adapter->netdev)) {
1536 set_bit(__I40E_DOWN, &adapter->vsi.state); 1545 set_bit(__I40E_DOWN, &adapter->vsi.state);
1537 i40evf_irq_disable(adapter);
1538 i40evf_napi_disable_all(adapter);
1539 netif_tx_disable(netdev);
1540 netif_tx_stop_all_queues(netdev);
1541 netif_carrier_off(netdev); 1546 netif_carrier_off(netdev);
1547 netif_tx_disable(netdev);
1548 i40evf_napi_disable_all(adapter);
1549 i40evf_irq_disable(adapter);
1542 i40evf_free_traffic_irqs(adapter); 1550 i40evf_free_traffic_irqs(adapter);
1543 i40evf_free_all_tx_resources(adapter); 1551 i40evf_free_all_tx_resources(adapter);
1544 i40evf_free_all_rx_resources(adapter); 1552 i40evf_free_all_rx_resources(adapter);
@@ -1550,6 +1558,7 @@ static void i40evf_reset_task(struct work_struct *work)
1550 list_del(&f->list); 1558 list_del(&f->list);
1551 kfree(f); 1559 kfree(f);
1552 } 1560 }
1561
1553 list_for_each_entry_safe(fv, fvtmp, &adapter->vlan_filter_list, 1562 list_for_each_entry_safe(fv, fvtmp, &adapter->vlan_filter_list,
1554 list) { 1563 list) {
1555 list_del(&fv->list); 1564 list_del(&fv->list);
@@ -1564,22 +1573,27 @@ static void i40evf_reset_task(struct work_struct *work)
1564 i40evf_shutdown_adminq(hw); 1573 i40evf_shutdown_adminq(hw);
1565 adapter->netdev->flags &= ~IFF_UP; 1574 adapter->netdev->flags &= ~IFF_UP;
1566 clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); 1575 clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
1576 adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
1577 dev_info(&adapter->pdev->dev, "Reset task did not complete, VF disabled\n");
1567 return; /* Do not attempt to reinit. It's dead, Jim. */ 1578 return; /* Do not attempt to reinit. It's dead, Jim. */
1568 } 1579 }
1569 1580
1570continue_reset: 1581continue_reset:
1571 adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
1572
1573 i40evf_irq_disable(adapter);
1574
1575 if (netif_running(adapter->netdev)) { 1582 if (netif_running(adapter->netdev)) {
1576 i40evf_napi_disable_all(adapter);
1577 netif_tx_disable(netdev);
1578 netif_tx_stop_all_queues(netdev);
1579 netif_carrier_off(netdev); 1583 netif_carrier_off(netdev);
1584 netif_tx_stop_all_queues(netdev);
1585 i40evf_napi_disable_all(adapter);
1580 } 1586 }
1587 i40evf_irq_disable(adapter);
1581 1588
1582 adapter->state = __I40EVF_RESETTING; 1589 adapter->state = __I40EVF_RESETTING;
1590 adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
1591
1592 /* free the Tx/Rx rings and descriptors, might be better to just
1593 * re-use them sometime in the future
1594 */
1595 i40evf_free_all_rx_resources(adapter);
1596 i40evf_free_all_tx_resources(adapter);
1583 1597
1584 /* kill and reinit the admin queue */ 1598 /* kill and reinit the admin queue */
1585 if (i40evf_shutdown_adminq(hw)) 1599 if (i40evf_shutdown_adminq(hw))
@@ -1603,6 +1617,7 @@ continue_reset:
1603 adapter->aq_required = I40EVF_FLAG_AQ_ADD_MAC_FILTER; 1617 adapter->aq_required = I40EVF_FLAG_AQ_ADD_MAC_FILTER;
1604 adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER; 1618 adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
1605 clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); 1619 clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
1620 i40evf_misc_irq_enable(adapter);
1606 1621
1607 mod_timer(&adapter->watchdog_timer, jiffies + 2); 1622 mod_timer(&adapter->watchdog_timer, jiffies + 2);
1608 1623
@@ -1624,7 +1639,10 @@ continue_reset:
1624 goto reset_err; 1639 goto reset_err;
1625 1640
1626 i40evf_irq_enable(adapter, true); 1641 i40evf_irq_enable(adapter, true);
1642 } else {
1643 adapter->state = __I40EVF_DOWN;
1627 } 1644 }
1645
1628 return; 1646 return;
1629reset_err: 1647reset_err:
1630 dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); 1648 dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
@@ -1667,6 +1685,11 @@ static void i40evf_adminq_task(struct work_struct *work)
1667 memset(event.msg_buf, 0, I40EVF_MAX_AQ_BUF_SIZE); 1685 memset(event.msg_buf, 0, I40EVF_MAX_AQ_BUF_SIZE);
1668 } while (pending); 1686 } while (pending);
1669 1687
1688 if ((adapter->flags &
1689 (I40EVF_FLAG_RESET_PENDING | I40EVF_FLAG_RESET_NEEDED)) ||
1690 adapter->state == __I40EVF_RESETTING)
1691 goto freedom;
1692
1670 /* check for error indications */ 1693 /* check for error indications */
1671 val = rd32(hw, hw->aq.arq.len); 1694 val = rd32(hw, hw->aq.arq.len);
1672 oldval = val; 1695 oldval = val;
@@ -1702,6 +1725,7 @@ static void i40evf_adminq_task(struct work_struct *work)
1702 if (oldval != val) 1725 if (oldval != val)
1703 wr32(hw, hw->aq.asq.len, val); 1726 wr32(hw, hw->aq.asq.len, val);
1704 1727
1728freedom:
1705 kfree(event.msg_buf); 1729 kfree(event.msg_buf);
1706out: 1730out:
1707 /* re-enable Admin queue interrupt cause */ 1731 /* re-enable Admin queue interrupt cause */
@@ -1897,47 +1921,6 @@ static struct net_device_stats *i40evf_get_stats(struct net_device *netdev)
1897} 1921}
1898 1922
1899/** 1923/**
1900 * i40evf_reinit_locked - Software reinit
1901 * @adapter: board private structure
1902 *
1903 * Reinititalizes the ring structures in response to a software configuration
1904 * change. Roughly the same as close followed by open, but skips releasing
1905 * and reallocating the interrupts.
1906 **/
1907void i40evf_reinit_locked(struct i40evf_adapter *adapter)
1908{
1909 struct net_device *netdev = adapter->netdev;
1910 int err;
1911
1912 WARN_ON(in_interrupt());
1913
1914 i40evf_down(adapter);
1915
1916 /* allocate transmit descriptors */
1917 err = i40evf_setup_all_tx_resources(adapter);
1918 if (err)
1919 goto err_reinit;
1920
1921 /* allocate receive descriptors */
1922 err = i40evf_setup_all_rx_resources(adapter);
1923 if (err)
1924 goto err_reinit;
1925
1926 i40evf_configure(adapter);
1927
1928 err = i40evf_up_complete(adapter);
1929 if (err)
1930 goto err_reinit;
1931
1932 i40evf_irq_enable(adapter, true);
1933 return;
1934
1935err_reinit:
1936 dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
1937 i40evf_close(netdev);
1938}
1939
1940/**
1941 * i40evf_change_mtu - Change the Maximum Transfer Unit 1924 * i40evf_change_mtu - Change the Maximum Transfer Unit
1942 * @netdev: network interface device structure 1925 * @netdev: network interface device structure
1943 * @new_mtu: new value for maximum frame size 1926 * @new_mtu: new value for maximum frame size
@@ -1952,9 +1935,10 @@ static int i40evf_change_mtu(struct net_device *netdev, int new_mtu)
1952 if ((new_mtu < 68) || (max_frame > I40E_MAX_RXBUFFER)) 1935 if ((new_mtu < 68) || (max_frame > I40E_MAX_RXBUFFER))
1953 return -EINVAL; 1936 return -EINVAL;
1954 1937
1955 /* must set new MTU before calling down or up */
1956 netdev->mtu = new_mtu; 1938 netdev->mtu = new_mtu;
1957 i40evf_reinit_locked(adapter); 1939 adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
1940 schedule_work(&adapter->reset_task);
1941
1958 return 0; 1942 return 0;
1959} 1943}
1960 1944