summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-06-15 14:29:01 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-15 14:29:01 -0400
commit18b6e7955d8f85613478ac1edd01dc1fb4c2a305 (patch)
treefb0e1abc90a1e1bd09cab91a0781e4c60e4e1232
parent7e9191c54a36c864b901ea8ce56dc42f10c2f5ae (diff)
parent21ecba6c48f903781d844b62854bedd8137df470 (diff)
Merge branch 'ibmvnic-LPM-bug-fixes'
Thomas Falcon says: ==================== ibmvnic: LPM bug fixes This series of small patches is meant to resolve a number of bugs, mostly occurring during an ibmvnic driver reset when recovering from a logical partition migration (LPM). The first patch ensures that RX buffer pools are properly activated following an adapter reset by setting the proper flag in the pool data structure. The second patch uses netif_tx_disable to stop TX queues when closing the device during a reset. Third, fixup a typo that resulted in partial sanitization of TX/RX descriptor queues following a device reset. Fourth, remove an ambiguous conditional check that was resulting in a kernel panic as null RX/TX completion descriptors were being processed during napi polling while the device is closing. Finally, fix a condition where the napi polling routine exits before it has completed its work budget without notifying the upper network layers. This omission could result in the napi_disable function sleeping indefinitely under certain conditions. v2: Attempt to provide a proper cover letter ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 78fdd4f0e341..9923b9fa0c74 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -383,6 +383,7 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
atomic_set(&rx_pool->available, 0);
rx_pool->next_alloc = 0;
rx_pool->next_free = 0;
+ rx_pool->active = 1;
}
return 0;
@@ -885,7 +886,13 @@ static int __ibmvnic_close(struct net_device *netdev)
int i;
adapter->state = VNIC_CLOSING;
- netif_tx_stop_all_queues(netdev);
+
+ /* ensure that transmissions are stopped if called by do_reset */
+ if (adapter->resetting)
+ netif_tx_disable(netdev);
+ else
+ netif_tx_stop_all_queues(netdev);
+
ibmvnic_napi_disable(adapter);
if (adapter->tx_scrq) {
@@ -1498,9 +1505,6 @@ static int ibmvnic_poll(struct napi_struct *napi, int budget)
int scrq_num = (int)(napi - adapter->napi);
int frames_processed = 0;
- if (adapter->resetting)
- return 0;
-
restart_poll:
while (frames_processed < budget) {
struct sk_buff *skb;
@@ -1510,6 +1514,12 @@ restart_poll:
u16 offset;
u8 flags = 0;
+ if (unlikely(adapter->resetting)) {
+ enable_scrq_irq(adapter, adapter->rx_scrq[scrq_num]);
+ napi_complete_done(napi, frames_processed);
+ return frames_processed;
+ }
+
if (!pending_scrq(adapter, adapter->rx_scrq[scrq_num]))
break;
next = ibmvnic_next_scrq(adapter, adapter->rx_scrq[scrq_num]);
@@ -1745,7 +1755,7 @@ static int reset_one_sub_crq_queue(struct ibmvnic_adapter *adapter,
scrq->irq = 0;
}
- memset(scrq->msgs, 0, 2 * PAGE_SIZE);
+ memset(scrq->msgs, 0, 4 * PAGE_SIZE);
scrq->cur = 0;
rc = h_reg_sub_crq(adapter->vdev->unit_address, scrq->msg_token,
@@ -2268,8 +2278,7 @@ static int pending_scrq(struct ibmvnic_adapter *adapter,
{
union sub_crq *entry = &scrq->msgs[scrq->cur];
- if (entry->generic.first & IBMVNIC_CRQ_CMD_RSP ||
- adapter->state == VNIC_CLOSING)
+ if (entry->generic.first & IBMVNIC_CRQ_CMD_RSP)
return 1;
else
return 0;