aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Tabachnik <alext@mellanox.com>2014-03-05 12:43:47 -0500
committerRoland Dreier <roland@purestorage.com>2014-03-18 01:33:58 -0400
commit6b5a8fb0d22f95fff1eefe1545aa2c7771cacc3f (patch)
tree0ac6a2d05f977960f3eeae0d06c9f044045b9fdd
parent7f73384752af3caf0756cf807b2f7fbac50982d1 (diff)
IB/iser: Initialize T10-PI resources
During connection establishment we also initialize T10-PI resources (QP, PI contexts) in order to support SCSI's protection operations. Signed-off-by: Alex Tabachnik <alext@mellanox.com> Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h21
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c77
2 files changed, 90 insertions, 8 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 011003f04253..99fc8b899648 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -134,6 +134,15 @@
134 ISER_MAX_TX_MISC_PDUS + \ 134 ISER_MAX_TX_MISC_PDUS + \
135 ISER_MAX_RX_MISC_PDUS) 135 ISER_MAX_RX_MISC_PDUS)
136 136
137/* Max registration work requests per command */
138#define ISER_MAX_REG_WR_PER_CMD 5
139
140/* For Signature we don't support DATAOUTs so no need to make room for them */
141#define ISER_QP_SIG_MAX_REQ_DTOS (ISER_DEF_XMIT_CMDS_MAX * \
142 (1 + ISER_MAX_REG_WR_PER_CMD) + \
143 ISER_MAX_TX_MISC_PDUS + \
144 ISER_MAX_RX_MISC_PDUS)
145
137#define ISER_VER 0x10 146#define ISER_VER 0x10
138#define ISER_WSV 0x08 147#define ISER_WSV 0x08
139#define ISER_RSV 0x04 148#define ISER_RSV 0x04
@@ -281,7 +290,16 @@ struct iser_device {
281}; 290};
282 291
283enum iser_reg_indicator { 292enum iser_reg_indicator {
284 ISER_DATA_KEY_VALID = 1 << 0, 293 ISER_DATA_KEY_VALID = 1 << 0,
294 ISER_PROT_KEY_VALID = 1 << 1,
295 ISER_SIG_KEY_VALID = 1 << 2,
296 ISER_FASTREG_PROTECTED = 1 << 3,
297};
298
299struct iser_pi_context {
300 struct ib_mr *prot_mr;
301 struct ib_fast_reg_page_list *prot_frpl;
302 struct ib_mr *sig_mr;
285}; 303};
286 304
287struct fast_reg_descriptor { 305struct fast_reg_descriptor {
@@ -289,6 +307,7 @@ struct fast_reg_descriptor {
289 /* For fast registration - FRWR */ 307 /* For fast registration - FRWR */
290 struct ib_mr *data_mr; 308 struct ib_mr *data_mr;
291 struct ib_fast_reg_page_list *data_frpl; 309 struct ib_fast_reg_page_list *data_frpl;
310 struct iser_pi_context *pi_ctx;
292 /* registration indicators container */ 311 /* registration indicators container */
293 u8 reg_indicators; 312 u8 reg_indicators;
294}; 313};
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 4c27f553df39..0404c71761f9 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -275,7 +275,7 @@ void iser_free_fmr_pool(struct iser_conn *ib_conn)
275 275
276static int 276static int
277iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd, 277iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd,
278 struct fast_reg_descriptor *desc) 278 bool pi_enable, struct fast_reg_descriptor *desc)
279{ 279{
280 int ret; 280 int ret;
281 281
@@ -294,12 +294,64 @@ iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd,
294 iser_err("Failed to allocate ib_fast_reg_mr err=%d\n", ret); 294 iser_err("Failed to allocate ib_fast_reg_mr err=%d\n", ret);
295 goto fast_reg_mr_failure; 295 goto fast_reg_mr_failure;
296 } 296 }
297 desc->reg_indicators |= ISER_DATA_KEY_VALID;
298
299 if (pi_enable) {
300 struct ib_mr_init_attr mr_init_attr = {0};
301 struct iser_pi_context *pi_ctx = NULL;
302
303 desc->pi_ctx = kzalloc(sizeof(*desc->pi_ctx), GFP_KERNEL);
304 if (!desc->pi_ctx) {
305 iser_err("Failed to allocate pi context\n");
306 ret = -ENOMEM;
307 goto pi_ctx_alloc_failure;
308 }
309 pi_ctx = desc->pi_ctx;
310
311 pi_ctx->prot_frpl = ib_alloc_fast_reg_page_list(ib_device,
312 ISCSI_ISER_SG_TABLESIZE);
313 if (IS_ERR(pi_ctx->prot_frpl)) {
314 ret = PTR_ERR(pi_ctx->prot_frpl);
315 iser_err("Failed to allocate prot frpl ret=%d\n",
316 ret);
317 goto prot_frpl_failure;
318 }
319
320 pi_ctx->prot_mr = ib_alloc_fast_reg_mr(pd,
321 ISCSI_ISER_SG_TABLESIZE + 1);
322 if (IS_ERR(pi_ctx->prot_mr)) {
323 ret = PTR_ERR(pi_ctx->prot_mr);
324 iser_err("Failed to allocate prot frmr ret=%d\n",
325 ret);
326 goto prot_mr_failure;
327 }
328 desc->reg_indicators |= ISER_PROT_KEY_VALID;
329
330 mr_init_attr.max_reg_descriptors = 2;
331 mr_init_attr.flags |= IB_MR_SIGNATURE_EN;
332 pi_ctx->sig_mr = ib_create_mr(pd, &mr_init_attr);
333 if (IS_ERR(pi_ctx->sig_mr)) {
334 ret = PTR_ERR(pi_ctx->sig_mr);
335 iser_err("Failed to allocate signature enabled mr err=%d\n",
336 ret);
337 goto sig_mr_failure;
338 }
339 desc->reg_indicators |= ISER_SIG_KEY_VALID;
340 }
341 desc->reg_indicators &= ~ISER_FASTREG_PROTECTED;
342
297 iser_info("Create fr_desc %p page_list %p\n", 343 iser_info("Create fr_desc %p page_list %p\n",
298 desc, desc->data_frpl->page_list); 344 desc, desc->data_frpl->page_list);
299 desc->reg_indicators |= ISER_DATA_KEY_VALID;
300 345
301 return 0; 346 return 0;
302 347sig_mr_failure:
348 ib_dereg_mr(desc->pi_ctx->prot_mr);
349prot_mr_failure:
350 ib_free_fast_reg_page_list(desc->pi_ctx->prot_frpl);
351prot_frpl_failure:
352 kfree(desc->pi_ctx);
353pi_ctx_alloc_failure:
354 ib_dereg_mr(desc->data_mr);
303fast_reg_mr_failure: 355fast_reg_mr_failure:
304 ib_free_fast_reg_page_list(desc->data_frpl); 356 ib_free_fast_reg_page_list(desc->data_frpl);
305 357
@@ -320,15 +372,15 @@ int iser_create_fastreg_pool(struct iser_conn *ib_conn, unsigned cmds_max)
320 INIT_LIST_HEAD(&ib_conn->fastreg.pool); 372 INIT_LIST_HEAD(&ib_conn->fastreg.pool);
321 ib_conn->fastreg.pool_size = 0; 373 ib_conn->fastreg.pool_size = 0;
322 for (i = 0; i < cmds_max; i++) { 374 for (i = 0; i < cmds_max; i++) {
323 desc = kmalloc(sizeof(*desc), GFP_KERNEL); 375 desc = kzalloc(sizeof(*desc), GFP_KERNEL);
324 if (!desc) { 376 if (!desc) {
325 iser_err("Failed to allocate a new fast_reg descriptor\n"); 377 iser_err("Failed to allocate a new fast_reg descriptor\n");
326 ret = -ENOMEM; 378 ret = -ENOMEM;
327 goto err; 379 goto err;
328 } 380 }
329 381
330 ret = iser_create_fastreg_desc(device->ib_device, 382 ret = iser_create_fastreg_desc(device->ib_device, device->pd,
331 device->pd, desc); 383 ib_conn->pi_support, desc);
332 if (ret) { 384 if (ret) {
333 iser_err("Failed to create fastreg descriptor err=%d\n", 385 iser_err("Failed to create fastreg descriptor err=%d\n",
334 ret); 386 ret);
@@ -364,6 +416,12 @@ void iser_free_fastreg_pool(struct iser_conn *ib_conn)
364 list_del(&desc->list); 416 list_del(&desc->list);
365 ib_free_fast_reg_page_list(desc->data_frpl); 417 ib_free_fast_reg_page_list(desc->data_frpl);
366 ib_dereg_mr(desc->data_mr); 418 ib_dereg_mr(desc->data_mr);
419 if (desc->pi_ctx) {
420 ib_free_fast_reg_page_list(desc->pi_ctx->prot_frpl);
421 ib_dereg_mr(desc->pi_ctx->prot_mr);
422 ib_destroy_mr(desc->pi_ctx->sig_mr);
423 kfree(desc->pi_ctx);
424 }
367 kfree(desc); 425 kfree(desc);
368 ++i; 426 ++i;
369 } 427 }
@@ -405,12 +463,17 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
405 init_attr.qp_context = (void *)ib_conn; 463 init_attr.qp_context = (void *)ib_conn;
406 init_attr.send_cq = device->tx_cq[min_index]; 464 init_attr.send_cq = device->tx_cq[min_index];
407 init_attr.recv_cq = device->rx_cq[min_index]; 465 init_attr.recv_cq = device->rx_cq[min_index];
408 init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
409 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; 466 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
410 init_attr.cap.max_send_sge = 2; 467 init_attr.cap.max_send_sge = 2;
411 init_attr.cap.max_recv_sge = 1; 468 init_attr.cap.max_recv_sge = 1;
412 init_attr.sq_sig_type = IB_SIGNAL_REQ_WR; 469 init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
413 init_attr.qp_type = IB_QPT_RC; 470 init_attr.qp_type = IB_QPT_RC;
471 if (ib_conn->pi_support) {
472 init_attr.cap.max_send_wr = ISER_QP_SIG_MAX_REQ_DTOS;
473 init_attr.create_flags |= IB_QP_CREATE_SIGNATURE_EN;
474 } else {
475 init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
476 }
414 477
415 ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr); 478 ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr);
416 if (ret) 479 if (ret)