Skip to content

Commit 59caaed

Browse files
jennyj-mellanoxdledford
authored andcommitted
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 <[email protected]> Signed-off-by: Sagi Grimberg <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent e26d2d2 commit 59caaed

File tree

4 files changed

+76
-3
lines changed

4 files changed

+76
-3
lines changed

drivers/infiniband/ulp/iser/iscsi_iser.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ struct iser_reg_ops {
369369
* cpus and device max completion vectors
370370
* @comps: Dinamically allocated array of completion handlers
371371
* @reg_ops: Registration ops
372+
* @remote_inv_sup: Remote invalidate is supported on this device
372373
*/
373374
struct iser_device {
374375
struct ib_device *ib_device;
@@ -380,6 +381,7 @@ struct iser_device {
380381
int comps_used;
381382
struct iser_comp *comps;
382383
const struct iser_reg_ops *reg_ops;
384+
bool remote_inv_sup;
383385
};
384386

385387
#define ISER_CHECK_GUARD 0xc0
@@ -525,6 +527,7 @@ struct iser_conn {
525527
u32 num_rx_descs;
526528
unsigned short scsi_sg_tablesize;
527529
unsigned int scsi_max_sectors;
530+
bool snd_w_inv;
528531
};
529532

530533
/**

drivers/infiniband/ulp/iser/iser_initiator.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,57 @@ void iser_login_rsp(struct ib_cq *cq, struct ib_wc *wc)
590590
ib_conn->post_recv_buf_count--;
591591
}
592592

593+
static inline void
594+
iser_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+
602+
static int
603+
iser_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+
593644
void iser_task_rsp(struct ib_cq *cq, struct ib_wc *wc)
594645
{
595646
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)
614665
iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
615666
hdr->itt, length);
616667

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+
617674
iscsi_iser_recv(iser_conn->iscsi_conn, hdr, desc->data, length);
618675

619676
ib_dma_sync_single_for_device(ib_conn->device->ib_device,

drivers/infiniband/ulp/iser/iser_memory.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ int iser_assign_reg_ops(struct iser_device *device)
8484
} else if (ib_dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
8585
iser_info("FastReg supported, using FastReg for registration\n");
8686
device->reg_ops = &fastreg_ops;
87+
device->remote_inv_sup = iser_always_reg;
8788
} else {
8889
iser_err("IB device does not support FMRs nor FastRegs, can't register memory\n");
8990
return -1;

drivers/infiniband/ulp/iser/iser_verbs.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,9 @@ static void iser_route_handler(struct rdma_cm_id *cma_id)
812812
conn_param.rnr_retry_count = 6;
813813

814814
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;
816818
conn_param.private_data = (void *)&req_hdr;
817819
conn_param.private_data_len = sizeof(struct iser_cm_hdr);
818820

@@ -827,7 +829,8 @@ static void iser_route_handler(struct rdma_cm_id *cma_id)
827829
iser_connect_error(cma_id);
828830
}
829831

830-
static void iser_connected_handler(struct rdma_cm_id *cma_id)
832+
static void iser_connected_handler(struct rdma_cm_id *cma_id,
833+
const void *private_data)
831834
{
832835
struct iser_conn *iser_conn;
833836
struct ib_qp_attr attr;
@@ -841,6 +844,15 @@ static void iser_connected_handler(struct rdma_cm_id *cma_id)
841844
(void)ib_query_qp(cma_id->qp, &attr, ~0, &init_attr);
842845
iser_info("remote qpn:%x my qpn:%x\n", attr.dest_qp_num, cma_id->qp->qp_num);
843846

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+
844856
iser_conn->state = ISER_CONN_UP;
845857
complete(&iser_conn->up_completion);
846858
}
@@ -892,7 +904,7 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve
892904
iser_route_handler(cma_id);
893905
break;
894906
case RDMA_CM_EVENT_ESTABLISHED:
895-
iser_connected_handler(cma_id);
907+
iser_connected_handler(cma_id, event->param.conn.private_data);
896908
break;
897909
case RDMA_CM_EVENT_ADDR_ERROR:
898910
case RDMA_CM_EVENT_ROUTE_ERROR:

0 commit comments

Comments
 (0)