diff options
author | David S. Miller <davem@davemloft.net> | 2017-06-15 20:29:01 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-06-15 20:29:01 +0200 |
commit | 18b6e7955d8f85613478ac1edd01dc1fb4c2a305 (patch) | |
tree | fb0e1abc90a1e1bd09cab91a0781e4c60e4e1232 | |
parent | sunvnet: restrict advertized checksum offloads to just IP (diff) | |
parent | ibmvnic: Exit polling routine correctly during adapter reset (diff) | |
download | linux-18b6e7955d8f85613478ac1edd01dc1fb4c2a305.tar.xz linux-18b6e7955d8f85613478ac1edd01dc1fb4c2a305.zip |
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.c | 23 |
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; |