diff options
author | Thomas Falcon <tlfalcon@linux.vnet.ibm.com> | 2018-02-26 18:10:57 -0600 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-27 14:31:19 -0500 |
commit | 637f81d164a5347ee3325f106f815c7969c032b5 (patch) | |
tree | 414aac998aee6222ca3ff51e67360adce1092872 /drivers/net/ethernet/ibm | |
parent | 53cc7721fdf12e649994cfb7d8f562acb0e4510b (diff) |
ibmvnic: Harden TX/RX pool cleaning
If the driver releases resources after a failed reset or some other
error, the driver might attempt to clean up and free memory that
isn't there anymore. Include some additional checks that RX/TX queues
along with their associated structures are still there before cleaning.
Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ibm')
-rw-r--r-- | drivers/net/ethernet/ibm/ibmvnic.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 1a0f67b60003..b907c0a607e6 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1081,6 +1081,7 @@ static int ibmvnic_open(struct net_device *netdev) static void clean_rx_pools(struct ibmvnic_adapter *adapter) { struct ibmvnic_rx_pool *rx_pool; + struct ibmvnic_rx_buff *rx_buff; u64 rx_entries; int rx_scrqs; int i, j; @@ -1094,14 +1095,15 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter) /* Free any remaining skbs in the rx buffer pools */ for (i = 0; i < rx_scrqs; i++) { rx_pool = &adapter->rx_pool[i]; - if (!rx_pool) + if (!rx_pool || !rx_pool->rx_buff) continue; netdev_dbg(adapter->netdev, "Cleaning rx_pool[%d]\n", i); for (j = 0; j < rx_entries; j++) { - if (rx_pool->rx_buff[j].skb) { - dev_kfree_skb_any(rx_pool->rx_buff[j].skb); - rx_pool->rx_buff[j].skb = NULL; + rx_buff = &rx_pool->rx_buff[j]; + if (rx_buff && rx_buff->skb) { + dev_kfree_skb_any(rx_buff->skb); + rx_buff->skb = NULL; } } } @@ -1110,6 +1112,7 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter) static void clean_tx_pools(struct ibmvnic_adapter *adapter) { struct ibmvnic_tx_pool *tx_pool; + struct ibmvnic_tx_buff *tx_buff; u64 tx_entries; int tx_scrqs; int i, j; @@ -1123,14 +1126,15 @@ static void clean_tx_pools(struct ibmvnic_adapter *adapter) /* Free any remaining skbs in the tx buffer pools */ for (i = 0; i < tx_scrqs; i++) { tx_pool = &adapter->tx_pool[i]; - if (!tx_pool) + if (!tx_pool && !tx_pool->tx_buff) continue; netdev_dbg(adapter->netdev, "Cleaning tx_pool[%d]\n", i); for (j = 0; j < tx_entries; j++) { - if (tx_pool->tx_buff[j].skb) { - dev_kfree_skb_any(tx_pool->tx_buff[j].skb); - tx_pool->tx_buff[j].skb = NULL; + tx_buff = &tx_pool->tx_buff[j]; + if (tx_buff && tx_buff->skb) { + dev_kfree_skb_any(tx_buff->skb); + tx_buff->skb = NULL; } } } |