diff options
author | Roland Dreier <rolandd@cisco.com> | 2005-10-06 16:28:16 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2005-10-17 18:20:28 -0400 |
commit | 4ab6fb7e5b3d34b65a1c3473d80d9d1a462d3a49 (patch) | |
tree | 3a78a17d4499bf95cc23be72ffb88bd49c8e7852 /drivers/infiniband | |
parent | e23d6d2b090658007732770720a44375cba23200 (diff) |
[IB] Fix leak on MAD initialization failure
There is a bug in ib_mad_init_device(): if ib_agent_port_open() fails
for a given port, then the current code doesn't call ib_mad_port_close()
for that port.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/mad.c | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index a14ca87fda18..af302e830561 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -2683,40 +2683,47 @@ static int ib_mad_port_close(struct ib_device *device, int port_num) | |||
2683 | 2683 | ||
2684 | static void ib_mad_init_device(struct ib_device *device) | 2684 | static void ib_mad_init_device(struct ib_device *device) |
2685 | { | 2685 | { |
2686 | int num_ports, cur_port, i; | 2686 | int start, end, i; |
2687 | 2687 | ||
2688 | if (device->node_type == IB_NODE_SWITCH) { | 2688 | if (device->node_type == IB_NODE_SWITCH) { |
2689 | num_ports = 1; | 2689 | start = 0; |
2690 | cur_port = 0; | 2690 | end = 0; |
2691 | } else { | 2691 | } else { |
2692 | num_ports = device->phys_port_cnt; | 2692 | start = 1; |
2693 | cur_port = 1; | 2693 | end = device->phys_port_cnt; |
2694 | } | 2694 | } |
2695 | for (i = 0; i < num_ports; i++, cur_port++) { | 2695 | |
2696 | if (ib_mad_port_open(device, cur_port)) { | 2696 | for (i = start; i <= end; i++) { |
2697 | if (ib_mad_port_open(device, i)) { | ||
2697 | printk(KERN_ERR PFX "Couldn't open %s port %d\n", | 2698 | printk(KERN_ERR PFX "Couldn't open %s port %d\n", |
2698 | device->name, cur_port); | 2699 | device->name, i); |
2699 | goto error_device_open; | 2700 | goto error; |
2700 | } | 2701 | } |
2701 | if (ib_agent_port_open(device, cur_port)) { | 2702 | if (ib_agent_port_open(device, i)) { |
2702 | printk(KERN_ERR PFX "Couldn't open %s port %d " | 2703 | printk(KERN_ERR PFX "Couldn't open %s port %d " |
2703 | "for agents\n", | 2704 | "for agents\n", |
2704 | device->name, cur_port); | 2705 | device->name, i); |
2705 | goto error_device_open; | 2706 | goto error_agent; |
2706 | } | 2707 | } |
2707 | } | 2708 | } |
2708 | return; | 2709 | return; |
2709 | 2710 | ||
2710 | error_device_open: | 2711 | error_agent: |
2711 | while (i > 0) { | 2712 | if (ib_mad_port_close(device, i)) |
2712 | cur_port--; | 2713 | printk(KERN_ERR PFX "Couldn't close %s port %d\n", |
2713 | if (ib_agent_port_close(device, cur_port)) | 2714 | device->name, i); |
2715 | |||
2716 | error: | ||
2717 | i--; | ||
2718 | |||
2719 | while (i >= start) { | ||
2720 | if (ib_agent_port_close(device, i)) | ||
2714 | printk(KERN_ERR PFX "Couldn't close %s port %d " | 2721 | printk(KERN_ERR PFX "Couldn't close %s port %d " |
2715 | "for agents\n", | 2722 | "for agents\n", |
2716 | device->name, cur_port); | 2723 | device->name, i); |
2717 | if (ib_mad_port_close(device, cur_port)) | 2724 | if (ib_mad_port_close(device, i)) |
2718 | printk(KERN_ERR PFX "Couldn't close %s port %d\n", | 2725 | printk(KERN_ERR PFX "Couldn't close %s port %d\n", |
2719 | device->name, cur_port); | 2726 | device->name, i); |
2720 | i--; | 2727 | i--; |
2721 | } | 2728 | } |
2722 | } | 2729 | } |