diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-10-26 07:32:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-26 19:09:01 -0400 |
commit | 39305965f31e080d6ed96e0ff51ed11e7639d52e (patch) | |
tree | e01872ac6287905362f611324ae78cc245499cba /drivers/net/igbvf | |
parent | 759884b4d4cbafcd3f222b29cd6e0c2cbc542d2b (diff) |
igbvf: fix memory leak when ring size changed while interface down
This patch resolves a memory leak which occurs while changing the ring size
while the interface is down.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igbvf')
-rw-r--r-- | drivers/net/igbvf/ethtool.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c index ee17a097d1ca..c68265bd0d1a 100644 --- a/drivers/net/igbvf/ethtool.c +++ b/drivers/net/igbvf/ethtool.c | |||
@@ -279,7 +279,7 @@ static int igbvf_set_ringparam(struct net_device *netdev, | |||
279 | { | 279 | { |
280 | struct igbvf_adapter *adapter = netdev_priv(netdev); | 280 | struct igbvf_adapter *adapter = netdev_priv(netdev); |
281 | struct igbvf_ring *temp_ring; | 281 | struct igbvf_ring *temp_ring; |
282 | int err; | 282 | int err = 0; |
283 | u32 new_rx_count, new_tx_count; | 283 | u32 new_rx_count, new_tx_count; |
284 | 284 | ||
285 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 285 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
@@ -299,15 +299,22 @@ static int igbvf_set_ringparam(struct net_device *netdev, | |||
299 | return 0; | 299 | return 0; |
300 | } | 300 | } |
301 | 301 | ||
302 | temp_ring = vmalloc(sizeof(struct igbvf_ring)); | ||
303 | if (!temp_ring) | ||
304 | return -ENOMEM; | ||
305 | |||
306 | while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state)) | 302 | while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state)) |
307 | msleep(1); | 303 | msleep(1); |
308 | 304 | ||
309 | if (netif_running(adapter->netdev)) | 305 | if (!netif_running(adapter->netdev)) { |
310 | igbvf_down(adapter); | 306 | adapter->tx_ring->count = new_tx_count; |
307 | adapter->rx_ring->count = new_rx_count; | ||
308 | goto clear_reset; | ||
309 | } | ||
310 | |||
311 | temp_ring = vmalloc(sizeof(struct igbvf_ring)); | ||
312 | if (!temp_ring) { | ||
313 | err = -ENOMEM; | ||
314 | goto clear_reset; | ||
315 | } | ||
316 | |||
317 | igbvf_down(adapter); | ||
311 | 318 | ||
312 | /* | 319 | /* |
313 | * We can't just free everything and then setup again, | 320 | * We can't just free everything and then setup again, |
@@ -339,14 +346,11 @@ static int igbvf_set_ringparam(struct net_device *netdev, | |||
339 | 346 | ||
340 | memcpy(adapter->rx_ring, temp_ring,sizeof(struct igbvf_ring)); | 347 | memcpy(adapter->rx_ring, temp_ring,sizeof(struct igbvf_ring)); |
341 | } | 348 | } |
342 | |||
343 | err = 0; | ||
344 | err_setup: | 349 | err_setup: |
345 | if (netif_running(adapter->netdev)) | 350 | igbvf_up(adapter); |
346 | igbvf_up(adapter); | ||
347 | |||
348 | clear_bit(__IGBVF_RESETTING, &adapter->state); | ||
349 | vfree(temp_ring); | 351 | vfree(temp_ring); |
352 | clear_reset: | ||
353 | clear_bit(__IGBVF_RESETTING, &adapter->state); | ||
350 | return err; | 354 | return err; |
351 | } | 355 | } |
352 | 356 | ||