diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 0b33e0405..39ea7b5d1 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -193,7 +193,6 @@ static enum rdma_ch_state srpt_set_ch_state_to_disc(struct srpt_rdma_ch *ch) spin_lock_irqsave(&ch->spinlock, flags); prev = ch->state; switch (prev) { - case CH_CONNECTING: case CH_LIVE: ch->state = CH_DISCONNECTING; wake_up_process(ch->thread); @@ -214,7 +213,6 @@ static bool srpt_set_ch_state_to_draining(struct srpt_rdma_ch *ch) spin_lock_irqsave(&ch->spinlock, flags); switch (ch->state) { - case CH_CONNECTING: case CH_LIVE: case CH_DISCONNECTING: ch->state = CH_DRAINING; @@ -229,29 +227,6 @@ static bool srpt_set_ch_state_to_draining(struct srpt_rdma_ch *ch) return changed; } -/** - * srpt_test_and_set_ch_state() - Test and set the channel state. - * - * Returns true if and only if the channel state has been set to the new state. - */ -static bool srpt_test_and_set_ch_state(struct srpt_rdma_ch *ch, - enum rdma_ch_state old, - enum rdma_ch_state new) -{ - unsigned long flags; - bool changed = false; - - spin_lock_irqsave(&ch->spinlock, flags); - if (ch->state == old) { - ch->state = new; - wake_up_process(ch->thread); - changed = true; - } - spin_unlock_irqrestore(&ch->spinlock, flags); - - return changed; -} - /** * srpt_adjust_req_lim() - Adjust ch->req_lim and ch->req_lim_delta atomically. * @@ -372,8 +347,6 @@ static void srpt_srq_event(struct ib_event *event, void *ctx) static const char *get_ch_state_name(enum rdma_ch_state s) { switch (s) { - case CH_CONNECTING: - return "connecting"; case CH_LIVE: return "live"; case CH_DISCONNECTING: @@ -1861,7 +1834,7 @@ static void srpt_handle_new_iu(struct srpt_rdma_ch *ch, DMA_FROM_DEVICE); srp_cmd = recv_ioctx->ioctx.buf; - if (unlikely(!ch->rtu_received)) { + if (unlikely(!ch->rts)) { list_add_tail(&recv_ioctx->wait_list, &ch->cmd_wait_list); goto out; } @@ -1995,9 +1968,7 @@ static void srpt_process_send_completion(struct ib_cq *cq, } } - if (unlikely(opcode == SRPT_SEND && - ch->rtu_received && - !list_empty(&ch->cmd_wait_list))) + if (unlikely(ch->rts && !list_empty(&ch->cmd_wait_list))) srpt_process_wait_list(ch); } @@ -2111,23 +2082,6 @@ static int srpt_compl_thread(void *arg) /* See also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52925. */ barrier(); #endif -#endif - while (ch->state < CH_LIVE) { - srpt_process_completion(ch); - schedule(); - set_current_state(TASK_INTERRUPTIBLE); - } - set_current_state(TASK_RUNNING); - - srpt_process_wait_list(ch); - ch->rtu_received = true; - - set_current_state(TASK_INTERRUPTIBLE); -#if defined(__GNUC__) -#if (__GNUC__ * 100 + __GNUC_MINOR__) <= 406 - /* See also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52925. */ - barrier(); -#endif #endif while (!ch->last_wqe_received && ch->state == CH_LIVE) { srpt_process_completion(ch); @@ -2268,7 +2222,7 @@ static void srpt_destroy_ch_ib(struct srpt_rdma_ch *ch) * an appropriate time. * * Returns true if and only if the channel state has been modified from - * CH_CONNECTING or CH_LIVE into CH_DISCONNECTING. + * CH_LIVE into CH_DISCONNECTING. */ static bool __srpt_close_ch(struct srpt_rdma_ch *ch) __releases(&ch->srpt_tgt->spinlock) @@ -2288,7 +2242,6 @@ static bool __srpt_close_ch(struct srpt_rdma_ch *ch) prev_state = srpt_set_ch_state_to_disc(ch); switch (prev_state) { - case CH_CONNECTING: case CH_LIVE: was_live = true; break; @@ -2552,7 +2505,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, */ ch->rq_size = min(SRPT_RQ_SIZE, scst_get_max_lun_commands(NULL, 0)); spin_lock_init(&ch->spinlock); - ch->state = CH_CONNECTING; + ch->state = CH_LIVE; INIT_LIST_HEAD(&ch->cmd_wait_list); ch->max_rsp_size = max_t(uint32_t, srp_max_rsp_size, MIN_MAX_RSP_SIZE); ch->ioctx_ring = (struct srpt_send_ioctx **) @@ -2714,7 +2667,7 @@ restart: rep_param->initiator_depth = 4; spin_lock_irq(&srpt_tgt->spinlock); - if (ch->state == CH_CONNECTING) + if (ch->state == CH_LIVE) ret = ib_send_cm_rep(cm_id, rep_param); else ret = -ECONNABORTED; @@ -2792,16 +2745,15 @@ static void srpt_cm_rej_recv(struct ib_cm_id *cm_id) */ static void srpt_cm_rtu_recv(struct ib_cm_id *cm_id) { - struct srpt_rdma_ch *ch; + struct srpt_rdma_ch *ch = cm_id->context; int ret; - ch = cm_id->context; - BUG_ON(!ch); - - if (srpt_test_and_set_ch_state(ch, CH_CONNECTING, CH_LIVE)) { - ret = srpt_ch_qp_rts(ch, ch->qp); - if (ret) - srpt_close_ch(ch); + ret = srpt_ch_qp_rts(ch, ch->qp); + if (ret == 0) { + smp_mb(); + ch->rts = true; + } else { + srpt_close_ch(ch); } } diff --git a/srpt/src/ib_srpt.h b/srpt/src/ib_srpt.h index b8bec7c0f..8661a23cd 100644 --- a/srpt/src/ib_srpt.h +++ b/srpt/src/ib_srpt.h @@ -268,15 +268,13 @@ struct srpt_send_ioctx { /** * enum rdma_ch_state - SRP channel state. - * @CH_CONNECTING: QP is in RTR state; waiting for RTU. - * @CH_LIVE: QP is in RTS state. + * @CH_LIVE: QP is in RTR, RTU or RTS state. * @CH_DISCONNECTING: DREQ has been received and waiting for DREP or DREQ has * been sent and waiting for DREP or channel is being closed * for another reason. * @CH_DRAINING: QP is in ERR state. */ enum rdma_ch_state { - CH_CONNECTING, CH_LIVE, CH_DISCONNECTING, CH_DRAINING, @@ -309,8 +307,7 @@ enum rdma_ch_state { * @wc: Work completion array. * @state: channel state. See also enum rdma_ch_state. * @dreq_received: Whether an IB CM DREQ event has been received. - * @rtu_received: Whether an IB CM RTU event has been received and the - * requests received before that event have been processed. + * @rts: Whether the QP is in the RTS state. * @list: node for insertion in the srpt_device.rch_list list. * @cmd_wait_list: list of SCST commands that arrived before the RTU event. This * list contains struct srpt_ioctx elements and is protected @@ -342,7 +339,7 @@ struct srpt_rdma_ch { enum rdma_ch_state state; struct list_head list; struct list_head cmd_wait_list; - bool rtu_received; + bool rts; bool dreq_received; bool last_wqe_received;