···16571657 return i;16581658}16591659EXPORT_SYMBOL(ib_sg_to_pages);16601660+16611661+struct ib_drain_cqe {16621662+ struct ib_cqe cqe;16631663+ struct completion done;16641664+};16651665+16661666+static void ib_drain_qp_done(struct ib_cq *cq, struct ib_wc *wc)16671667+{16681668+ struct ib_drain_cqe *cqe = container_of(wc->wr_cqe, struct ib_drain_cqe,16691669+ cqe);16701670+16711671+ complete(&cqe->done);16721672+}16731673+16741674+/*16751675+ * Post a WR and block until its completion is reaped for the SQ.16761676+ */16771677+static void __ib_drain_sq(struct ib_qp *qp)16781678+{16791679+ struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR };16801680+ struct ib_drain_cqe sdrain;16811681+ struct ib_send_wr swr = {}, *bad_swr;16821682+ int ret;16831683+16841684+ if (qp->send_cq->poll_ctx == IB_POLL_DIRECT) {16851685+ WARN_ONCE(qp->send_cq->poll_ctx == IB_POLL_DIRECT,16861686+ "IB_POLL_DIRECT poll_ctx not supported for drain\n");16871687+ return;16881688+ }16891689+16901690+ swr.wr_cqe = &sdrain.cqe;16911691+ sdrain.cqe.done = ib_drain_qp_done;16921692+ init_completion(&sdrain.done);16931693+16941694+ ret = ib_modify_qp(qp, &attr, IB_QP_STATE);16951695+ if (ret) {16961696+ WARN_ONCE(ret, "failed to drain send queue: %d\n", ret);16971697+ return;16981698+ }16991699+17001700+ ret = ib_post_send(qp, &swr, &bad_swr);17011701+ if (ret) {17021702+ WARN_ONCE(ret, "failed to drain send queue: %d\n", ret);17031703+ return;17041704+ }17051705+17061706+ wait_for_completion(&sdrain.done);17071707+}17081708+17091709+/*17101710+ * Post a WR and block until its completion is reaped for the RQ.17111711+ */17121712+static void __ib_drain_rq(struct ib_qp *qp)17131713+{17141714+ struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR };17151715+ struct ib_drain_cqe rdrain;17161716+ struct ib_recv_wr rwr = {}, *bad_rwr;17171717+ int ret;17181718+17191719+ if (qp->recv_cq->poll_ctx == IB_POLL_DIRECT) {17201720+ WARN_ONCE(qp->recv_cq->poll_ctx == IB_POLL_DIRECT,17211721+ "IB_POLL_DIRECT poll_ctx not supported for drain\n");17221722+ return;17231723+ }17241724+17251725+ rwr.wr_cqe = &rdrain.cqe;17261726+ rdrain.cqe.done = ib_drain_qp_done;17271727+ init_completion(&rdrain.done);17281728+17291729+ ret = ib_modify_qp(qp, &attr, IB_QP_STATE);17301730+ if (ret) {17311731+ WARN_ONCE(ret, "failed to drain recv queue: %d\n", ret);17321732+ return;17331733+ }17341734+17351735+ ret = ib_post_recv(qp, &rwr, &bad_rwr);17361736+ if (ret) {17371737+ WARN_ONCE(ret, "failed to drain recv queue: %d\n", ret);17381738+ return;17391739+ }17401740+17411741+ wait_for_completion(&rdrain.done);17421742+}17431743+17441744+/**17451745+ * ib_drain_sq() - Block until all SQ CQEs have been consumed by the17461746+ * application.17471747+ * @qp: queue pair to drain17481748+ *17491749+ * If the device has a provider-specific drain function, then17501750+ * call that. Otherwise call the generic drain function17511751+ * __ib_drain_sq().17521752+ *17531753+ * The caller must:17541754+ *17551755+ * ensure there is room in the CQ and SQ for the drain work request and17561756+ * completion.17571757+ *17581758+ * allocate the CQ using ib_alloc_cq() and the CQ poll context cannot be17591759+ * IB_POLL_DIRECT.17601760+ *17611761+ * ensure that there are no other contexts that are posting WRs concurrently.17621762+ * Otherwise the drain is not guaranteed.17631763+ */17641764+void ib_drain_sq(struct ib_qp *qp)17651765+{17661766+ if (qp->device->drain_sq)17671767+ qp->device->drain_sq(qp);17681768+ else17691769+ __ib_drain_sq(qp);17701770+}17711771+EXPORT_SYMBOL(ib_drain_sq);17721772+17731773+/**17741774+ * ib_drain_rq() - Block until all RQ CQEs have been consumed by the17751775+ * application.17761776+ * @qp: queue pair to drain17771777+ *17781778+ * If the device has a provider-specific drain function, then17791779+ * call that. Otherwise call the generic drain function17801780+ * __ib_drain_rq().17811781+ *17821782+ * The caller must:17831783+ *17841784+ * ensure there is room in the CQ and RQ for the drain work request and17851785+ * completion.17861786+ *17871787+ * allocate the CQ using ib_alloc_cq() and the CQ poll context cannot be17881788+ * IB_POLL_DIRECT.17891789+ *17901790+ * ensure that there are no other contexts that are posting WRs concurrently.17911791+ * Otherwise the drain is not guaranteed.17921792+ */17931793+void ib_drain_rq(struct ib_qp *qp)17941794+{17951795+ if (qp->device->drain_rq)17961796+ qp->device->drain_rq(qp);17971797+ else17981798+ __ib_drain_rq(qp);17991799+}18001800+EXPORT_SYMBOL(ib_drain_rq);18011801+18021802+/**18031803+ * ib_drain_qp() - Block until all CQEs have been consumed by the18041804+ * application on both the RQ and SQ.18051805+ * @qp: queue pair to drain18061806+ *18071807+ * The caller must:18081808+ *18091809+ * ensure there is room in the CQ(s), SQ, and RQ for drain work requests18101810+ * and completions.18111811+ *18121812+ * allocate the CQs using ib_alloc_cq() and the CQ poll context cannot be18131813+ * IB_POLL_DIRECT.18141814+ *18151815+ * ensure that there are no other contexts that are posting WRs concurrently.18161816+ * Otherwise the drain is not guaranteed.18171817+ */18181818+void ib_drain_qp(struct ib_qp *qp)18191819+{18201820+ ib_drain_sq(qp);18211821+ ib_drain_rq(qp);18221822+}18231823+EXPORT_SYMBOL(ib_drain_qp);
+8-1
drivers/infiniband/hw/cxgb4/cq.c
···815815 }816816 }817817out:818818- if (wq)818818+ if (wq) {819819+ if (unlikely(qhp->attr.state != C4IW_QP_STATE_RTS)) {820820+ if (t4_sq_empty(wq))821821+ complete(&qhp->sq_drained);822822+ if (t4_rq_empty(wq))823823+ complete(&qhp->rq_drained);824824+ }819825 spin_unlock(&qhp->lock);826826+ }820827 return ret;821828}822829
+4
drivers/infiniband/hw/cxgb4/iw_cxgb4.h
···476476 wait_queue_head_t wait;477477 struct timer_list timer;478478 int sq_sig_all;479479+ struct completion rq_drained;480480+ struct completion sq_drained;479481};480482481483static inline struct c4iw_qp *to_c4iw_qp(struct ib_qp *ibqp)···10181016extern int db_fc_threshold;10191017extern int db_coalescing_threshold;10201018extern int use_dsgl;10191019+void c4iw_drain_rq(struct ib_qp *qp);10201020+void c4iw_drain_sq(struct ib_qp *qp);102110211022102210231023#endif
···663663int iser_conn_terminate(struct iser_conn *iser_conn)664664{665665 struct ib_conn *ib_conn = &iser_conn->ib_conn;666666- struct ib_send_wr *bad_wr;667666 int err = 0;668667669668 /* terminate the iser conn only if the conn state is UP */···687688 iser_err("Failed to disconnect, conn: 0x%p err %d\n",688689 iser_conn, err);689690690690- /* post an indication that all flush errors were consumed */691691- err = ib_post_send(ib_conn->qp, &ib_conn->last, &bad_wr);692692- if (err) {693693- iser_err("conn %p failed to post last wr", ib_conn);694694- return 1;695695- }696696-697697- wait_for_completion(&ib_conn->last_comp);691691+ /* block until all flush errors are consumed */692692+ ib_drain_sq(ib_conn->qp);698693 }699694700695 return 1;···947954948955 ib_conn->post_recv_buf_count = 0;949956 ib_conn->reg_cqe.done = iser_reg_comp;950950- ib_conn->last_cqe.done = iser_last_comp;951951- ib_conn->last.wr_cqe = &ib_conn->last_cqe;952952- ib_conn->last.opcode = IB_WR_SEND;953953- init_completion(&ib_conn->last_comp);954957}955958956959 /**
+4-36
drivers/infiniband/ulp/srp/ib_srp.c
···446446 dev->max_pages_per_mr);447447}448448449449-static void srp_drain_done(struct ib_cq *cq, struct ib_wc *wc)450450-{451451- struct srp_rdma_ch *ch = cq->cq_context;452452-453453- complete(&ch->done);454454-}455455-456456-static struct ib_cqe srp_drain_cqe = {457457- .done = srp_drain_done,458458-};459459-460449/**461450 * srp_destroy_qp() - destroy an RDMA queue pair462451 * @ch: SRP RDMA channel.463452 *464464- * Change a queue pair into the error state and wait until all receive465465- * completions have been processed before destroying it. This avoids that466466- * the receive completion handler can access the queue pair while it is453453+ * Drain the qp before destroying it. This avoids that the receive454454+ * completion handler can access the queue pair while it is467455 * being destroyed.468456 */469457static void srp_destroy_qp(struct srp_rdma_ch *ch)470458{471471- static struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR };472472- static struct ib_recv_wr wr = { 0 };473473- struct ib_recv_wr *bad_wr;474474- int ret;475475-476476- wr.wr_cqe = &srp_drain_cqe;477477- /* Destroying a QP and reusing ch->done is only safe if not connected */478478- WARN_ON_ONCE(ch->connected);479479-480480- ret = ib_modify_qp(ch->qp, &attr, IB_QP_STATE);481481- WARN_ONCE(ret, "ib_cm_init_qp_attr() returned %d\n", ret);482482- if (ret)483483- goto out;484484-485485- init_completion(&ch->done);486486- ret = ib_post_recv(ch->qp, &wr, &bad_wr);487487- WARN_ONCE(ret, "ib_post_recv() returned %d\n", ret);488488- if (ret == 0)489489- wait_for_completion(&ch->done);490490-491491-out:459459+ ib_drain_rq(ch->qp);492460 ib_destroy_qp(ch->qp);493461}494462···476508 if (!init_attr)477509 return -ENOMEM;478510479479- /* queue_size + 1 for ib_drain_qp */511511+ /* queue_size + 1 for ib_drain_rq() */480512 recv_cq = ib_alloc_cq(dev->dev, ch, target->queue_size + 1,481513 ch->comp_vector, IB_POLL_SOFTIRQ);482514 if (IS_ERR(recv_cq)) {
+328-606
drivers/infiniband/ulp/srpt/ib_srpt.c
···9191 " instead of using the node_guid of the first HCA.");92929393static struct ib_client srpt_client;9494-static void srpt_release_channel(struct srpt_rdma_ch *ch);9494+static void srpt_release_cmd(struct se_cmd *se_cmd);9595+static void srpt_free_ch(struct kref *kref);9596static int srpt_queue_status(struct se_cmd *cmd);9697static void srpt_recv_done(struct ib_cq *cq, struct ib_wc *wc);9798static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc);9999+static void srpt_process_wait_list(struct srpt_rdma_ch *ch);981009999-/**100100- * opposite_dma_dir() - Swap DMA_TO_DEVICE and DMA_FROM_DEVICE.101101+/*102102+ * The only allowed channel state changes are those that change the channel103103+ * state into a state with a higher numerical value. Hence the new > prev test.101104 */102102-static inline103103-enum dma_data_direction opposite_dma_dir(enum dma_data_direction dir)104104-{105105- switch (dir) {106106- case DMA_TO_DEVICE: return DMA_FROM_DEVICE;107107- case DMA_FROM_DEVICE: return DMA_TO_DEVICE;108108- default: return dir;109109- }110110-}111111-112112-/**113113- * srpt_sdev_name() - Return the name associated with the HCA.114114- *115115- * Examples are ib0, ib1, ...116116- */117117-static inline const char *srpt_sdev_name(struct srpt_device *sdev)118118-{119119- return sdev->device->name;120120-}121121-122122-static enum rdma_ch_state srpt_get_ch_state(struct srpt_rdma_ch *ch)123123-{124124- unsigned long flags;125125- enum rdma_ch_state state;126126-127127- spin_lock_irqsave(&ch->spinlock, flags);128128- state = ch->state;129129- spin_unlock_irqrestore(&ch->spinlock, flags);130130- return state;131131-}132132-133133-static enum rdma_ch_state134134-srpt_set_ch_state(struct srpt_rdma_ch *ch, enum rdma_ch_state new_state)105105+static bool srpt_set_ch_state(struct srpt_rdma_ch *ch, enum rdma_ch_state new)135106{136107 unsigned long flags;137108 enum rdma_ch_state prev;109109+ bool changed = false;138110139111 spin_lock_irqsave(&ch->spinlock, flags);140112 prev = ch->state;141141- ch->state = new_state;142142- spin_unlock_irqrestore(&ch->spinlock, flags);143143- return prev;144144-}145145-146146-/**147147- * srpt_test_and_set_ch_state() - Test and set the channel state.148148- *149149- * Returns true if and only if the channel state has been set to the new state.150150- */151151-static bool152152-srpt_test_and_set_ch_state(struct srpt_rdma_ch *ch, enum rdma_ch_state old,153153- enum rdma_ch_state new)154154-{155155- unsigned long flags;156156- enum rdma_ch_state prev;157157-158158- spin_lock_irqsave(&ch->spinlock, flags);159159- prev = ch->state;160160- if (prev == old)113113+ if (new > prev) {161114 ch->state = new;115115+ changed = true;116116+ }162117 spin_unlock_irqrestore(&ch->spinlock, flags);163163- return prev == old;118118+119119+ return changed;164120}165121166122/**···138182 return;139183140184 pr_debug("ASYNC event= %d on device= %s\n", event->event,141141- srpt_sdev_name(sdev));185185+ sdev->device->name);142186143187 switch (event->event) {144188 case IB_EVENT_PORT_ERR:···176220 pr_info("SRQ event %d\n", event->event);177221}178222223223+static const char *get_ch_state_name(enum rdma_ch_state s)224224+{225225+ switch (s) {226226+ case CH_CONNECTING:227227+ return "connecting";228228+ case CH_LIVE:229229+ return "live";230230+ case CH_DISCONNECTING:231231+ return "disconnecting";232232+ case CH_DRAINING:233233+ return "draining";234234+ case CH_DISCONNECTED:235235+ return "disconnected";236236+ }237237+ return "???";238238+}239239+179240/**180241 * srpt_qp_event() - QP event callback function.181242 */182243static void srpt_qp_event(struct ib_event *event, struct srpt_rdma_ch *ch)183244{184245 pr_debug("QP event %d on cm_id=%p sess_name=%s state=%d\n",185185- event->event, ch->cm_id, ch->sess_name, srpt_get_ch_state(ch));246246+ event->event, ch->cm_id, ch->sess_name, ch->state);186247187248 switch (event->event) {188249 case IB_EVENT_COMM_EST:189250 ib_cm_notify(ch->cm_id, event->event);190251 break;191252 case IB_EVENT_QP_LAST_WQE_REACHED:192192- if (srpt_test_and_set_ch_state(ch, CH_DRAINING,193193- CH_RELEASING))194194- srpt_release_channel(ch);195195- else196196- pr_debug("%s: state %d - ignored LAST_WQE.\n",197197- ch->sess_name, srpt_get_ch_state(ch));253253+ pr_debug("%s-%d, state %s: received Last WQE event.\n",254254+ ch->sess_name, ch->qp->qp_num,255255+ get_ch_state_name(ch->state));198256 break;199257 default:200258 pr_err("received unrecognized IB QP event %d\n", event->event);···251281 struct ib_class_port_info *cif;252282253283 cif = (struct ib_class_port_info *)mad->data;254254- memset(cif, 0, sizeof *cif);284284+ memset(cif, 0, sizeof(*cif));255285 cif->base_version = 1;256286 cif->class_version = 1;257287 cif->resp_time_value = 20;···310340 return;311341 }312342313313- memset(iocp, 0, sizeof *iocp);343343+ memset(iocp, 0, sizeof(*iocp));314344 strcpy(iocp->id_string, SRPT_ID_STRING);315345 iocp->guid = cpu_to_be64(srpt_service_guid);316346 iocp->vendor_id = cpu_to_be32(sdev->device->attrs.vendor_id);···360390 }361391362392 svc_entries = (struct ib_dm_svc_entries *)mad->data;363363- memset(svc_entries, 0, sizeof *svc_entries);393393+ memset(svc_entries, 0, sizeof(*svc_entries));364394 svc_entries->service_entries[0].id = cpu_to_be64(ioc_guid);365395 snprintf(svc_entries->service_entries[0].name,366396 sizeof(svc_entries->service_entries[0].name),···454484 rsp->ah = ah;455485456486 dm_mad = rsp->mad;457457- memcpy(dm_mad, mad_wc->recv_buf.mad, sizeof *dm_mad);487487+ memcpy(dm_mad, mad_wc->recv_buf.mad, sizeof(*dm_mad));458488 dm_mad->mad_hdr.method = IB_MGMT_METHOD_GET_RESP;459489 dm_mad->mad_hdr.status = 0;460490···502532 struct ib_port_attr port_attr;503533 int ret;504534505505- memset(&port_modify, 0, sizeof port_modify);535535+ memset(&port_modify, 0, sizeof(port_modify));506536 port_modify.set_port_cap_mask = IB_PORT_DEVICE_MGMT_SUP;507537 port_modify.clr_port_cap_mask = 0;508538···523553 goto err_query_port;524554525555 if (!sport->mad_agent) {526526- memset(®_req, 0, sizeof reg_req);556556+ memset(®_req, 0, sizeof(reg_req));527557 reg_req.mgmt_class = IB_MGMT_CLASS_DEVICE_MGMT;528558 reg_req.mgmt_class_version = IB_MGMT_BASE_VERSION;529559 set_bit(IB_MGMT_METHOD_GET, reg_req.method_mask);···811841}812842813843/**844844+ * srpt_zerolength_write() - Perform a zero-length RDMA write.845845+ *846846+ * A quote from the InfiniBand specification: C9-88: For an HCA responder847847+ * using Reliable Connection service, for each zero-length RDMA READ or WRITE848848+ * request, the R_Key shall not be validated, even if the request includes849849+ * Immediate data.850850+ */851851+static int srpt_zerolength_write(struct srpt_rdma_ch *ch)852852+{853853+ struct ib_send_wr wr, *bad_wr;854854+855855+ memset(&wr, 0, sizeof(wr));856856+ wr.opcode = IB_WR_RDMA_WRITE;857857+ wr.wr_cqe = &ch->zw_cqe;858858+ wr.send_flags = IB_SEND_SIGNALED;859859+ return ib_post_send(ch->qp, &wr, &bad_wr);860860+}861861+862862+static void srpt_zerolength_write_done(struct ib_cq *cq, struct ib_wc *wc)863863+{864864+ struct srpt_rdma_ch *ch = cq->cq_context;865865+866866+ if (wc->status == IB_WC_SUCCESS) {867867+ srpt_process_wait_list(ch);868868+ } else {869869+ if (srpt_set_ch_state(ch, CH_DISCONNECTED))870870+ schedule_work(&ch->release_work);871871+ else872872+ WARN_ONCE("%s-%d\n", ch->sess_name, ch->qp->qp_num);873873+ }874874+}875875+876876+/**814877 * srpt_get_desc_tbl() - Parse the data descriptors of an SRP_CMD request.815878 * @ioctx: Pointer to the I/O context associated with the request.816879 * @srp_cmd: Pointer to the SRP_CMD request data.···906903907904 db = (struct srp_direct_buf *)(srp_cmd->add_data908905 + add_cdb_offset);909909- memcpy(ioctx->rbufs, db, sizeof *db);906906+ memcpy(ioctx->rbufs, db, sizeof(*db));910907 *data_len = be32_to_cpu(db->len);911908 } else if (((srp_cmd->buf_fmt & 0xf) == SRP_DATA_DESC_INDIRECT) ||912909 ((srp_cmd->buf_fmt >> 4) == SRP_DATA_DESC_INDIRECT)) {913910 idb = (struct srp_indirect_buf *)(srp_cmd->add_data914911 + add_cdb_offset);915912916916- ioctx->n_rbuf = be32_to_cpu(idb->table_desc.len) / sizeof *db;913913+ ioctx->n_rbuf = be32_to_cpu(idb->table_desc.len) / sizeof(*db);917914918915 if (ioctx->n_rbuf >919916 (srp_cmd->data_out_desc_cnt + srp_cmd->data_in_desc_cnt)) {···932929 ioctx->rbufs = &ioctx->single_rbuf;933930 else {934931 ioctx->rbufs =935935- kmalloc(ioctx->n_rbuf * sizeof *db, GFP_ATOMIC);932932+ kmalloc(ioctx->n_rbuf * sizeof(*db), GFP_ATOMIC);936933 if (!ioctx->rbufs) {937934 ioctx->n_rbuf = 0;938935 ret = -ENOMEM;···941938 }942939943940 db = idb->desc_list;944944- memcpy(ioctx->rbufs, db, ioctx->n_rbuf * sizeof *db);941941+ memcpy(ioctx->rbufs, db, ioctx->n_rbuf * sizeof(*db));945942 *data_len = be32_to_cpu(idb->len);946943 }947944out:···959956 struct ib_qp_attr *attr;960957 int ret;961958962962- attr = kzalloc(sizeof *attr, GFP_KERNEL);959959+ attr = kzalloc(sizeof(*attr), GFP_KERNEL);963960 if (!attr)964961 return -ENOMEM;965962···10731070 dir = ioctx->cmd.data_direction;10741071 BUG_ON(dir == DMA_NONE);10751072 ib_dma_unmap_sg(ch->sport->sdev->device, sg, ioctx->sg_cnt,10761076- opposite_dma_dir(dir));10731073+ target_reverse_dma_direction(&ioctx->cmd));10771074 ioctx->mapped_sg_count = 0;10781075 }10791076}···11101107 ioctx->sg_cnt = sg_cnt = cmd->t_data_nents;1111110811121109 count = ib_dma_map_sg(ch->sport->sdev->device, sg, sg_cnt,11131113- opposite_dma_dir(dir));11101110+ target_reverse_dma_direction(cmd));11141111 if (unlikely(!count))11151112 return -EAGAIN;11161113···1316131313171314 /*13181315 * If the command is in a state where the target core is waiting for13191319- * the ib_srpt driver, change the state to the next state. Changing13201320- * the state of the command from SRPT_STATE_NEED_DATA to13211321- * SRPT_STATE_DATA_IN ensures that srpt_xmit_response() will call this13221322- * function a second time.13161316+ * the ib_srpt driver, change the state to the next state.13231317 */1324131813251319 spin_lock_irqsave(&ioctx->spinlock, flags);···13251325 case SRPT_STATE_NEED_DATA:13261326 ioctx->state = SRPT_STATE_DATA_IN;13271327 break;13281328- case SRPT_STATE_DATA_IN:13291328 case SRPT_STATE_CMD_RSP_SENT:13301329 case SRPT_STATE_MGMT_RSP_SENT:13311330 ioctx->state = SRPT_STATE_DONE;13321331 break;13331332 default:13331333+ WARN_ONCE(true, "%s: unexpected I/O context state %d\n",13341334+ __func__, state);13341335 break;13351336 }13361337 spin_unlock_irqrestore(&ioctx->spinlock, flags);13371337-13381338- if (state == SRPT_STATE_DONE) {13391339- struct srpt_rdma_ch *ch = ioctx->ch;13401340-13411341- BUG_ON(ch->sess == NULL);13421342-13431343- target_put_sess_cmd(&ioctx->cmd);13441344- goto out;13451345- }1346133813471339 pr_debug("Aborting cmd with state %d and tag %lld\n", state,13481340 ioctx->cmd.tag);···13431351 case SRPT_STATE_NEW:13441352 case SRPT_STATE_DATA_IN:13451353 case SRPT_STATE_MGMT:13541354+ case SRPT_STATE_DONE:13461355 /*13471356 * Do nothing - defer abort processing until13481357 * srpt_queue_response() is invoked.13491358 */13501350- WARN_ON(!transport_check_aborted_status(&ioctx->cmd, false));13511359 break;13521360 case SRPT_STATE_NEED_DATA:13531353- /* DMA_TO_DEVICE (write) - RDMA read error. */13541354-13551355- /* XXX(hch): this is a horrible layering violation.. */13561356- spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);13571357- ioctx->cmd.transport_state &= ~CMD_T_ACTIVE;13581358- spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);13611361+ pr_debug("tag %#llx: RDMA read error\n", ioctx->cmd.tag);13621362+ transport_generic_request_failure(&ioctx->cmd,13631363+ TCM_CHECK_CONDITION_ABORT_CMD);13591364 break;13601365 case SRPT_STATE_CMD_RSP_SENT:13611366 /*···13601371 * not been received in time.13611372 */13621373 srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx);13631363- target_put_sess_cmd(&ioctx->cmd);13741374+ transport_generic_free_cmd(&ioctx->cmd, 0);13641375 break;13651376 case SRPT_STATE_MGMT_RSP_SENT:13661366- srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);13671367- target_put_sess_cmd(&ioctx->cmd);13771377+ transport_generic_free_cmd(&ioctx->cmd, 0);13681378 break;13691379 default:13701380 WARN(1, "Unexpected command state (%d)", state);13711381 break;13721382 }1373138313741374-out:13751384 return state;13761385}13771386···14091422 container_of(wc->wr_cqe, struct srpt_send_ioctx, rdma_cqe);1410142314111424 if (unlikely(wc->status != IB_WC_SUCCESS)) {14251425+ /*14261426+ * Note: if an RDMA write error completion is received that14271427+ * means that a SEND also has been posted. Defer further14281428+ * processing of the associated command until the send error14291429+ * completion has been received.14301430+ */14121431 pr_info("RDMA_WRITE for ioctx 0x%p failed with status %d\n",14131432 ioctx, wc->status);14141414- srpt_abort_cmd(ioctx);14151433 }14161434}14171435···14561464 sense_data_len = ioctx->cmd.scsi_sense_length;14571465 WARN_ON(sense_data_len > sizeof(ioctx->sense_data));1458146614591459- memset(srp_rsp, 0, sizeof *srp_rsp);14671467+ memset(srp_rsp, 0, sizeof(*srp_rsp));14601468 srp_rsp->opcode = SRP_RSP;14611469 srp_rsp->req_lim_delta =14621470 cpu_to_be32(1 + atomic_xchg(&ch->req_lim_delta, 0));···1506151415071515 srp_rsp = ioctx->ioctx.buf;15081516 BUG_ON(!srp_rsp);15091509- memset(srp_rsp, 0, sizeof *srp_rsp);15171517+ memset(srp_rsp, 0, sizeof(*srp_rsp));1510151815111519 srp_rsp->opcode = SRP_RSP;15121520 srp_rsp->req_lim_delta =···15201528 return resp_len;15211529}1522153015231523-#define NO_SUCH_LUN ((uint64_t)-1LL)15241524-15251525-/*15261526- * SCSI LUN addressing method. See also SAM-2 and the section about15271527- * eight byte LUNs.15281528- */15291529-enum scsi_lun_addr_method {15301530- SCSI_LUN_ADDR_METHOD_PERIPHERAL = 0,15311531- SCSI_LUN_ADDR_METHOD_FLAT = 1,15321532- SCSI_LUN_ADDR_METHOD_LUN = 2,15331533- SCSI_LUN_ADDR_METHOD_EXTENDED_LUN = 3,15341534-};15351535-15361536-/*15371537- * srpt_unpack_lun() - Convert from network LUN to linear LUN.15381538- *15391539- * Convert an 2-byte, 4-byte, 6-byte or 8-byte LUN structure in network byte15401540- * order (big endian) to a linear LUN. Supports three LUN addressing methods:15411541- * peripheral, flat and logical unit. See also SAM-2, section 4.9.4 (page 40).15421542- */15431543-static uint64_t srpt_unpack_lun(const uint8_t *lun, int len)15441544-{15451545- uint64_t res = NO_SUCH_LUN;15461546- int addressing_method;15471547-15481548- if (unlikely(len < 2)) {15491549- pr_err("Illegal LUN length %d, expected 2 bytes or more\n",15501550- len);15511551- goto out;15521552- }15531553-15541554- switch (len) {15551555- case 8:15561556- if ((*((__be64 *)lun) &15571557- cpu_to_be64(0x0000FFFFFFFFFFFFLL)) != 0)15581558- goto out_err;15591559- break;15601560- case 4:15611561- if (*((__be16 *)&lun[2]) != 0)15621562- goto out_err;15631563- break;15641564- case 6:15651565- if (*((__be32 *)&lun[2]) != 0)15661566- goto out_err;15671567- break;15681568- case 2:15691569- break;15701570- default:15711571- goto out_err;15721572- }15731573-15741574- addressing_method = (*lun) >> 6; /* highest two bits of byte 0 */15751575- switch (addressing_method) {15761576- case SCSI_LUN_ADDR_METHOD_PERIPHERAL:15771577- case SCSI_LUN_ADDR_METHOD_FLAT:15781578- case SCSI_LUN_ADDR_METHOD_LUN:15791579- res = *(lun + 1) | (((*lun) & 0x3f) << 8);15801580- break;15811581-15821582- case SCSI_LUN_ADDR_METHOD_EXTENDED_LUN:15831583- default:15841584- pr_err("Unimplemented LUN addressing method %u\n",15851585- addressing_method);15861586- break;15871587- }15881588-15891589-out:15901590- return res;15911591-15921592-out_err:15931593- pr_err("Support for multi-level LUNs has not yet been implemented\n");15941594- goto out;15951595-}15961596-15971531static int srpt_check_stop_free(struct se_cmd *cmd)15981532{15991533 struct srpt_send_ioctx *ioctx = container_of(cmd,···15311613/**15321614 * srpt_handle_cmd() - Process SRP_CMD.15331615 */15341534-static int srpt_handle_cmd(struct srpt_rdma_ch *ch,15351535- struct srpt_recv_ioctx *recv_ioctx,15361536- struct srpt_send_ioctx *send_ioctx)16161616+static void srpt_handle_cmd(struct srpt_rdma_ch *ch,16171617+ struct srpt_recv_ioctx *recv_ioctx,16181618+ struct srpt_send_ioctx *send_ioctx)15371619{15381620 struct se_cmd *cmd;15391621 struct srp_cmd *srp_cmd;15401540- uint64_t unpacked_lun;15411622 u64 data_len;15421623 enum dma_data_direction dir;15431543- sense_reason_t ret;15441624 int rc;1545162515461626 BUG_ON(!send_ioctx);···15661650 if (srpt_get_desc_tbl(send_ioctx, srp_cmd, &dir, &data_len)) {15671651 pr_err("0x%llx: parsing SRP descriptor table failed.\n",15681652 srp_cmd->tag);15691569- ret = TCM_INVALID_CDB_FIELD;15701570- goto send_sense;16531653+ goto release_ioctx;15711654 }1572165515731573- unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun,15741574- sizeof(srp_cmd->lun));15751656 rc = target_submit_cmd(cmd, ch->sess, srp_cmd->cdb,15761576- &send_ioctx->sense_data[0], unpacked_lun, data_len,15771577- TCM_SIMPLE_TAG, dir, TARGET_SCF_ACK_KREF);16571657+ &send_ioctx->sense_data[0],16581658+ scsilun_to_int(&srp_cmd->lun), data_len,16591659+ TCM_SIMPLE_TAG, dir, TARGET_SCF_ACK_KREF);15781660 if (rc != 0) {15791579- ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;15801580- goto send_sense;16611661+ pr_debug("target_submit_cmd() returned %d for tag %#llx\n", rc,16621662+ srp_cmd->tag);16631663+ goto release_ioctx;15811664 }15821582- return 0;16651665+ return;1583166615841584-send_sense:15851585- transport_send_check_condition_and_sense(cmd, ret, 0);15861586- return -1;15871587-}15881588-15891589-/**15901590- * srpt_rx_mgmt_fn_tag() - Process a task management function by tag.15911591- * @ch: RDMA channel of the task management request.15921592- * @fn: Task management function to perform.15931593- * @req_tag: Tag of the SRP task management request.15941594- * @mgmt_ioctx: I/O context of the task management request.15951595- *15961596- * Returns zero if the target core will process the task management15971597- * request asynchronously.15981598- *15991599- * Note: It is assumed that the initiator serializes tag-based task management16001600- * requests.16011601- */16021602-static int srpt_rx_mgmt_fn_tag(struct srpt_send_ioctx *ioctx, u64 tag)16031603-{16041604- struct srpt_device *sdev;16051605- struct srpt_rdma_ch *ch;16061606- struct srpt_send_ioctx *target;16071607- int ret, i;16081608-16091609- ret = -EINVAL;16101610- ch = ioctx->ch;16111611- BUG_ON(!ch);16121612- BUG_ON(!ch->sport);16131613- sdev = ch->sport->sdev;16141614- BUG_ON(!sdev);16151615- spin_lock_irq(&sdev->spinlock);16161616- for (i = 0; i < ch->rq_size; ++i) {16171617- target = ch->ioctx_ring[i];16181618- if (target->cmd.se_lun == ioctx->cmd.se_lun &&16191619- target->cmd.tag == tag &&16201620- srpt_get_cmd_state(target) != SRPT_STATE_DONE) {16211621- ret = 0;16221622- /* now let the target core abort &target->cmd; */16231623- break;16241624- }16251625- }16261626- spin_unlock_irq(&sdev->spinlock);16271627- return ret;16671667+release_ioctx:16681668+ send_ioctx->state = SRPT_STATE_DONE;16691669+ srpt_release_cmd(cmd);16281670}1629167116301672static int srp_tmr_to_tcm(int fn)···16181744 struct srp_tsk_mgmt *srp_tsk;16191745 struct se_cmd *cmd;16201746 struct se_session *sess = ch->sess;16211621- uint64_t unpacked_lun;16221622- uint32_t tag = 0;16231747 int tcm_tmr;16241748 int rc;16251749···16331761 srpt_set_cmd_state(send_ioctx, SRPT_STATE_MGMT);16341762 send_ioctx->cmd.tag = srp_tsk->tag;16351763 tcm_tmr = srp_tmr_to_tcm(srp_tsk->tsk_mgmt_func);16361636- if (tcm_tmr < 0) {16371637- send_ioctx->cmd.se_tmr_req->response =16381638- TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;16391639- goto fail;16401640- }16411641- unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_tsk->lun,16421642- sizeof(srp_tsk->lun));16431643-16441644- if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK) {16451645- rc = srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);16461646- if (rc < 0) {16471647- send_ioctx->cmd.se_tmr_req->response =16481648- TMR_TASK_DOES_NOT_EXIST;16491649- goto fail;16501650- }16511651- tag = srp_tsk->task_tag;16521652- }16531653- rc = target_submit_tmr(&send_ioctx->cmd, sess, NULL, unpacked_lun,16541654- srp_tsk, tcm_tmr, GFP_KERNEL, tag,16551655- TARGET_SCF_ACK_KREF);17641764+ rc = target_submit_tmr(&send_ioctx->cmd, sess, NULL,17651765+ scsilun_to_int(&srp_tsk->lun), srp_tsk, tcm_tmr,17661766+ GFP_KERNEL, srp_tsk->task_tag,17671767+ TARGET_SCF_ACK_KREF);16561768 if (rc != 0) {16571769 send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;16581770 goto fail;···16561800 struct srpt_send_ioctx *send_ioctx)16571801{16581802 struct srp_cmd *srp_cmd;16591659- enum rdma_ch_state ch_state;1660180316611804 BUG_ON(!ch);16621805 BUG_ON(!recv_ioctx);···16641809 recv_ioctx->ioctx.dma, srp_max_req_size,16651810 DMA_FROM_DEVICE);1666181116671667- ch_state = srpt_get_ch_state(ch);16681668- if (unlikely(ch_state == CH_CONNECTING)) {18121812+ if (unlikely(ch->state == CH_CONNECTING)) {16691813 list_add_tail(&recv_ioctx->wait_list, &ch->cmd_wait_list);16701814 goto out;16711815 }1672181616731673- if (unlikely(ch_state != CH_LIVE))18171817+ if (unlikely(ch->state != CH_LIVE))16741818 goto out;1675181916761820 srp_cmd = recv_ioctx->ioctx.buf;···17321878 }17331879}1734188018811881+/*18821882+ * This function must be called from the context in which RDMA completions are18831883+ * processed because it accesses the wait list without protection against18841884+ * access from other threads.18851885+ */18861886+static void srpt_process_wait_list(struct srpt_rdma_ch *ch)18871887+{18881888+ struct srpt_send_ioctx *ioctx;18891889+18901890+ while (!list_empty(&ch->cmd_wait_list) &&18911891+ ch->state >= CH_LIVE &&18921892+ (ioctx = srpt_get_send_ioctx(ch)) != NULL) {18931893+ struct srpt_recv_ioctx *recv_ioctx;18941894+18951895+ recv_ioctx = list_first_entry(&ch->cmd_wait_list,18961896+ struct srpt_recv_ioctx,18971897+ wait_list);18981898+ list_del(&recv_ioctx->wait_list);18991899+ srpt_handle_new_iu(ch, recv_ioctx, ioctx);19001900+ }19011901+}19021902+17351903/**17361904 * Note: Although this has not yet been observed during tests, at least in17371905 * theory it is possible that the srpt_get_send_ioctx() call invoked by···1781190517821906 atomic_inc(&ch->sq_wr_avail);1783190717841784- if (wc->status != IB_WC_SUCCESS) {19081908+ if (wc->status != IB_WC_SUCCESS)17851909 pr_info("sending response for ioctx 0x%p failed"17861910 " with status %d\n", ioctx, wc->status);17871787-17881788- atomic_dec(&ch->req_lim);17891789- srpt_abort_cmd(ioctx);17901790- goto out;17911791- }1792191117931912 if (state != SRPT_STATE_DONE) {17941913 srpt_unmap_sg_to_ib_sge(ch, ioctx);···17931922 " wr_id = %u.\n", ioctx->ioctx.index);17941923 }1795192417961796-out:17971797- while (!list_empty(&ch->cmd_wait_list) &&17981798- srpt_get_ch_state(ch) == CH_LIVE &&17991799- (ioctx = srpt_get_send_ioctx(ch)) != NULL) {18001800- struct srpt_recv_ioctx *recv_ioctx;18011801-18021802- recv_ioctx = list_first_entry(&ch->cmd_wait_list,18031803- struct srpt_recv_ioctx,18041804- wait_list);18051805- list_del(&recv_ioctx->wait_list);18061806- srpt_handle_new_iu(ch, recv_ioctx, ioctx);18071807- }19251925+ srpt_process_wait_list(ch);18081926}1809192718101928/**···18101950 WARN_ON(ch->rq_size < 1);1811195118121952 ret = -ENOMEM;18131813- qp_init = kzalloc(sizeof *qp_init, GFP_KERNEL);19531953+ qp_init = kzalloc(sizeof(*qp_init), GFP_KERNEL);18141954 if (!qp_init)18151955 goto out;18161956···18772017}1878201818792019/**18801880- * __srpt_close_ch() - Close an RDMA channel by setting the QP error state.20202020+ * srpt_close_ch() - Close an RDMA channel.18812021 *18821882- * Reset the QP and make sure all resources associated with the channel will18831883- * be deallocated at an appropriate time.20222022+ * Make sure all resources associated with the channel will be deallocated at20232023+ * an appropriate time.18842024 *18851885- * Note: The caller must hold ch->sport->sdev->spinlock.20252025+ * Returns true if and only if the channel state has been modified into20262026+ * CH_DRAINING.18862027 */18871887-static void __srpt_close_ch(struct srpt_rdma_ch *ch)20282028+static bool srpt_close_ch(struct srpt_rdma_ch *ch)18882029{18891889- enum rdma_ch_state prev_state;18901890- unsigned long flags;20302030+ int ret;1891203118921892- spin_lock_irqsave(&ch->spinlock, flags);18931893- prev_state = ch->state;18941894- switch (prev_state) {18951895- case CH_CONNECTING:18961896- case CH_LIVE:18971897- ch->state = CH_DISCONNECTING;18981898- break;18991899- default:19001900- break;20322032+ if (!srpt_set_ch_state(ch, CH_DRAINING)) {20332033+ pr_debug("%s-%d: already closed\n", ch->sess_name,20342034+ ch->qp->qp_num);20352035+ return false;19012036 }19021902- spin_unlock_irqrestore(&ch->spinlock, flags);1903203719041904- switch (prev_state) {19051905- case CH_CONNECTING:19061906- ib_send_cm_rej(ch->cm_id, IB_CM_REJ_NO_RESOURCES, NULL, 0,19071907- NULL, 0);19081908- /* fall through */19091909- case CH_LIVE:19101910- if (ib_send_cm_dreq(ch->cm_id, NULL, 0) < 0)19111911- pr_err("sending CM DREQ failed.\n");19121912- break;19131913- case CH_DISCONNECTING:19141914- break;19151915- case CH_DRAINING:19161916- case CH_RELEASING:19171917- break;20382038+ kref_get(&ch->kref);20392039+20402040+ ret = srpt_ch_qp_err(ch);20412041+ if (ret < 0)20422042+ pr_err("%s-%d: changing queue pair into error state failed: %d\n",20432043+ ch->sess_name, ch->qp->qp_num, ret);20442044+20452045+ pr_debug("%s-%d: queued zerolength write\n", ch->sess_name,20462046+ ch->qp->qp_num);20472047+ ret = srpt_zerolength_write(ch);20482048+ if (ret < 0) {20492049+ pr_err("%s-%d: queuing zero-length write failed: %d\n",20502050+ ch->sess_name, ch->qp->qp_num, ret);20512051+ if (srpt_set_ch_state(ch, CH_DISCONNECTED))20522052+ schedule_work(&ch->release_work);20532053+ else20542054+ WARN_ON_ONCE(true);19182055 }20562056+20572057+ kref_put(&ch->kref, srpt_free_ch);20582058+20592059+ return true;19192060}1920206119211921-/**19221922- * srpt_close_ch() - Close an RDMA channel.20622062+/*20632063+ * Change the channel state into CH_DISCONNECTING. If a channel has not yet20642064+ * reached the connected state, close it. If a channel is in the connected20652065+ * state, send a DREQ. If a DREQ has been received, send a DREP. Note: it is20662066+ * the responsibility of the caller to ensure that this function is not20672067+ * invoked concurrently with the code that accepts a connection. This means20682068+ * that this function must either be invoked from inside a CM callback20692069+ * function or that it must be invoked with the srpt_port.mutex held.19232070 */19241924-static void srpt_close_ch(struct srpt_rdma_ch *ch)20712071+static int srpt_disconnect_ch(struct srpt_rdma_ch *ch)19252072{19261926- struct srpt_device *sdev;20732073+ int ret;1927207419281928- sdev = ch->sport->sdev;19291929- spin_lock_irq(&sdev->spinlock);19301930- __srpt_close_ch(ch);19311931- spin_unlock_irq(&sdev->spinlock);20752075+ if (!srpt_set_ch_state(ch, CH_DISCONNECTING))20762076+ return -ENOTCONN;20772077+20782078+ ret = ib_send_cm_dreq(ch->cm_id, NULL, 0);20792079+ if (ret < 0)20802080+ ret = ib_send_cm_drep(ch->cm_id, NULL, 0);20812081+20822082+ if (ret < 0 && srpt_close_ch(ch))20832083+ ret = 0;20842084+20852085+ return ret;20862086+}20872087+20882088+static void __srpt_close_all_ch(struct srpt_device *sdev)20892089+{20902090+ struct srpt_rdma_ch *ch;20912091+20922092+ lockdep_assert_held(&sdev->mutex);20932093+20942094+ list_for_each_entry(ch, &sdev->rch_list, list) {20952095+ if (srpt_disconnect_ch(ch) >= 0)20962096+ pr_info("Closing channel %s-%d because target %s has been disabled\n",20972097+ ch->sess_name, ch->qp->qp_num,20982098+ sdev->device->name);20992099+ srpt_close_ch(ch);21002100+ }19322101}1933210219342103/**···19652076 */19662077static int srpt_shutdown_session(struct se_session *se_sess)19672078{19681968- struct srpt_rdma_ch *ch = se_sess->fabric_sess_ptr;19691969- unsigned long flags;19701970-19711971- spin_lock_irqsave(&ch->spinlock, flags);19721972- if (ch->in_shutdown) {19731973- spin_unlock_irqrestore(&ch->spinlock, flags);19741974- return true;19751975- }19761976-19771977- ch->in_shutdown = true;19781978- target_sess_cmd_list_set_waiting(se_sess);19791979- spin_unlock_irqrestore(&ch->spinlock, flags);19801980-19811981- return true;20792079+ return 1;19822080}1983208119841984-/**19851985- * srpt_drain_channel() - Drain a channel by resetting the IB queue pair.19861986- * @cm_id: Pointer to the CM ID of the channel to be drained.19871987- *19881988- * Note: Must be called from inside srpt_cm_handler to avoid a race between19891989- * accessing sdev->spinlock and the call to kfree(sdev) in srpt_remove_one()19901990- * (the caller of srpt_cm_handler holds the cm_id spinlock; srpt_remove_one()19911991- * waits until all target sessions for the associated IB device have been19921992- * unregistered and target session registration involves a call to19931993- * ib_destroy_cm_id(), which locks the cm_id spinlock and hence waits until19941994- * this function has finished).19951995- */19961996-static void srpt_drain_channel(struct ib_cm_id *cm_id)20822082+static void srpt_free_ch(struct kref *kref)19972083{19981998- struct srpt_device *sdev;19991999- struct srpt_rdma_ch *ch;20002000- int ret;20012001- bool do_reset = false;20842084+ struct srpt_rdma_ch *ch = container_of(kref, struct srpt_rdma_ch, kref);2002208520032003- WARN_ON_ONCE(irqs_disabled());20042004-20052005- sdev = cm_id->context;20062006- BUG_ON(!sdev);20072007- spin_lock_irq(&sdev->spinlock);20082008- list_for_each_entry(ch, &sdev->rch_list, list) {20092009- if (ch->cm_id == cm_id) {20102010- do_reset = srpt_test_and_set_ch_state(ch,20112011- CH_CONNECTING, CH_DRAINING) ||20122012- srpt_test_and_set_ch_state(ch,20132013- CH_LIVE, CH_DRAINING) ||20142014- srpt_test_and_set_ch_state(ch,20152015- CH_DISCONNECTING, CH_DRAINING);20162016- break;20172017- }20182018- }20192019- spin_unlock_irq(&sdev->spinlock);20202020-20212021- if (do_reset) {20222022- if (ch->sess)20232023- srpt_shutdown_session(ch->sess);20242024-20252025- ret = srpt_ch_qp_err(ch);20262026- if (ret < 0)20272027- pr_err("Setting queue pair in error state"20282028- " failed: %d\n", ret);20292029- }20302030-}20312031-20322032-/**20332033- * srpt_find_channel() - Look up an RDMA channel.20342034- * @cm_id: Pointer to the CM ID of the channel to be looked up.20352035- *20362036- * Return NULL if no matching RDMA channel has been found.20372037- */20382038-static struct srpt_rdma_ch *srpt_find_channel(struct srpt_device *sdev,20392039- struct ib_cm_id *cm_id)20402040-{20412041- struct srpt_rdma_ch *ch;20422042- bool found;20432043-20442044- WARN_ON_ONCE(irqs_disabled());20452045- BUG_ON(!sdev);20462046-20472047- found = false;20482048- spin_lock_irq(&sdev->spinlock);20492049- list_for_each_entry(ch, &sdev->rch_list, list) {20502050- if (ch->cm_id == cm_id) {20512051- found = true;20522052- break;20532053- }20542054- }20552055- spin_unlock_irq(&sdev->spinlock);20562056-20572057- return found ? ch : NULL;20582058-}20592059-20602060-/**20612061- * srpt_release_channel() - Release channel resources.20622062- *20632063- * Schedules the actual release because:20642064- * - Calling the ib_destroy_cm_id() call from inside an IB CM callback would20652065- * trigger a deadlock.20662066- * - It is not safe to call TCM transport_* functions from interrupt context.20672067- */20682068-static void srpt_release_channel(struct srpt_rdma_ch *ch)20692069-{20702070- schedule_work(&ch->release_work);20862086+ kfree(ch);20712087}2072208820732089static void srpt_release_channel_work(struct work_struct *w)···19822188 struct se_session *se_sess;1983218919842190 ch = container_of(w, struct srpt_rdma_ch, release_work);19851985- pr_debug("ch = %p; ch->sess = %p; release_done = %p\n", ch, ch->sess,19861986- ch->release_done);21912191+ pr_debug("%s: %s-%d; release_done = %p\n", __func__, ch->sess_name,21922192+ ch->qp->qp_num, ch->release_done);1987219319882194 sdev = ch->sport->sdev;19892195 BUG_ON(!sdev);···19912197 se_sess = ch->sess;19922198 BUG_ON(!se_sess);1993219922002200+ target_sess_cmd_list_set_waiting(se_sess);19942201 target_wait_for_sess_cmds(se_sess);1995220219962203 transport_deregister_session_configfs(se_sess);···20062211 ch->sport->sdev, ch->rq_size,20072212 ch->rsp_size, DMA_TO_DEVICE);2008221320092009- spin_lock_irq(&sdev->spinlock);20102010- list_del(&ch->list);20112011- spin_unlock_irq(&sdev->spinlock);20122012-22142214+ mutex_lock(&sdev->mutex);22152215+ list_del_init(&ch->list);20132216 if (ch->release_done)20142217 complete(ch->release_done);22182218+ mutex_unlock(&sdev->mutex);2015221920162220 wake_up(&sdev->ch_releaseQ);2017222120182018- kfree(ch);22222222+ kref_put(&ch->kref, srpt_free_ch);20192223}2020222420212225/**···20602266 be64_to_cpu(*(__be64 *)&sdev->port[param->port - 1].gid.raw[0]),20612267 be64_to_cpu(*(__be64 *)&sdev->port[param->port - 1].gid.raw[8]));2062226820632063- rsp = kzalloc(sizeof *rsp, GFP_KERNEL);20642064- rej = kzalloc(sizeof *rej, GFP_KERNEL);20652065- rep_param = kzalloc(sizeof *rep_param, GFP_KERNEL);22692269+ rsp = kzalloc(sizeof(*rsp), GFP_KERNEL);22702270+ rej = kzalloc(sizeof(*rej), GFP_KERNEL);22712271+ rep_param = kzalloc(sizeof(*rep_param), GFP_KERNEL);2066227220672273 if (!rsp || !rej || !rep_param) {20682274 ret = -ENOMEM;···20912297 if ((req->req_flags & SRP_MTCH_ACTION) == SRP_MULTICHAN_SINGLE) {20922298 rsp->rsp_flags = SRP_LOGIN_RSP_MULTICHAN_NO_CHAN;2093229920942094- spin_lock_irq(&sdev->spinlock);23002300+ mutex_lock(&sdev->mutex);2095230120962302 list_for_each_entry_safe(ch, tmp_ch, &sdev->rch_list, list) {20972303 if (!memcmp(ch->i_port_id, req->initiator_port_id, 16)···20992305 && param->port == ch->sport->port21002306 && param->listen_id == ch->sport->sdev->cm_id21012307 && ch->cm_id) {21022102- enum rdma_ch_state ch_state;21032103-21042104- ch_state = srpt_get_ch_state(ch);21052105- if (ch_state != CH_CONNECTING21062106- && ch_state != CH_LIVE)23082308+ if (srpt_disconnect_ch(ch) < 0)21072309 continue;21082108-21092109- /* found an existing channel */21102110- pr_debug("Found existing channel %s"21112111- " cm_id= %p state= %d\n",21122112- ch->sess_name, ch->cm_id, ch_state);21132113-21142114- __srpt_close_ch(ch);21152115-23102310+ pr_info("Relogin - closed existing channel %s\n",23112311+ ch->sess_name);21162312 rsp->rsp_flags =21172313 SRP_LOGIN_RSP_MULTICHAN_TERMINATED;21182314 }21192315 }2120231621212121- spin_unlock_irq(&sdev->spinlock);23172317+ mutex_unlock(&sdev->mutex);2122231821232319 } else21242320 rsp->rsp_flags = SRP_LOGIN_RSP_MULTICHAN_MAINTAINED;···21242340 goto reject;21252341 }2126234221272127- ch = kzalloc(sizeof *ch, GFP_KERNEL);23432343+ ch = kzalloc(sizeof(*ch), GFP_KERNEL);21282344 if (!ch) {21292345 rej->reason = cpu_to_be32(21302346 SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);···21332349 goto reject;21342350 }2135235123522352+ kref_init(&ch->kref);23532353+ ch->zw_cqe.done = srpt_zerolength_write_done;21362354 INIT_WORK(&ch->release_work, srpt_release_channel_work);21372355 memcpy(ch->i_port_id, req->initiator_port_id, 16);21382356 memcpy(ch->t_port_id, req->target_port_id, 16);21392357 ch->sport = &sdev->port[param->port - 1];21402358 ch->cm_id = cm_id;23592359+ cm_id->context = ch;21412360 /*21422361 * Avoid QUEUE_FULL conditions by limiting the number of buffers used21432362 * for the SRP protocol to the command queue size.···22402453 /* create cm reply */22412454 rep_param->qp_num = ch->qp->qp_num;22422455 rep_param->private_data = (void *)rsp;22432243- rep_param->private_data_len = sizeof *rsp;24562456+ rep_param->private_data_len = sizeof(*rsp);22442457 rep_param->rnr_retry_count = 7;22452458 rep_param->flow_control = 1;22462459 rep_param->failover_accepted = 0;···22552468 goto release_channel;22562469 }2257247022582258- spin_lock_irq(&sdev->spinlock);24712471+ mutex_lock(&sdev->mutex);22592472 list_add_tail(&ch->list, &sdev->rch_list);22602260- spin_unlock_irq(&sdev->spinlock);24732473+ mutex_unlock(&sdev->mutex);2261247422622475 goto out;2263247622642477release_channel:22652265- srpt_set_ch_state(ch, CH_RELEASING);24782478+ srpt_disconnect_ch(ch);22662479 transport_deregister_session_configfs(ch->sess);22672480 transport_deregister_session(ch->sess);22682481 ch->sess = NULL;···22842497 | SRP_BUF_FORMAT_INDIRECT);2285249822862499 ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED, NULL, 0,22872287- (void *)rej, sizeof *rej);25002500+ (void *)rej, sizeof(*rej));2288250122892502out:22902503 kfree(rep_param);···22942507 return ret;22952508}2296250922972297-static void srpt_cm_rej_recv(struct ib_cm_id *cm_id)25102510+static void srpt_cm_rej_recv(struct srpt_rdma_ch *ch,25112511+ enum ib_cm_rej_reason reason,25122512+ const u8 *private_data,25132513+ u8 private_data_len)22982514{22992299- pr_info("Received IB REJ for cm_id %p.\n", cm_id);23002300- srpt_drain_channel(cm_id);25152515+ char *priv = NULL;25162516+ int i;25172517+25182518+ if (private_data_len && (priv = kmalloc(private_data_len * 3 + 1,25192519+ GFP_KERNEL))) {25202520+ for (i = 0; i < private_data_len; i++)25212521+ sprintf(priv + 3 * i, " %02x", private_data[i]);25222522+ }25232523+ pr_info("Received CM REJ for ch %s-%d; reason %d%s%s.\n",25242524+ ch->sess_name, ch->qp->qp_num, reason, private_data_len ?25252525+ "; private data" : "", priv ? priv : " (?)");25262526+ kfree(priv);23012527}2302252823032529/**···23192519 * An IB_CM_RTU_RECEIVED message indicates that the connection is established23202520 * and that the recipient may begin transmitting (RTU = ready to use).23212521 */23222322-static void srpt_cm_rtu_recv(struct ib_cm_id *cm_id)25222522+static void srpt_cm_rtu_recv(struct srpt_rdma_ch *ch)23232523{23242324- struct srpt_rdma_ch *ch;23252524 int ret;2326252523272327- ch = srpt_find_channel(cm_id->context, cm_id);23282328- BUG_ON(!ch);23292329-23302330- if (srpt_test_and_set_ch_state(ch, CH_CONNECTING, CH_LIVE)) {23312331- struct srpt_recv_ioctx *ioctx, *ioctx_tmp;23322332-25262526+ if (srpt_set_ch_state(ch, CH_LIVE)) {23332527 ret = srpt_ch_qp_rts(ch, ch->qp);2334252823352335- list_for_each_entry_safe(ioctx, ioctx_tmp, &ch->cmd_wait_list,23362336- wait_list) {23372337- list_del(&ioctx->wait_list);23382338- srpt_handle_new_iu(ch, ioctx, NULL);23392339- }23402340- if (ret)25292529+ if (ret == 0) {25302530+ /* Trigger wait list processing. */25312531+ ret = srpt_zerolength_write(ch);25322532+ WARN_ONCE(ret < 0, "%d\n", ret);25332533+ } else {23412534 srpt_close_ch(ch);25352535+ }23422536 }23432343-}23442344-23452345-static void srpt_cm_timewait_exit(struct ib_cm_id *cm_id)23462346-{23472347- pr_info("Received IB TimeWait exit for cm_id %p.\n", cm_id);23482348- srpt_drain_channel(cm_id);23492349-}23502350-23512351-static void srpt_cm_rep_error(struct ib_cm_id *cm_id)23522352-{23532353- pr_info("Received IB REP error for cm_id %p.\n", cm_id);23542354- srpt_drain_channel(cm_id);23552355-}23562356-23572357-/**23582358- * srpt_cm_dreq_recv() - Process reception of a DREQ message.23592359- */23602360-static void srpt_cm_dreq_recv(struct ib_cm_id *cm_id)23612361-{23622362- struct srpt_rdma_ch *ch;23632363- unsigned long flags;23642364- bool send_drep = false;23652365-23662366- ch = srpt_find_channel(cm_id->context, cm_id);23672367- BUG_ON(!ch);23682368-23692369- pr_debug("cm_id= %p ch->state= %d\n", cm_id, srpt_get_ch_state(ch));23702370-23712371- spin_lock_irqsave(&ch->spinlock, flags);23722372- switch (ch->state) {23732373- case CH_CONNECTING:23742374- case CH_LIVE:23752375- send_drep = true;23762376- ch->state = CH_DISCONNECTING;23772377- break;23782378- case CH_DISCONNECTING:23792379- case CH_DRAINING:23802380- case CH_RELEASING:23812381- WARN(true, "unexpected channel state %d\n", ch->state);23822382- break;23832383- }23842384- spin_unlock_irqrestore(&ch->spinlock, flags);23852385-23862386- if (send_drep) {23872387- if (ib_send_cm_drep(ch->cm_id, NULL, 0) < 0)23882388- pr_err("Sending IB DREP failed.\n");23892389- pr_info("Received DREQ and sent DREP for session %s.\n",23902390- ch->sess_name);23912391- }23922392-}23932393-23942394-/**23952395- * srpt_cm_drep_recv() - Process reception of a DREP message.23962396- */23972397-static void srpt_cm_drep_recv(struct ib_cm_id *cm_id)23982398-{23992399- pr_info("Received InfiniBand DREP message for cm_id %p.\n", cm_id);24002400- srpt_drain_channel(cm_id);24012537}2402253824032539/**···23482612 */23492613static int srpt_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)23502614{26152615+ struct srpt_rdma_ch *ch = cm_id->context;23512616 int ret;2352261723532618 ret = 0;···23582621 event->private_data);23592622 break;23602623 case IB_CM_REJ_RECEIVED:23612361- srpt_cm_rej_recv(cm_id);26242624+ srpt_cm_rej_recv(ch, event->param.rej_rcvd.reason,26252625+ event->private_data,26262626+ IB_CM_REJ_PRIVATE_DATA_SIZE);23622627 break;23632628 case IB_CM_RTU_RECEIVED:23642629 case IB_CM_USER_ESTABLISHED:23652365- srpt_cm_rtu_recv(cm_id);26302630+ srpt_cm_rtu_recv(ch);23662631 break;23672632 case IB_CM_DREQ_RECEIVED:23682368- srpt_cm_dreq_recv(cm_id);26332633+ srpt_disconnect_ch(ch);23692634 break;23702635 case IB_CM_DREP_RECEIVED:23712371- srpt_cm_drep_recv(cm_id);26362636+ pr_info("Received CM DREP message for ch %s-%d.\n",26372637+ ch->sess_name, ch->qp->qp_num);26382638+ srpt_close_ch(ch);23722639 break;23732640 case IB_CM_TIMEWAIT_EXIT:23742374- srpt_cm_timewait_exit(cm_id);26412641+ pr_info("Received CM TimeWait exit for ch %s-%d.\n",26422642+ ch->sess_name, ch->qp->qp_num);26432643+ srpt_close_ch(ch);23752644 break;23762645 case IB_CM_REP_ERROR:23772377- srpt_cm_rep_error(cm_id);26462646+ pr_info("Received CM REP error for ch %s-%d.\n", ch->sess_name,26472647+ ch->qp->qp_num);23782648 break;23792649 case IB_CM_DREQ_ERROR:23802380- pr_info("Received IB DREQ ERROR event.\n");26502650+ pr_info("Received CM DREQ ERROR event.\n");23812651 break;23822652 case IB_CM_MRA_RECEIVED:23832383- pr_info("Received IB MRA event\n");26532653+ pr_info("Received CM MRA event\n");23842654 break;23852655 default:23862386- pr_err("received unrecognized IB CM event %d\n", event->event);26562656+ pr_err("received unrecognized CM event %d\n", event->event);23872657 break;23882658 }23892659···24992755 */25002756static int srpt_write_pending(struct se_cmd *se_cmd)25012757{25022502- struct srpt_rdma_ch *ch;25032503- struct srpt_send_ioctx *ioctx;27582758+ struct srpt_send_ioctx *ioctx =27592759+ container_of(se_cmd, struct srpt_send_ioctx, cmd);27602760+ struct srpt_rdma_ch *ch = ioctx->ch;25042761 enum srpt_command_state new_state;25052505- enum rdma_ch_state ch_state;25062506- int ret;25072507-25082508- ioctx = container_of(se_cmd, struct srpt_send_ioctx, cmd);2509276225102763 new_state = srpt_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA);25112764 WARN_ON(new_state == SRPT_STATE_DONE);25122512-25132513- ch = ioctx->ch;25142514- BUG_ON(!ch);25152515-25162516- ch_state = srpt_get_ch_state(ch);25172517- switch (ch_state) {25182518- case CH_CONNECTING:25192519- WARN(true, "unexpected channel state %d\n", ch_state);25202520- ret = -EINVAL;25212521- goto out;25222522- case CH_LIVE:25232523- break;25242524- case CH_DISCONNECTING:25252525- case CH_DRAINING:25262526- case CH_RELEASING:25272527- pr_debug("cmd with tag %lld: channel disconnecting\n",25282528- ioctx->cmd.tag);25292529- srpt_set_cmd_state(ioctx, SRPT_STATE_DATA_IN);25302530- ret = -EINVAL;25312531- goto out;25322532- }25332533- ret = srpt_xfer_data(ch, ioctx);25342534-25352535-out:25362536- return ret;27652765+ return srpt_xfer_data(ch, ioctx);25372766}2538276725392768static u8 tcm_to_srp_tsk_mgmt_status(const int tcm_mgmt_status)···26372920 srpt_refresh_port(sport);26382921}2639292226402640-static int srpt_ch_list_empty(struct srpt_device *sdev)26412641-{26422642- int res;26432643-26442644- spin_lock_irq(&sdev->spinlock);26452645- res = list_empty(&sdev->rch_list);26462646- spin_unlock_irq(&sdev->spinlock);26472647-26482648- return res;26492649-}26502650-26512923/**26522924 * srpt_release_sdev() - Free the channel resources associated with a target.26532925 */26542926static int srpt_release_sdev(struct srpt_device *sdev)26552927{26562656- struct srpt_rdma_ch *ch, *tmp_ch;26572657- int res;29282928+ int i, res;2658292926592930 WARN_ON_ONCE(irqs_disabled());2660293126612932 BUG_ON(!sdev);2662293326632663- spin_lock_irq(&sdev->spinlock);26642664- list_for_each_entry_safe(ch, tmp_ch, &sdev->rch_list, list)26652665- __srpt_close_ch(ch);26662666- spin_unlock_irq(&sdev->spinlock);29342934+ mutex_lock(&sdev->mutex);29352935+ for (i = 0; i < ARRAY_SIZE(sdev->port); i++)29362936+ sdev->port[i].enabled = false;29372937+ __srpt_close_all_ch(sdev);29382938+ mutex_unlock(&sdev->mutex);2667293926682940 res = wait_event_interruptible(sdev->ch_releaseQ,26692669- srpt_ch_list_empty(sdev));29412941+ list_empty_careful(&sdev->rch_list));26702942 if (res)26712943 pr_err("%s: interrupted.\n", __func__);26722944···27093003 pr_debug("device = %p, device->dma_ops = %p\n", device,27103004 device->dma_ops);2711300527122712- sdev = kzalloc(sizeof *sdev, GFP_KERNEL);30063006+ sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);27133007 if (!sdev)27143008 goto err;2715300927163010 sdev->device = device;27173011 INIT_LIST_HEAD(&sdev->rch_list);27183012 init_waitqueue_head(&sdev->ch_releaseQ);27192719- spin_lock_init(&sdev->spinlock);30133013+ mutex_init(&sdev->mutex);2720301427213015 sdev->pd = ib_alloc_pd(device);27223016 if (IS_ERR(sdev->pd))···2788308227893083 if (srpt_refresh_port(sport)) {27903084 pr_err("MAD registration failed for %s-%d.\n",27912791- srpt_sdev_name(sdev), i);30853085+ sdev->device->name, i);27923086 goto err_ring;27933087 }27943088 snprintf(sport->port_guid, sizeof(sport->port_guid),···29373231static void srpt_close_session(struct se_session *se_sess)29383232{29393233 DECLARE_COMPLETION_ONSTACK(release_done);29402940- struct srpt_rdma_ch *ch;29412941- struct srpt_device *sdev;29422942- unsigned long res;32343234+ struct srpt_rdma_ch *ch = se_sess->fabric_sess_ptr;32353235+ struct srpt_device *sdev = ch->sport->sdev;32363236+ bool wait;2943323729442944- ch = se_sess->fabric_sess_ptr;29452945- WARN_ON(ch->sess != se_sess);32383238+ pr_debug("ch %s-%d state %d\n", ch->sess_name, ch->qp->qp_num,32393239+ ch->state);2946324029472947- pr_debug("ch %p state %d\n", ch, srpt_get_ch_state(ch));29482948-29492949- sdev = ch->sport->sdev;29502950- spin_lock_irq(&sdev->spinlock);32413241+ mutex_lock(&sdev->mutex);29513242 BUG_ON(ch->release_done);29523243 ch->release_done = &release_done;29532953- __srpt_close_ch(ch);29542954- spin_unlock_irq(&sdev->spinlock);32443244+ wait = !list_empty(&ch->list);32453245+ srpt_disconnect_ch(ch);32463246+ mutex_unlock(&sdev->mutex);2955324729562956- res = wait_for_completion_timeout(&release_done, 60 * HZ);29572957- WARN_ON(res == 0);32483248+ if (!wait)32493249+ return;32503250+32513251+ while (wait_for_completion_timeout(&release_done, 180 * HZ) == 0)32523252+ pr_info("%s(%s-%d state %d): still waiting ...\n", __func__,32533253+ ch->sess_name, ch->qp->qp_num, ch->state);29583254}2959325529603256/**···31643456{31653457 struct se_portal_group *se_tpg = to_tpg(item);31663458 struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);34593459+ struct srpt_device *sdev = sport->sdev;34603460+ struct srpt_rdma_ch *ch;31673461 unsigned long tmp;31683462 int ret;31693463···31793469 pr_err("Illegal value for srpt_tpg_store_enable: %lu\n", tmp);31803470 return -EINVAL;31813471 }31823182- if (tmp == 1)31833183- sport->enabled = true;31843184- else31853185- sport->enabled = false;34723472+ if (sport->enabled == tmp)34733473+ goto out;34743474+ sport->enabled = tmp;34753475+ if (sport->enabled)34763476+ goto out;3186347734783478+ mutex_lock(&sdev->mutex);34793479+ list_for_each_entry(ch, &sdev->rch_list, list) {34803480+ if (ch->sport == sport) {34813481+ pr_debug("%s: ch %p %s-%d\n", __func__, ch,34823482+ ch->sess_name, ch->qp->qp_num);34833483+ srpt_disconnect_ch(ch);34843484+ srpt_close_ch(ch);34853485+ }34863486+ }34873487+ mutex_unlock(&sdev->mutex);34883488+34893489+out:31873490 return count;31883491}31893492···32883565static const struct target_core_fabric_ops srpt_template = {32893566 .module = THIS_MODULE,32903567 .name = "srpt",32913291- .node_acl_size = sizeof(struct srpt_node_acl),32923568 .get_fabric_name = srpt_get_fabric_name,32933569 .tpg_get_wwn = srpt_get_fabric_wwn,32943570 .tpg_get_tag = srpt_get_tag,
+12-19
drivers/infiniband/ulp/srpt/ib_srpt.h
···218218219219/**220220 * enum rdma_ch_state - SRP channel state.221221- * @CH_CONNECTING: QP is in RTR state; waiting for RTU.222222- * @CH_LIVE: QP is in RTS state.223223- * @CH_DISCONNECTING: DREQ has been received; waiting for DREP224224- * or DREQ has been send and waiting for DREP225225- * or .226226- * @CH_DRAINING: QP is in ERR state; waiting for last WQE event.227227- * @CH_RELEASING: Last WQE event has been received; releasing resources.221221+ * @CH_CONNECTING: QP is in RTR state; waiting for RTU.222222+ * @CH_LIVE: QP is in RTS state.223223+ * @CH_DISCONNECTING: DREQ has been sent and waiting for DREP or DREQ has224224+ * been received.225225+ * @CH_DRAINING: DREP has been received or waiting for DREP timed out226226+ * and last work request has been queued.227227+ * @CH_DISCONNECTED: Last completion has been received.228228 */229229enum rdma_ch_state {230230 CH_CONNECTING,231231 CH_LIVE,232232 CH_DISCONNECTING,233233 CH_DRAINING,234234- CH_RELEASING234234+ CH_DISCONNECTED,235235};236236237237/**···267267 struct ib_cm_id *cm_id;268268 struct ib_qp *qp;269269 struct ib_cq *cq;270270+ struct ib_cqe zw_cqe;271271+ struct kref kref;270272 int rq_size;271273 u32 rsp_size;272274 atomic_t sq_wr_avail;···288286 u8 sess_name[36];289287 struct work_struct release_work;290288 struct completion *release_done;291291- bool in_shutdown;292289};293290294291/**···344343 * @ioctx_ring: Per-HCA SRQ.345344 * @rch_list: Per-device channel list -- see also srpt_rdma_ch.list.346345 * @ch_releaseQ: Enables waiting for removal from rch_list.347347- * @spinlock: Protects rch_list and tpg.346346+ * @mutex: Protects rch_list.348347 * @port: Information about the ports owned by this HCA.349348 * @event_handler: Per-HCA asynchronous IB event handler.350349 * @list: Node in srpt_dev_list.···358357 struct srpt_recv_ioctx **ioctx_ring;359358 struct list_head rch_list;360359 wait_queue_head_t ch_releaseQ;361361- spinlock_t spinlock;360360+ struct mutex mutex;362361 struct srpt_port port[2];363362 struct ib_event_handler event_handler;364363 struct list_head list;365365-};366366-367367-/**368368- * struct srpt_node_acl - Per-initiator ACL data (managed via configfs).369369- * @nacl: Target core node ACL information.370370- */371371-struct srpt_node_acl {372372- struct se_node_acl nacl;373364};374365375366#endif /* IB_SRPT_H */