From c3e53b9a3efe300a7864ab1ccfbae239d50d0002 Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Wed, 14 Jun 2017 23:50:05 -0500 Subject: [PATCH 1/5] ibmvnic: Activate disabled RX buffer pools on reset RX buffer pools are disabled while awaiting a device reset if firmware indicates that the resource is closed. This patch fixes a bug where pools were not being subsequently enabled after the device reset, causing the device to become inoperable. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 78fdd4f0e341..99c552a79e9d 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; From 4c2687a512b9a6737e86d72f23ad0a1097d56bd5 Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Wed, 14 Jun 2017 23:50:06 -0500 Subject: [PATCH 2/5] ibmvnic: Ensure that TX queues are disabled in __ibmvnic_close Use netif_tx_disable to guarantee that TX queues are disabled when __ibmvnic_close is called by the device reset routine. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 99c552a79e9d..134ab295c1d6 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -886,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) { From c8b2ad0a4a9015228874708f83a17b7bdb194f84 Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Wed, 14 Jun 2017 23:50:07 -0500 Subject: [PATCH 3/5] ibmvnic: Sanitize entire SCRQ buffer on reset Fixup a typo so that the entire SCRQ buffer is cleaned. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 134ab295c1d6..03ddf6e1b5b3 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1752,7 +1752,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, From 1cf9cc72bd7024af69419b5adee42c39ad4caf6f Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Wed, 14 Jun 2017 23:50:08 -0500 Subject: [PATCH 4/5] ibmvnic: Remove VNIC_CLOSING check from pending_scrq Fix a kernel panic resulting from data access of a NULL pointer during device close. The pending_scrq routine is meant to determine whether there is a valid sub-CRQ message awaiting processing. When the device is closing, however, there is a possibility that NULL messages can be processed because pending_scrq will always return 1 even if there no valid message in the queue. It's not clear what this closing state check was originally meant to accomplish, so just remove it. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 03ddf6e1b5b3..ebe443fe51db 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -2275,8 +2275,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; From 21ecba6c48f903781d844b62854bedd8137df470 Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Wed, 14 Jun 2017 23:50:09 -0500 Subject: [PATCH 5/5] ibmvnic: Exit polling routine correctly during adapter reset This patch fixes a bug where, in the case of a device reset, the polling routine will never complete, causing napi_disable to sleep indefinitely when attempting to close the device. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index ebe443fe51db..9923b9fa0c74 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1505,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; @@ -1517,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]);