aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatan Barak <matanb@mellanox.com>2014-12-14 09:18:04 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-15 11:34:53 -0500
commitda315679e80635021e98de1306ff4eee0759ba57 (patch)
tree35ce69487bed726b3225d9bd320dd80d50e6a328
parent67e2c3883828b39548cee2091b36656787775d95 (diff)
net/mlx4_core: Fixed memory leak and incorrect refcount in mlx4_load_one
The current mlx4_load_one has a memory leak as it always allocates dev_cap, but frees it only on error. In addition, even if VFs exist when mlx4_load_one is called, we still need to notify probed VFs that we're loading (by incrementing pf_loading). Fixes: a0eacca948d2 ('net/mlx4_core: Refactor mlx4_load_one') Signed-off-by: Matan Barak <matanb@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index e25436b24ce7..c2ef266ad7c1 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2488,41 +2488,42 @@ static u64 mlx4_enable_sriov(struct mlx4_dev *dev, struct pci_dev *pdev,
2488 u8 total_vfs, int existing_vfs) 2488 u8 total_vfs, int existing_vfs)
2489{ 2489{
2490 u64 dev_flags = dev->flags; 2490 u64 dev_flags = dev->flags;
2491 int err = 0;
2491 2492
2492 dev->dev_vfs = kzalloc( 2493 atomic_inc(&pf_loading);
2493 total_vfs * sizeof(*dev->dev_vfs), 2494 if (dev->flags & MLX4_FLAG_SRIOV) {
2494 GFP_KERNEL); 2495 if (existing_vfs != total_vfs) {
2496 mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n",
2497 existing_vfs, total_vfs);
2498 total_vfs = existing_vfs;
2499 }
2500 }
2501
2502 dev->dev_vfs = kzalloc(total_vfs * sizeof(*dev->dev_vfs), GFP_KERNEL);
2495 if (NULL == dev->dev_vfs) { 2503 if (NULL == dev->dev_vfs) {
2496 mlx4_err(dev, "Failed to allocate memory for VFs\n"); 2504 mlx4_err(dev, "Failed to allocate memory for VFs\n");
2497 goto disable_sriov; 2505 goto disable_sriov;
2498 } else if (!(dev->flags & MLX4_FLAG_SRIOV)) { 2506 }
2499 int err = 0; 2507
2500 2508 if (!(dev->flags & MLX4_FLAG_SRIOV)) {
2501 atomic_inc(&pf_loading); 2509 mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", total_vfs);
2502 if (existing_vfs) { 2510 err = pci_enable_sriov(pdev, total_vfs);
2503 if (existing_vfs != total_vfs) 2511 }
2504 mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n", 2512 if (err) {
2505 existing_vfs, total_vfs); 2513 mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n",
2506 } else { 2514 err);
2507 mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", total_vfs); 2515 goto disable_sriov;
2508 err = pci_enable_sriov(pdev, total_vfs); 2516 } else {
2509 } 2517 mlx4_warn(dev, "Running in master mode\n");
2510 if (err) { 2518 dev_flags |= MLX4_FLAG_SRIOV |
2511 mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n", 2519 MLX4_FLAG_MASTER;
2512 err); 2520 dev_flags &= ~MLX4_FLAG_SLAVE;
2513 atomic_dec(&pf_loading); 2521 dev->num_vfs = total_vfs;
2514 goto disable_sriov;
2515 } else {
2516 mlx4_warn(dev, "Running in master mode\n");
2517 dev_flags |= MLX4_FLAG_SRIOV |
2518 MLX4_FLAG_MASTER;
2519 dev_flags &= ~MLX4_FLAG_SLAVE;
2520 dev->num_vfs = total_vfs;
2521 }
2522 } 2522 }
2523 return dev_flags; 2523 return dev_flags;
2524 2524
2525disable_sriov: 2525disable_sriov:
2526 atomic_dec(&pf_loading);
2526 dev->num_vfs = 0; 2527 dev->num_vfs = 0;
2527 kfree(dev->dev_vfs); 2528 kfree(dev->dev_vfs);
2528 return dev_flags & ~MLX4_FLAG_MASTER; 2529 return dev_flags & ~MLX4_FLAG_MASTER;
@@ -2606,8 +2607,10 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
2606 } 2607 }
2607 2608
2608 if (total_vfs) { 2609 if (total_vfs) {
2609 existing_vfs = pci_num_vf(pdev);
2610 dev->flags = MLX4_FLAG_MASTER; 2610 dev->flags = MLX4_FLAG_MASTER;
2611 existing_vfs = pci_num_vf(pdev);
2612 if (existing_vfs)
2613 dev->flags |= MLX4_FLAG_SRIOV;
2611 dev->num_vfs = total_vfs; 2614 dev->num_vfs = total_vfs;
2612 } 2615 }
2613 } 2616 }
@@ -2643,6 +2646,7 @@ slave_start:
2643 } 2646 }
2644 2647
2645 if (mlx4_is_master(dev)) { 2648 if (mlx4_is_master(dev)) {
2649 /* when we hit the goto slave_start below, dev_cap already initialized */
2646 if (!dev_cap) { 2650 if (!dev_cap) {
2647 dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL); 2651 dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL);
2648 2652
@@ -2849,6 +2853,7 @@ slave_start:
2849 if (mlx4_is_master(dev) && dev->num_vfs) 2853 if (mlx4_is_master(dev) && dev->num_vfs)
2850 atomic_dec(&pf_loading); 2854 atomic_dec(&pf_loading);
2851 2855
2856 kfree(dev_cap);
2852 return 0; 2857 return 0;
2853 2858
2854err_port: 2859err_port: