Commit 10c56b8d authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 46e371f0 18b8d6bb
...@@ -1143,14 +1143,11 @@ static void clean_tx_pools(struct ibmvnic_adapter *adapter) ...@@ -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); struct ibmvnic_adapter *adapter = netdev_priv(netdev);
int rc = 0;
int i; int i;
adapter->state = VNIC_CLOSING;
/* ensure that transmissions are stopped if called by do_reset */ /* ensure that transmissions are stopped if called by do_reset */
if (adapter->resetting) if (adapter->resetting)
netif_tx_disable(netdev); netif_tx_disable(netdev);
...@@ -1162,30 +1159,16 @@ static int __ibmvnic_close(struct net_device *netdev) ...@@ -1162,30 +1159,16 @@ static int __ibmvnic_close(struct net_device *netdev)
if (adapter->tx_scrq) { if (adapter->tx_scrq) {
for (i = 0; i < adapter->req_tx_queues; i++) for (i = 0; i < adapter->req_tx_queues; i++)
if (adapter->tx_scrq[i]->irq) { if (adapter->tx_scrq[i]->irq) {
netdev_dbg(adapter->netdev, netdev_dbg(netdev,
"Disabling tx_scrq[%d] irq\n", i); "Disabling tx_scrq[%d] irq\n", i);
disable_irq(adapter->tx_scrq[i]->irq); disable_irq(adapter->tx_scrq[i]->irq);
} }
} }
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
if (rc)
return rc;
if (adapter->rx_scrq) { if (adapter->rx_scrq) {
for (i = 0; i < adapter->req_rx_queues; i++) { 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) { if (adapter->rx_scrq[i]->irq) {
netdev_dbg(adapter->netdev, netdev_dbg(netdev,
"Disabling rx_scrq[%d] irq\n", i); "Disabling rx_scrq[%d] irq\n", i);
disable_irq(adapter->rx_scrq[i]->irq); disable_irq(adapter->rx_scrq[i]->irq);
} }
...@@ -1193,8 +1176,20 @@ static int __ibmvnic_close(struct net_device *netdev) ...@@ -1193,8 +1176,20 @@ static int __ibmvnic_close(struct net_device *netdev)
} }
clean_rx_pools(adapter); clean_rx_pools(adapter);
clean_tx_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; adapter->state = VNIC_CLOSED;
return rc; return 0;
} }
static int ibmvnic_close(struct net_device *netdev) static int ibmvnic_close(struct net_device *netdev)
...@@ -1658,12 +1653,15 @@ static int do_reset(struct ibmvnic_adapter *adapter, ...@@ -1658,12 +1653,15 @@ static int do_reset(struct ibmvnic_adapter *adapter,
rc = ibmvnic_reenable_crq_queue(adapter); rc = ibmvnic_reenable_crq_queue(adapter);
if (rc) if (rc)
return 0; 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 || if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM ||
adapter->wait_for_reset) { adapter->wait_for_reset) {
release_resources(adapter); release_resources(adapter);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment