aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenny Derzhavetz <jennyf@mellanox.com>2015-12-24 05:20:48 -0500
committerDoug Ledford <dledford@redhat.com>2015-12-26 19:27:10 -0500
commit59caaed7a72a0e3750dfb84636dae6b781559310 (patch)
tree69fce7d166f4552fbee364c1c6fe3879c4110070
parente26d2d21ff8e3e4f9768960a83e4b7be43f0aeed (diff)
IB/iser: Support the remote invalidation exception
Declare that we support remote invalidation in case we are: 1. using fastreg method 2. always registering memory Detect the invalidated rkey from the work completion info so we won't invalidate it locally. The spec mandates that we must not rely on the target remote invalidate our rkey so we must check it upon a receive (scsi response) completion. Signed-off-by: Jenny Derzhavetz <jennyf@mellanox.com> Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h3
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c57
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c1
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c18
4 files changed, 76 insertions, 3 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index d3b2a27ee928..95f0a64e076b 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -369,6 +369,7 @@ struct iser_reg_ops {
369 * cpus and device max completion vectors 369 * cpus and device max completion vectors
370 * @comps: Dinamically allocated array of completion handlers 370 * @comps: Dinamically allocated array of completion handlers
371 * @reg_ops: Registration ops 371 * @reg_ops: Registration ops
372 * @remote_inv_sup: Remote invalidate is supported on this device
372 */ 373 */
373struct iser_device { 374struct iser_device {
374 struct ib_device *ib_device; 375 struct ib_device *ib_device;
@@ -380,6 +381,7 @@ struct iser_device {
380 int comps_used; 381 int comps_used;
381 struct iser_comp *comps; 382 struct iser_comp *comps;
382 const struct iser_reg_ops *reg_ops; 383 const struct iser_reg_ops *reg_ops;
384 bool remote_inv_sup;
383}; 385};
384 386
385#define ISER_CHECK_GUARD 0xc0 387#define ISER_CHECK_GUARD 0xc0
@@ -525,6 +527,7 @@ struct iser_conn {
525 u32 num_rx_descs; 527 u32 num_rx_descs;
526 unsigned short scsi_sg_tablesize; 528 unsigned short scsi_sg_tablesize;
527 unsigned int scsi_max_sectors; 529 unsigned int scsi_max_sectors;
530 bool snd_w_inv;
528}; 531};
529 532
530/** 533/**
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 07ca5a94e60e..ed54b388e7ad 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -590,6 +590,57 @@ void iser_login_rsp(struct ib_cq *cq, struct ib_wc *wc)
590 ib_conn->post_recv_buf_count--; 590 ib_conn->post_recv_buf_count--;
591} 591}
592 592
593static inline void
594iser_inv_desc(struct iser_fr_desc *desc, u32 rkey)
595{
596 if (likely(rkey == desc->rsc.mr->rkey))
597 desc->rsc.mr_valid = 0;
598 else if (likely(rkey == desc->pi_ctx->sig_mr->rkey))
599 desc->pi_ctx->sig_mr_valid = 0;
600}
601
602static int
603iser_check_remote_inv(struct iser_conn *iser_conn,
604 struct ib_wc *wc,
605 struct iscsi_hdr *hdr)
606{
607 if (wc->wc_flags & IB_WC_WITH_INVALIDATE) {
608 struct iscsi_task *task;
609 u32 rkey = wc->ex.invalidate_rkey;
610
611 iser_dbg("conn %p: remote invalidation for rkey %#x\n",
612 iser_conn, rkey);
613
614 if (unlikely(!iser_conn->snd_w_inv)) {
615 iser_err("conn %p: unexepected remote invalidation, "
616 "terminating connection\n", iser_conn);
617 return -EPROTO;
618 }
619
620 task = iscsi_itt_to_ctask(iser_conn->iscsi_conn, hdr->itt);
621 if (likely(task)) {
622 struct iscsi_iser_task *iser_task = task->dd_data;
623 struct iser_fr_desc *desc;
624
625 if (iser_task->dir[ISER_DIR_IN]) {
626 desc = iser_task->rdma_reg[ISER_DIR_IN].mem_h;
627 iser_inv_desc(desc, rkey);
628 }
629
630 if (iser_task->dir[ISER_DIR_OUT]) {
631 desc = iser_task->rdma_reg[ISER_DIR_OUT].mem_h;
632 iser_inv_desc(desc, rkey);
633 }
634 } else {
635 iser_err("failed to get task for itt=%d\n", hdr->itt);
636 return -EINVAL;
637 }
638 }
639
640 return 0;
641}
642
643
593void iser_task_rsp(struct ib_cq *cq, struct ib_wc *wc) 644void iser_task_rsp(struct ib_cq *cq, struct ib_wc *wc)
594{ 645{
595 struct ib_conn *ib_conn = wc->qp->qp_context; 646 struct ib_conn *ib_conn = wc->qp->qp_context;
@@ -614,6 +665,12 @@ void iser_task_rsp(struct ib_cq *cq, struct ib_wc *wc)
614 iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode, 665 iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
615 hdr->itt, length); 666 hdr->itt, length);
616 667
668 if (iser_check_remote_inv(iser_conn, wc, hdr)) {
669 iscsi_conn_failure(iser_conn->iscsi_conn,
670 ISCSI_ERR_CONN_FAILED);
671 return;
672 }
673
617 iscsi_iser_recv(iser_conn->iscsi_conn, hdr, desc->data, length); 674 iscsi_iser_recv(iser_conn->iscsi_conn, hdr, desc->data, length);
618 675
619 ib_dma_sync_single_for_device(ib_conn->device->ib_device, 676 ib_dma_sync_single_for_device(ib_conn->device->ib_device,
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 722b8aa703c7..9a391cc5b9b3 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -84,6 +84,7 @@ int iser_assign_reg_ops(struct iser_device *device)
84 } else if (ib_dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) { 84 } else if (ib_dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
85 iser_info("FastReg supported, using FastReg for registration\n"); 85 iser_info("FastReg supported, using FastReg for registration\n");
86 device->reg_ops = &fastreg_ops; 86 device->reg_ops = &fastreg_ops;
87 device->remote_inv_sup = iser_always_reg;
87 } else { 88 } else {
88 iser_err("IB device does not support FMRs nor FastRegs, can't register memory\n"); 89 iser_err("IB device does not support FMRs nor FastRegs, can't register memory\n");
89 return -1; 90 return -1;
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 1752e40dd043..40c0f4978e2f 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -812,7 +812,9 @@ static void iser_route_handler(struct rdma_cm_id *cma_id)
812 conn_param.rnr_retry_count = 6; 812 conn_param.rnr_retry_count = 6;
813 813
814 memset(&req_hdr, 0, sizeof(req_hdr)); 814 memset(&req_hdr, 0, sizeof(req_hdr));
815 req_hdr.flags = (ISER_ZBVA_NOT_SUP | ISER_SEND_W_INV_NOT_SUP); 815 req_hdr.flags = ISER_ZBVA_NOT_SUP;
816 if (!device->remote_inv_sup)
817 req_hdr.flags |= ISER_SEND_W_INV_NOT_SUP;
816 conn_param.private_data = (void *)&req_hdr; 818 conn_param.private_data = (void *)&req_hdr;
817 conn_param.private_data_len = sizeof(struct iser_cm_hdr); 819 conn_param.private_data_len = sizeof(struct iser_cm_hdr);
818 820
@@ -827,7 +829,8 @@ failure:
827 iser_connect_error(cma_id); 829 iser_connect_error(cma_id);
828} 830}
829 831
830static void iser_connected_handler(struct rdma_cm_id *cma_id) 832static void iser_connected_handler(struct rdma_cm_id *cma_id,
833 const void *private_data)
831{ 834{
832 struct iser_conn *iser_conn; 835 struct iser_conn *iser_conn;
833 struct ib_qp_attr attr; 836 struct ib_qp_attr attr;
@@ -841,6 +844,15 @@ static void iser_connected_handler(struct rdma_cm_id *cma_id)
841 (void)ib_query_qp(cma_id->qp, &attr, ~0, &init_attr); 844 (void)ib_query_qp(cma_id->qp, &attr, ~0, &init_attr);
842 iser_info("remote qpn:%x my qpn:%x\n", attr.dest_qp_num, cma_id->qp->qp_num); 845 iser_info("remote qpn:%x my qpn:%x\n", attr.dest_qp_num, cma_id->qp->qp_num);
843 846
847 if (private_data) {
848 u8 flags = *(u8 *)private_data;
849
850 iser_conn->snd_w_inv = !(flags & ISER_SEND_W_INV_NOT_SUP);
851 }
852
853 iser_info("conn %p: negotiated %s invalidation\n",
854 iser_conn, iser_conn->snd_w_inv ? "remote" : "local");
855
844 iser_conn->state = ISER_CONN_UP; 856 iser_conn->state = ISER_CONN_UP;
845 complete(&iser_conn->up_completion); 857 complete(&iser_conn->up_completion);
846} 858}
@@ -892,7 +904,7 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve
892 iser_route_handler(cma_id); 904 iser_route_handler(cma_id);
893 break; 905 break;
894 case RDMA_CM_EVENT_ESTABLISHED: 906 case RDMA_CM_EVENT_ESTABLISHED:
895 iser_connected_handler(cma_id); 907 iser_connected_handler(cma_id, event->param.conn.private_data);
896 break; 908 break;
897 case RDMA_CM_EVENT_ADDR_ERROR: 909 case RDMA_CM_EVENT_ADDR_ERROR:
898 case RDMA_CM_EVENT_ROUTE_ERROR: 910 case RDMA_CM_EVENT_ROUTE_ERROR: