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 | |
| 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>
| -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 | } |
