Commit 637f81d1 authored by Thomas Falcon's avatar Thomas Falcon Committed by David S. Miller

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: default avatarThomas Falcon <tlfalcon@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 53cc7721
...@@ -1081,6 +1081,7 @@ static int ibmvnic_open(struct net_device *netdev) ...@@ -1081,6 +1081,7 @@ static int ibmvnic_open(struct net_device *netdev)
static void clean_rx_pools(struct ibmvnic_adapter *adapter) static void clean_rx_pools(struct ibmvnic_adapter *adapter)
{ {
struct ibmvnic_rx_pool *rx_pool; struct ibmvnic_rx_pool *rx_pool;
struct ibmvnic_rx_buff *rx_buff;
u64 rx_entries; u64 rx_entries;
int rx_scrqs; int rx_scrqs;
int i, j; int i, j;
...@@ -1094,14 +1095,15 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter) ...@@ -1094,14 +1095,15 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter)
/* Free any remaining skbs in the rx buffer pools */ /* Free any remaining skbs in the rx buffer pools */
for (i = 0; i < rx_scrqs; i++) { for (i = 0; i < rx_scrqs; i++) {
rx_pool = &adapter->rx_pool[i]; rx_pool = &adapter->rx_pool[i];
if (!rx_pool) if (!rx_pool || !rx_pool->rx_buff)
continue; continue;
netdev_dbg(adapter->netdev, "Cleaning rx_pool[%d]\n", i); netdev_dbg(adapter->netdev, "Cleaning rx_pool[%d]\n", i);
for (j = 0; j < rx_entries; j++) { for (j = 0; j < rx_entries; j++) {
if (rx_pool->rx_buff[j].skb) { rx_buff = &rx_pool->rx_buff[j];
dev_kfree_skb_any(rx_pool->rx_buff[j].skb); if (rx_buff && rx_buff->skb) {
rx_pool->rx_buff[j].skb = NULL; dev_kfree_skb_any(rx_buff->skb);
rx_buff->skb = NULL;
} }
} }
} }
...@@ -1110,6 +1112,7 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter) ...@@ -1110,6 +1112,7 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter)
static void clean_tx_pools(struct ibmvnic_adapter *adapter) static void clean_tx_pools(struct ibmvnic_adapter *adapter)
{ {
struct ibmvnic_tx_pool *tx_pool; struct ibmvnic_tx_pool *tx_pool;
struct ibmvnic_tx_buff *tx_buff;
u64 tx_entries; u64 tx_entries;
int tx_scrqs; int tx_scrqs;
int i, j; int i, j;
...@@ -1123,14 +1126,15 @@ static void clean_tx_pools(struct ibmvnic_adapter *adapter) ...@@ -1123,14 +1126,15 @@ static void clean_tx_pools(struct ibmvnic_adapter *adapter)
/* Free any remaining skbs in the tx buffer pools */ /* Free any remaining skbs in the tx buffer pools */
for (i = 0; i < tx_scrqs; i++) { for (i = 0; i < tx_scrqs; i++) {
tx_pool = &adapter->tx_pool[i]; tx_pool = &adapter->tx_pool[i];
if (!tx_pool) if (!tx_pool && !tx_pool->tx_buff)
continue; continue;
netdev_dbg(adapter->netdev, "Cleaning tx_pool[%d]\n", i); netdev_dbg(adapter->netdev, "Cleaning tx_pool[%d]\n", i);
for (j = 0; j < tx_entries; j++) { for (j = 0; j < tx_entries; j++) {
if (tx_pool->tx_buff[j].skb) { tx_buff = &tx_pool->tx_buff[j];
dev_kfree_skb_any(tx_pool->tx_buff[j].skb); if (tx_buff && tx_buff->skb) {
tx_pool->tx_buff[j].skb = NULL; dev_kfree_skb_any(tx_buff->skb);
tx_buff->skb = NULL;
} }
} }
} }
......
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