diff options
author | David S. Miller <davem@davemloft.net> | 2018-03-08 12:51:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-08 12:51:46 -0500 |
commit | 10c56b8d93863abb4dbb01a9b9f1b40c336a1c3b (patch) | |
tree | 3b8db1085222b16065fa96113f6adfaf01c83e53 | |
parent | 46e371f0e78a82186a83cbcb4f4b8850417c7dd5 (diff) | |
parent | 18b8d6bbad47efd9bd1595c57271fbacc5eb0d46 (diff) |
Merge branch 'ibmvnic-Clean-up-net-close-and-fix-reset-bug'
Thomas Falcon says:
====================
ibmvnic: Clean up net close and fix reset bug
This patch set cleans up and reorganizes the driver's net_device
close function and leverages that to fix up a bug that can occur
during some device resets. Some reset cases require the backing
adapter to be disabled before continuing, but other cases, such as
during a device failover or partition migration, do not require this
step. Since the device will not be initialized at this stage and
its command-processing queue is closed, do not send the request to
disable the device as it could result in an error or timeout
disrupting the reset.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/ibm/ibmvnic.c | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 765407179fdd..7be4b06f69d2 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1143,14 +1143,11 @@ static void clean_tx_pools(struct ibmvnic_adapter *adapter) } } -static int __ibmvnic_close(struct net_device *netdev) +static void ibmvnic_cleanup(struct net_device *netdev) { struct ibmvnic_adapter *adapter = netdev_priv(netdev); - int rc = 0; int i; - adapter->state = VNIC_CLOSING; - /* ensure that transmissions are stopped if called by do_reset */ if (adapter->resetting) netif_tx_disable(netdev); @@ -1162,30 +1159,16 @@ static int __ibmvnic_close(struct net_device *netdev) if (adapter->tx_scrq) { for (i = 0; i < adapter->req_tx_queues; i++) if (adapter->tx_scrq[i]->irq) { - netdev_dbg(adapter->netdev, + netdev_dbg(netdev, "Disabling tx_scrq[%d] irq\n", i); disable_irq(adapter->tx_scrq[i]->irq); } } - rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN); - if (rc) - return rc; - if (adapter->rx_scrq) { for (i = 0; i < adapter->req_rx_queues; i++) { - int retries = 10; - - while (pending_scrq(adapter, adapter->rx_scrq[i])) { - retries--; - mdelay(100); - - if (retries == 0) - break; - } - if (adapter->rx_scrq[i]->irq) { - netdev_dbg(adapter->netdev, + netdev_dbg(netdev, "Disabling rx_scrq[%d] irq\n", i); disable_irq(adapter->rx_scrq[i]->irq); } @@ -1193,8 +1176,20 @@ static int __ibmvnic_close(struct net_device *netdev) } clean_rx_pools(adapter); clean_tx_pools(adapter); +} + +static int __ibmvnic_close(struct net_device *netdev) +{ + struct ibmvnic_adapter *adapter = netdev_priv(netdev); + int rc = 0; + + adapter->state = VNIC_CLOSING; + rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN); + if (rc) + return rc; + ibmvnic_cleanup(netdev); adapter->state = VNIC_CLOSED; - return rc; + return 0; } static int ibmvnic_close(struct net_device *netdev) @@ -1658,12 +1653,15 @@ static int do_reset(struct ibmvnic_adapter *adapter, rc = ibmvnic_reenable_crq_queue(adapter); if (rc) return 0; + ibmvnic_cleanup(netdev); + } else if (rwi->reset_reason == VNIC_RESET_FAILOVER) { + ibmvnic_cleanup(netdev); + } else { + rc = __ibmvnic_close(netdev); + if (rc) + return rc; } - rc = __ibmvnic_close(netdev); - if (rc) - return rc; - if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM || adapter->wait_for_reset) { release_resources(adapter); |