diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.h | 2 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_initiator.c | 92 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 128 |
3 files changed, 151 insertions, 71 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index d694bcd479fe..fee8829053e0 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h | |||
@@ -395,4 +395,6 @@ void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); | |||
395 | int iser_initialize_task_headers(struct iscsi_task *task, | 395 | int iser_initialize_task_headers(struct iscsi_task *task, |
396 | struct iser_tx_desc *tx_desc); | 396 | struct iser_tx_desc *tx_desc); |
397 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn); | 397 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn); |
398 | int iser_create_fmr_pool(struct iser_conn *ib_conn); | ||
399 | void iser_free_fmr_pool(struct iser_conn *ib_conn); | ||
398 | #endif | 400 | #endif |
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index b6d81a86c976..626d950b64a8 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c | |||
@@ -170,6 +170,76 @@ static void iser_create_send_desc(struct iser_conn *ib_conn, | |||
170 | } | 170 | } |
171 | } | 171 | } |
172 | 172 | ||
173 | static void iser_free_login_buf(struct iser_conn *ib_conn) | ||
174 | { | ||
175 | if (!ib_conn->login_buf) | ||
176 | return; | ||
177 | |||
178 | if (ib_conn->login_req_dma) | ||
179 | ib_dma_unmap_single(ib_conn->device->ib_device, | ||
180 | ib_conn->login_req_dma, | ||
181 | ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE); | ||
182 | |||
183 | if (ib_conn->login_resp_dma) | ||
184 | ib_dma_unmap_single(ib_conn->device->ib_device, | ||
185 | ib_conn->login_resp_dma, | ||
186 | ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE); | ||
187 | |||
188 | kfree(ib_conn->login_buf); | ||
189 | |||
190 | /* make sure we never redo any unmapping */ | ||
191 | ib_conn->login_req_dma = 0; | ||
192 | ib_conn->login_resp_dma = 0; | ||
193 | ib_conn->login_buf = NULL; | ||
194 | } | ||
195 | |||
196 | static int iser_alloc_login_buf(struct iser_conn *ib_conn) | ||
197 | { | ||
198 | struct iser_device *device; | ||
199 | int req_err, resp_err; | ||
200 | |||
201 | BUG_ON(ib_conn->device == NULL); | ||
202 | |||
203 | device = ib_conn->device; | ||
204 | |||
205 | ib_conn->login_buf = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN + | ||
206 | ISER_RX_LOGIN_SIZE, GFP_KERNEL); | ||
207 | if (!ib_conn->login_buf) | ||
208 | goto out_err; | ||
209 | |||
210 | ib_conn->login_req_buf = ib_conn->login_buf; | ||
211 | ib_conn->login_resp_buf = ib_conn->login_buf + | ||
212 | ISCSI_DEF_MAX_RECV_SEG_LEN; | ||
213 | |||
214 | ib_conn->login_req_dma = ib_dma_map_single(ib_conn->device->ib_device, | ||
215 | (void *)ib_conn->login_req_buf, | ||
216 | ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE); | ||
217 | |||
218 | ib_conn->login_resp_dma = ib_dma_map_single(ib_conn->device->ib_device, | ||
219 | (void *)ib_conn->login_resp_buf, | ||
220 | ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE); | ||
221 | |||
222 | req_err = ib_dma_mapping_error(device->ib_device, | ||
223 | ib_conn->login_req_dma); | ||
224 | resp_err = ib_dma_mapping_error(device->ib_device, | ||
225 | ib_conn->login_resp_dma); | ||
226 | |||
227 | if (req_err || resp_err) { | ||
228 | if (req_err) | ||
229 | ib_conn->login_req_dma = 0; | ||
230 | if (resp_err) | ||
231 | ib_conn->login_resp_dma = 0; | ||
232 | goto free_login_buf; | ||
233 | } | ||
234 | return 0; | ||
235 | |||
236 | free_login_buf: | ||
237 | iser_free_login_buf(ib_conn); | ||
238 | |||
239 | out_err: | ||
240 | iser_err("unable to alloc or map login buf\n"); | ||
241 | return -ENOMEM; | ||
242 | } | ||
173 | 243 | ||
174 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) | 244 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) |
175 | { | 245 | { |
@@ -179,6 +249,12 @@ int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) | |||
179 | struct ib_sge *rx_sg; | 249 | struct ib_sge *rx_sg; |
180 | struct iser_device *device = ib_conn->device; | 250 | struct iser_device *device = ib_conn->device; |
181 | 251 | ||
252 | if (iser_create_fmr_pool(ib_conn)) | ||
253 | goto create_fmr_pool_failed; | ||
254 | |||
255 | if (iser_alloc_login_buf(ib_conn)) | ||
256 | goto alloc_login_buf_fail; | ||
257 | |||
182 | ib_conn->rx_descs = kmalloc(ISER_QP_MAX_RECV_DTOS * | 258 | ib_conn->rx_descs = kmalloc(ISER_QP_MAX_RECV_DTOS * |
183 | sizeof(struct iser_rx_desc), GFP_KERNEL); | 259 | sizeof(struct iser_rx_desc), GFP_KERNEL); |
184 | if (!ib_conn->rx_descs) | 260 | if (!ib_conn->rx_descs) |
@@ -207,10 +283,14 @@ rx_desc_dma_map_failed: | |||
207 | rx_desc = ib_conn->rx_descs; | 283 | rx_desc = ib_conn->rx_descs; |
208 | for (j = 0; j < i; j++, rx_desc++) | 284 | for (j = 0; j < i; j++, rx_desc++) |
209 | ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr, | 285 | ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr, |
210 | ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); | 286 | ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); |
211 | kfree(ib_conn->rx_descs); | 287 | kfree(ib_conn->rx_descs); |
212 | ib_conn->rx_descs = NULL; | 288 | ib_conn->rx_descs = NULL; |
213 | rx_desc_alloc_fail: | 289 | rx_desc_alloc_fail: |
290 | iser_free_login_buf(ib_conn); | ||
291 | alloc_login_buf_fail: | ||
292 | iser_free_fmr_pool(ib_conn); | ||
293 | create_fmr_pool_failed: | ||
214 | iser_err("failed allocating rx descriptors / data buffers\n"); | 294 | iser_err("failed allocating rx descriptors / data buffers\n"); |
215 | return -ENOMEM; | 295 | return -ENOMEM; |
216 | } | 296 | } |
@@ -222,13 +302,19 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn) | |||
222 | struct iser_device *device = ib_conn->device; | 302 | struct iser_device *device = ib_conn->device; |
223 | 303 | ||
224 | if (!ib_conn->rx_descs) | 304 | if (!ib_conn->rx_descs) |
225 | return; | 305 | goto free_login_buf; |
226 | 306 | ||
227 | rx_desc = ib_conn->rx_descs; | 307 | rx_desc = ib_conn->rx_descs; |
228 | for (i = 0; i < ISER_QP_MAX_RECV_DTOS; i++, rx_desc++) | 308 | for (i = 0; i < ISER_QP_MAX_RECV_DTOS; i++, rx_desc++) |
229 | ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr, | 309 | ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr, |
230 | ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); | 310 | ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); |
231 | kfree(ib_conn->rx_descs); | 311 | kfree(ib_conn->rx_descs); |
312 | /* make sure we never redo any unmapping */ | ||
313 | ib_conn->rx_descs = NULL; | ||
314 | |||
315 | free_login_buf: | ||
316 | iser_free_login_buf(ib_conn); | ||
317 | iser_free_fmr_pool(ib_conn); | ||
232 | } | 318 | } |
233 | 319 | ||
234 | static int iser_post_rx_bufs(struct iscsi_conn *conn, struct iscsi_hdr *req) | 320 | static int iser_post_rx_bufs(struct iscsi_conn *conn, struct iscsi_hdr *req) |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 2c4941d0656b..b72e349790d2 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -178,56 +178,23 @@ static void iser_free_device_ib_res(struct iser_device *device) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | /** | 180 | /** |
181 | * iser_create_ib_conn_res - Creates FMR pool and Queue-Pair (QP) | 181 | * iser_create_fmr_pool - Creates FMR pool and page_vector |
182 | * | 182 | * |
183 | * returns 0 on success, -1 on failure | 183 | * returns 0 on success, or errno code on failure |
184 | */ | 184 | */ |
185 | static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | 185 | int iser_create_fmr_pool(struct iser_conn *ib_conn) |
186 | { | 186 | { |
187 | struct iser_device *device; | 187 | struct iser_device *device = ib_conn->device; |
188 | struct ib_qp_init_attr init_attr; | ||
189 | int req_err, resp_err, ret = -ENOMEM; | ||
190 | struct ib_fmr_pool_param params; | 188 | struct ib_fmr_pool_param params; |
191 | int index, min_index = 0; | 189 | int ret = -ENOMEM; |
192 | |||
193 | BUG_ON(ib_conn->device == NULL); | ||
194 | |||
195 | device = ib_conn->device; | ||
196 | |||
197 | ib_conn->login_buf = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN + | ||
198 | ISER_RX_LOGIN_SIZE, GFP_KERNEL); | ||
199 | if (!ib_conn->login_buf) | ||
200 | goto out_err; | ||
201 | |||
202 | ib_conn->login_req_buf = ib_conn->login_buf; | ||
203 | ib_conn->login_resp_buf = ib_conn->login_buf + ISCSI_DEF_MAX_RECV_SEG_LEN; | ||
204 | |||
205 | ib_conn->login_req_dma = ib_dma_map_single(ib_conn->device->ib_device, | ||
206 | (void *)ib_conn->login_req_buf, | ||
207 | ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE); | ||
208 | |||
209 | ib_conn->login_resp_dma = ib_dma_map_single(ib_conn->device->ib_device, | ||
210 | (void *)ib_conn->login_resp_buf, | ||
211 | ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE); | ||
212 | |||
213 | req_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_req_dma); | ||
214 | resp_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_resp_dma); | ||
215 | |||
216 | if (req_err || resp_err) { | ||
217 | if (req_err) | ||
218 | ib_conn->login_req_dma = 0; | ||
219 | if (resp_err) | ||
220 | ib_conn->login_resp_dma = 0; | ||
221 | goto out_err; | ||
222 | } | ||
223 | 190 | ||
224 | ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + | 191 | ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + |
225 | (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), | 192 | (sizeof(u64)*(ISCSI_ISER_SG_TABLESIZE+1)), |
226 | GFP_KERNEL); | 193 | GFP_KERNEL); |
227 | if (!ib_conn->page_vec) | 194 | if (!ib_conn->page_vec) |
228 | goto out_err; | 195 | return ret; |
229 | 196 | ||
230 | ib_conn->page_vec->pages = (u64 *) (ib_conn->page_vec + 1); | 197 | ib_conn->page_vec->pages = (u64 *)(ib_conn->page_vec + 1); |
231 | 198 | ||
232 | params.page_shift = SHIFT_4K; | 199 | params.page_shift = SHIFT_4K; |
233 | /* when the first/last SG element are not start/end * | 200 | /* when the first/last SG element are not start/end * |
@@ -244,15 +211,56 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
244 | IB_ACCESS_REMOTE_READ); | 211 | IB_ACCESS_REMOTE_READ); |
245 | 212 | ||
246 | ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, ¶ms); | 213 | ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, ¶ms); |
214 | if (!IS_ERR(ib_conn->fmr_pool)) | ||
215 | return 0; | ||
216 | |||
217 | /* no FMR => no need for page_vec */ | ||
218 | kfree(ib_conn->page_vec); | ||
219 | ib_conn->page_vec = NULL; | ||
220 | |||
247 | ret = PTR_ERR(ib_conn->fmr_pool); | 221 | ret = PTR_ERR(ib_conn->fmr_pool); |
248 | if (IS_ERR(ib_conn->fmr_pool) && ret != -ENOSYS) { | 222 | ib_conn->fmr_pool = NULL; |
249 | ib_conn->fmr_pool = NULL; | 223 | if (ret != -ENOSYS) { |
250 | goto out_err; | 224 | iser_err("FMR allocation failed, err %d\n", ret); |
251 | } else if (ret == -ENOSYS) { | 225 | return ret; |
252 | ib_conn->fmr_pool = NULL; | 226 | } else { |
253 | iser_warn("FMRs are not supported, using unaligned mode\n"); | 227 | iser_warn("FMRs are not supported, using unaligned mode\n"); |
254 | ret = 0; | 228 | return 0; |
255 | } | 229 | } |
230 | } | ||
231 | |||
232 | /** | ||
233 | * iser_free_fmr_pool - releases the FMR pool and page vec | ||
234 | */ | ||
235 | void iser_free_fmr_pool(struct iser_conn *ib_conn) | ||
236 | { | ||
237 | iser_info("freeing conn %p fmr pool %p\n", | ||
238 | ib_conn, ib_conn->fmr_pool); | ||
239 | |||
240 | if (ib_conn->fmr_pool != NULL) | ||
241 | ib_destroy_fmr_pool(ib_conn->fmr_pool); | ||
242 | |||
243 | ib_conn->fmr_pool = NULL; | ||
244 | |||
245 | kfree(ib_conn->page_vec); | ||
246 | ib_conn->page_vec = NULL; | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * iser_create_ib_conn_res - Queue-Pair (QP) | ||
251 | * | ||
252 | * returns 0 on success, -1 on failure | ||
253 | */ | ||
254 | static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | ||
255 | { | ||
256 | struct iser_device *device; | ||
257 | struct ib_qp_init_attr init_attr; | ||
258 | int ret = -ENOMEM; | ||
259 | int index, min_index = 0; | ||
260 | |||
261 | BUG_ON(ib_conn->device == NULL); | ||
262 | |||
263 | device = ib_conn->device; | ||
256 | 264 | ||
257 | memset(&init_attr, 0, sizeof init_attr); | 265 | memset(&init_attr, 0, sizeof init_attr); |
258 | 266 | ||
@@ -282,9 +290,9 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
282 | goto out_err; | 290 | goto out_err; |
283 | 291 | ||
284 | ib_conn->qp = ib_conn->cma_id->qp; | 292 | ib_conn->qp = ib_conn->cma_id->qp; |
285 | iser_info("setting conn %p cma_id %p: fmr_pool %p qp %p\n", | 293 | iser_info("setting conn %p cma_id %p qp %p\n", |
286 | ib_conn, ib_conn->cma_id, | 294 | ib_conn, ib_conn->cma_id, |
287 | ib_conn->fmr_pool, ib_conn->cma_id->qp); | 295 | ib_conn->cma_id->qp); |
288 | return ret; | 296 | return ret; |
289 | 297 | ||
290 | out_err: | 298 | out_err: |
@@ -293,7 +301,7 @@ out_err: | |||
293 | } | 301 | } |
294 | 302 | ||
295 | /** | 303 | /** |
296 | * releases the FMR pool and QP objects, returns 0 on success, | 304 | * releases the QP objects, returns 0 on success, |
297 | * -1 on failure | 305 | * -1 on failure |
298 | */ | 306 | */ |
299 | static int iser_free_ib_conn_res(struct iser_conn *ib_conn) | 307 | static int iser_free_ib_conn_res(struct iser_conn *ib_conn) |
@@ -301,13 +309,11 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn) | |||
301 | int cq_index; | 309 | int cq_index; |
302 | BUG_ON(ib_conn == NULL); | 310 | BUG_ON(ib_conn == NULL); |
303 | 311 | ||
304 | iser_info("freeing conn %p cma_id %p fmr pool %p qp %p\n", | 312 | iser_info("freeing conn %p cma_id %p qp %p\n", |
305 | ib_conn, ib_conn->cma_id, | 313 | ib_conn, ib_conn->cma_id, |
306 | ib_conn->fmr_pool, ib_conn->qp); | 314 | ib_conn->qp); |
307 | 315 | ||
308 | /* qp is created only once both addr & route are resolved */ | 316 | /* qp is created only once both addr & route are resolved */ |
309 | if (ib_conn->fmr_pool != NULL) | ||
310 | ib_destroy_fmr_pool(ib_conn->fmr_pool); | ||
311 | 317 | ||
312 | if (ib_conn->qp != NULL) { | 318 | if (ib_conn->qp != NULL) { |
313 | cq_index = ((struct iser_cq_desc *)ib_conn->qp->recv_cq->cq_context)->cq_index; | 319 | cq_index = ((struct iser_cq_desc *)ib_conn->qp->recv_cq->cq_context)->cq_index; |
@@ -316,21 +322,7 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn) | |||
316 | rdma_destroy_qp(ib_conn->cma_id); | 322 | rdma_destroy_qp(ib_conn->cma_id); |
317 | } | 323 | } |
318 | 324 | ||
319 | ib_conn->fmr_pool = NULL; | ||
320 | ib_conn->qp = NULL; | 325 | ib_conn->qp = NULL; |
321 | kfree(ib_conn->page_vec); | ||
322 | |||
323 | if (ib_conn->login_buf) { | ||
324 | if (ib_conn->login_req_dma) | ||
325 | ib_dma_unmap_single(ib_conn->device->ib_device, | ||
326 | ib_conn->login_req_dma, | ||
327 | ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE); | ||
328 | if (ib_conn->login_resp_dma) | ||
329 | ib_dma_unmap_single(ib_conn->device->ib_device, | ||
330 | ib_conn->login_resp_dma, | ||
331 | ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE); | ||
332 | kfree(ib_conn->login_buf); | ||
333 | } | ||
334 | 326 | ||
335 | return 0; | 327 | return 0; |
336 | } | 328 | } |