summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/i40evf/i40evf_main.c
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2014-04-24 06:41:37 +0000
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-06-05 02:13:01 -0700
commitd732a18445071fea4e062c3d66e2fc21f1bd1290 (patch)
treec8b273d1907855ccdb7e4351151acf075bf5c49f /drivers/net/ethernet/intel/i40evf/i40evf_main.c
parent337eb08e5ad0c3e7929d1f1745165af412e7d6eb (diff)
i40evf: fix crash when changing ring sizes
i40evf_set_ringparam was broken in several ways. First, it only changed the size of the first ring, and second, changing the ring size would often result in a panic because it would change the count before deallocating resources, causing the driver to either free nonexistent buffers, or leak leftover buffers. Fix this by storing the descriptor count in the adapter structure, and updating the count for each ring each time we allocate them. This ensures that we always free the right size ring, and always end up with the requested count when the device is (re)opened. Change-ID: I298396cd3d452ba8509d9f2d33a93f25868a9a55 Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/i40evf/i40evf_main.c')
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 632c2b32afa..d24f40f1673 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -1091,14 +1091,14 @@ static int i40evf_alloc_queues(struct i40evf_adapter *adapter)
tx_ring->queue_index = i;
tx_ring->netdev = adapter->netdev;
tx_ring->dev = &adapter->pdev->dev;
- tx_ring->count = I40EVF_DEFAULT_TXD;
+ tx_ring->count = adapter->tx_desc_count;
adapter->tx_rings[i] = tx_ring;
rx_ring = &tx_ring[1];
rx_ring->queue_index = i;
rx_ring->netdev = adapter->netdev;
rx_ring->dev = &adapter->pdev->dev;
- rx_ring->count = I40EVF_DEFAULT_RXD;
+ rx_ring->count = adapter->rx_desc_count;
adapter->rx_rings[i] = rx_ring;
}
@@ -1669,6 +1669,7 @@ static int i40evf_setup_all_tx_resources(struct i40evf_adapter *adapter)
int i, err = 0;
for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) {
+ adapter->tx_rings[i]->count = adapter->tx_desc_count;
err = i40evf_setup_tx_descriptors(adapter->tx_rings[i]);
if (!err)
continue;
@@ -1696,6 +1697,7 @@ static int i40evf_setup_all_rx_resources(struct i40evf_adapter *adapter)
int i, err = 0;
for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) {
+ adapter->rx_rings[i]->count = adapter->rx_desc_count;
err = i40evf_setup_rx_descriptors(adapter->rx_rings[i]);
if (!err)
continue;
@@ -2092,6 +2094,8 @@ static void i40evf_init_task(struct work_struct *work)
adapter->watchdog_timer.data = (unsigned long)adapter;
mod_timer(&adapter->watchdog_timer, jiffies + 1);
+ adapter->tx_desc_count = I40EVF_DEFAULT_TXD;
+ adapter->rx_desc_count = I40EVF_DEFAULT_RXD;
err = i40evf_init_interrupt_scheme(adapter);
if (err)
goto err_sw_init;