vxge: fix memory leak in vxge_alloc_msix() error path
authorMichal Schmidt <mschmidt@redhat.com>
Thu, 24 Jun 2010 04:13:44 +0000 (04:13 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 27 Jun 2010 05:10:04 +0000 (22:10 -0700)
When pci_enable_msix() returned ret<0, entries and vxge_entries were leaked.
While at it, use the centralized exit idiom in the function.

Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
Acked-by: Ram Vepa <ram.vepa@exar.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/vxge/vxge-main.c

index b504bd56136210776fa0d31e87a5e00b687cb03b..d14e207de1df8c8f074d0428e0d21d380344a7f2 100644 (file)
@@ -2262,7 +2262,8 @@ start:
                vxge_debug_init(VXGE_ERR,
                        "%s: memory allocation failed",
                        VXGE_DRIVER_NAME);
-               return  -ENOMEM;
+               ret = -ENOMEM;
+               goto alloc_entries_failed;
        }
 
        vdev->vxge_entries =
@@ -2271,8 +2272,8 @@ start:
        if (!vdev->vxge_entries) {
                vxge_debug_init(VXGE_ERR, "%s: memory allocation failed",
                        VXGE_DRIVER_NAME);
-               kfree(vdev->entries);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto alloc_vxge_entries_failed;
        }
 
        for (i = 0, j = 0; i < vdev->no_of_vpath; i++) {
@@ -2303,22 +2304,32 @@ start:
                vxge_debug_init(VXGE_ERR,
                        "%s: MSI-X enable failed for %d vectors, ret: %d",
                        VXGE_DRIVER_NAME, vdev->intr_cnt, ret);
+               if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) {
+                       ret = -ENODEV;
+                       goto enable_msix_failed;
+               }
+
                kfree(vdev->entries);
                kfree(vdev->vxge_entries);
                vdev->entries = NULL;
                vdev->vxge_entries = NULL;
-
-               if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3))
-                       return -ENODEV;
                /* Try with less no of vector by reducing no of vpaths count */
                temp = (ret - 1)/2;
                vxge_close_vpaths(vdev, temp);
                vdev->no_of_vpath = temp;
                goto start;
-       } else if (ret < 0)
-               return -ENODEV;
-
+       } else if (ret < 0) {
+               ret = -ENODEV;
+               goto enable_msix_failed;
+       }
        return 0;
+
+enable_msix_failed:
+       kfree(vdev->vxge_entries);
+alloc_vxge_entries_failed:
+       kfree(vdev->entries);
+alloc_entries_failed:
+       return ret;
 }
 
 static int vxge_enable_msix(struct vxgedev *vdev)