aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorRoi Dayan <roid@mellanox.com>2014-09-02 10:08:41 -0400
committerRoland Dreier <roland@purestorage.com>2014-09-22 12:46:42 -0400
commitc33b15f00bbfb9324dc38e5176f576a0f46e0873 (patch)
tree2befec36153b1d9afc4e3237320b72a906a3dbca /drivers/infiniband
parent52addcf9d6669fa439387610bc65c92fa0980cef (diff)
IB/iser: Fix RX/TX CQ resource leak on error flow
When failing to allocate TX CQ we already allocated RX CQ, so we need to make sure we release it. Also, when failing to register notification to the RX CQ we currently leak both RX and TX CQs of the current index, fix that too. Signed-off-by: Roi Dayan <roid@mellanox.com> Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 3ef167f97d6f..3bfec4bbda52 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -73,7 +73,7 @@ static int iser_create_device_ib_res(struct iser_device *device)
73{ 73{
74 struct iser_cq_desc *cq_desc; 74 struct iser_cq_desc *cq_desc;
75 struct ib_device_attr *dev_attr = &device->dev_attr; 75 struct ib_device_attr *dev_attr = &device->dev_attr;
76 int ret, i, j; 76 int ret, i;
77 77
78 ret = ib_query_device(device->ib_device, dev_attr); 78 ret = ib_query_device(device->ib_device, dev_attr);
79 if (ret) { 79 if (ret) {
@@ -125,16 +125,20 @@ static int iser_create_device_ib_res(struct iser_device *device)
125 iser_cq_event_callback, 125 iser_cq_event_callback,
126 (void *)&cq_desc[i], 126 (void *)&cq_desc[i],
127 ISER_MAX_RX_CQ_LEN, i); 127 ISER_MAX_RX_CQ_LEN, i);
128 if (IS_ERR(device->rx_cq[i])) 128 if (IS_ERR(device->rx_cq[i])) {
129 device->rx_cq[i] = NULL;
129 goto cq_err; 130 goto cq_err;
131 }
130 132
131 device->tx_cq[i] = ib_create_cq(device->ib_device, 133 device->tx_cq[i] = ib_create_cq(device->ib_device,
132 NULL, iser_cq_event_callback, 134 NULL, iser_cq_event_callback,
133 (void *)&cq_desc[i], 135 (void *)&cq_desc[i],
134 ISER_MAX_TX_CQ_LEN, i); 136 ISER_MAX_TX_CQ_LEN, i);
135 137
136 if (IS_ERR(device->tx_cq[i])) 138 if (IS_ERR(device->tx_cq[i])) {
139 device->tx_cq[i] = NULL;
137 goto cq_err; 140 goto cq_err;
141 }
138 142
139 if (ib_req_notify_cq(device->rx_cq[i], IB_CQ_NEXT_COMP)) 143 if (ib_req_notify_cq(device->rx_cq[i], IB_CQ_NEXT_COMP))
140 goto cq_err; 144 goto cq_err;
@@ -160,14 +164,14 @@ static int iser_create_device_ib_res(struct iser_device *device)
160handler_err: 164handler_err:
161 ib_dereg_mr(device->mr); 165 ib_dereg_mr(device->mr);
162dma_mr_err: 166dma_mr_err:
163 for (j = 0; j < device->cqs_used; j++) 167 for (i = 0; i < device->cqs_used; i++)
164 tasklet_kill(&device->cq_tasklet[j]); 168 tasklet_kill(&device->cq_tasklet[i]);
165cq_err: 169cq_err:
166 for (j = 0; j < i; j++) { 170 for (i = 0; i < device->cqs_used; i++) {
167 if (device->tx_cq[j]) 171 if (device->tx_cq[i])
168 ib_destroy_cq(device->tx_cq[j]); 172 ib_destroy_cq(device->tx_cq[i]);
169 if (device->rx_cq[j]) 173 if (device->rx_cq[i])
170 ib_destroy_cq(device->rx_cq[j]); 174 ib_destroy_cq(device->rx_cq[i]);
171 } 175 }
172 ib_dealloc_pd(device->pd); 176 ib_dealloc_pd(device->pd);
173pd_err: 177pd_err: