diff --git a/iscsi-scst/README.iser b/iscsi-scst/README.iser index ea5a57511..751213edc 100644 --- a/iscsi-scst/README.iser +++ b/iscsi-scst/README.iser @@ -25,9 +25,10 @@ Limitations: ------------- * Bidirectional commands are not supported * Block size over 512KB is not supported -* Maximum number of concurent login requests that can be handled is 127. +* Maximum number of concurent login requests that can be handled is 127 by default. Note that there may be more connections, but only up to 127 login requests - can be handled at the same time. + can be handled at the same time. If you wish to increase this, load isert_scst with + module parameter isert_nr_devs set to the number of login requests you need to handle. Troubleshooting: diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index 95cdc4ec5..be8c8c9a2 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -66,6 +66,8 @@ struct isert_wr { #define ISER_SQ_SIZE 128 #define ISER_MAX_WCE 2048 +#define ISER_MIN_SQ_SIZE 16 + struct isert_cmnd { struct iscsi_cmnd iscsi ____cacheline_aligned; diff --git a/iscsi-scst/kernel/isert-scst/iser_buf.c b/iscsi-scst/kernel/isert-scst/iser_buf.c index 32daeb377..dd418f0de 100644 --- a/iscsi-scst/kernel/isert-scst/iser_buf.c +++ b/iscsi-scst/kernel/isert-scst/iser_buf.c @@ -293,9 +293,11 @@ void isert_wr_release(struct isert_wr *wr) struct isert_device *isert_dev = wr->isert_dev; struct ib_device *ib_dev; - ib_dev = isert_dev->ib_dev; - ib_dma_unmap_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, - isert_buf->dma_dir); + if (isert_buf->sg_cnt) { + ib_dev = isert_dev->ib_dev; + ib_dma_unmap_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, + isert_buf->dma_dir); + } isert_buf_release(isert_buf); } memset(wr, 0, sizeof(*wr)); diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 0c669e611..03dc2afa9 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -359,6 +359,7 @@ static void isert_rdma_rd_completion_handler(struct isert_wr *wr) ib_dma_unmap_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, isert_buf->dma_dir); + isert_buf->sg_cnt = 0; isert_data_out_ready(&wr->pdu->iscsi); } @@ -371,6 +372,7 @@ static void isert_rdma_wr_completion_handler(struct isert_wr *wr) ib_dma_unmap_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, isert_buf->dma_dir); + isert_buf->sg_cnt = 0; isert_data_in_sent(&wr->pdu->iscsi); } @@ -544,9 +546,9 @@ static void isert_handle_wc_error(struct ib_wc *wc) break; case ISER_WR_RDMA_READ: if (isert_buf->sg_cnt != 0) { - isert_buf->sg_cnt = 0; ib_dma_unmap_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, isert_buf->dma_dir); + isert_buf->sg_cnt = 0; } isert_pdu_err(&isert_pdu->iscsi); break; @@ -555,9 +557,9 @@ static void isert_handle_wc_error(struct ib_wc *wc) break; case ISER_WR_RDMA_WRITE: if (isert_buf->sg_cnt != 0) { - isert_buf->sg_cnt = 0; ib_dma_unmap_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, isert_buf->dma_dir); + isert_buf->sg_cnt = 0; } /* RDMA-WR and SEND response of a READ task are sent together, so when receiving RDMA-WR error, @@ -978,6 +980,7 @@ static int isert_conn_qp_create(struct isert_connection *isert_conn) struct ib_qp_init_attr qp_attr; int err; int cq_idx; + int max_wr = ISER_MAX_WCE; TRACE_ENTRY(); @@ -989,8 +992,6 @@ static int isert_conn_qp_create(struct isert_connection *isert_conn) qp_attr.qp_context = isert_conn; qp_attr.send_cq = isert_dev->cq_desc[cq_idx].cq; qp_attr.recv_cq = isert_dev->cq_desc[cq_idx].cq; - qp_attr.cap.max_send_wr = ISER_MAX_WCE; - qp_attr.cap.max_recv_wr = ISER_MAX_WCE; isert_conn->cq_desc = &isert_dev->cq_desc[cq_idx]; @@ -1014,11 +1015,24 @@ static int isert_conn_qp_create(struct isert_connection *isert_conn) qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; qp_attr.qp_type = IB_QPT_RC; - err = rdma_create_qp(cm_id, isert_dev->pd, &qp_attr); - if (unlikely(err)) { - pr_err("Failed to create qp, err:%d\n", err); - goto fail_create_qp; - } + do { + if (max_wr < ISER_MIN_SQ_SIZE) { + pr_err("Failed to create qp, not enough memory\n"); + goto fail_create_qp; + } + + qp_attr.cap.max_send_wr = max_wr; + qp_attr.cap.max_recv_wr = max_wr; + + err = rdma_create_qp(cm_id, isert_dev->pd, &qp_attr); + if (err && err != -ENOMEM) { + pr_err("Failed to create qp, err:%d\n", err); + goto fail_create_qp; + } + + max_wr /= 2; + } while (err == -ENOMEM); + isert_conn->qp = cm_id->qp; pr_info("iser created cm_id:%p qp:0x%X\n", cm_id, cm_id->qp->qp_num);