aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorDan Carpenter <error27@gmail.com>2010-05-06 09:22:21 -0400
committerRoland Dreier <rolandd@cisco.com>2010-05-12 12:30:45 -0400
commit9fda1ac5fa09c49e9148f85be14f55e2bb856c0f (patch)
treedef6cf681e460d54b6fc7fe148e5756fb9d5c4c0 /drivers/infiniband
parent39ff05dbbbdb082bbabf06206c56b3cd4ef73904 (diff)
IB/iser: Fix error flow in iser_create_ib_conn_res()
We shouldn't free things here because we free them later. The call tree looks like this: iser_connect() ==> initiating the connection establishment and later iser_cma_handler() => iser_route_handler() => iser_create_ib_conn_res() if we fail here, eventually iser_conn_release() is called, resulting in a double free. Signed-off-by: Dan Carpenter <error27@gmail.com> Signed-off-by: Or Gerlitz <ogerlitz@voltaire.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 78fdecacea35..9876865732f7 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -163,10 +163,8 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
163 device = ib_conn->device; 163 device = ib_conn->device;
164 164
165 ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL); 165 ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL);
166 if (!ib_conn->login_buf) { 166 if (!ib_conn->login_buf)
167 goto alloc_err; 167 goto out_err;
168 ret = -ENOMEM;
169 }
170 168
171 ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device, 169 ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device,
172 (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE, 170 (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE,
@@ -175,10 +173,9 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
175 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + 173 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) +
176 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), 174 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)),
177 GFP_KERNEL); 175 GFP_KERNEL);
178 if (!ib_conn->page_vec) { 176 if (!ib_conn->page_vec)
179 ret = -ENOMEM; 177 goto out_err;
180 goto alloc_err; 178
181 }
182 ib_conn->page_vec->pages = (u64 *) (ib_conn->page_vec + 1); 179 ib_conn->page_vec->pages = (u64 *) (ib_conn->page_vec + 1);
183 180
184 params.page_shift = SHIFT_4K; 181 params.page_shift = SHIFT_4K;
@@ -198,7 +195,8 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
198 ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, &params); 195 ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, &params);
199 if (IS_ERR(ib_conn->fmr_pool)) { 196 if (IS_ERR(ib_conn->fmr_pool)) {
200 ret = PTR_ERR(ib_conn->fmr_pool); 197 ret = PTR_ERR(ib_conn->fmr_pool);
201 goto fmr_pool_err; 198 ib_conn->fmr_pool = NULL;
199 goto out_err;
202 } 200 }
203 201
204 memset(&init_attr, 0, sizeof init_attr); 202 memset(&init_attr, 0, sizeof init_attr);
@@ -216,7 +214,7 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
216 214
217 ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr); 215 ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr);
218 if (ret) 216 if (ret)
219 goto qp_err; 217 goto out_err;
220 218
221 ib_conn->qp = ib_conn->cma_id->qp; 219 ib_conn->qp = ib_conn->cma_id->qp;
222 iser_err("setting conn %p cma_id %p: fmr_pool %p qp %p\n", 220 iser_err("setting conn %p cma_id %p: fmr_pool %p qp %p\n",
@@ -224,12 +222,7 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
224 ib_conn->fmr_pool, ib_conn->cma_id->qp); 222 ib_conn->fmr_pool, ib_conn->cma_id->qp);
225 return ret; 223 return ret;
226 224
227qp_err: 225out_err:
228 (void)ib_destroy_fmr_pool(ib_conn->fmr_pool);
229fmr_pool_err:
230 kfree(ib_conn->page_vec);
231 kfree(ib_conn->login_buf);
232alloc_err:
233 iser_err("unable to alloc mem or create resource, err %d\n", ret); 226 iser_err("unable to alloc mem or create resource, err %d\n", ret);
234 return ret; 227 return ret;
235} 228}