diff --git a/iscsi-scst/README.iser b/iscsi-scst/README.iser index a52d1a8b1..014bef310 100644 --- a/iscsi-scst/README.iser +++ b/iscsi-scst/README.iser @@ -24,7 +24,6 @@ NUMA node, you want the HCA to be close to the same node. 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 by default. Note that there may be more connections, but only up to 127 login requests can be handled at the same time. If you wish to increase this, load isert_scst with diff --git a/iscsi-scst/kernel/isert-scst/TODO b/iscsi-scst/kernel/isert-scst/TODO index 479c6b76b..7f14da508 100644 --- a/iscsi-scst/kernel/isert-scst/TODO +++ b/iscsi-scst/kernel/isert-scst/TODO @@ -1,6 +1,5 @@ * Add suppport for immediate data in iSER * Add suppport for data-out in iSER -* Look into allocating wr and sg entries dynamically from kmem_cache instead of embedding them into iser_cmnd * Look into seperating between RX pdu and TX pdu * Do not signal every "response sent" notification * Make the code NUMA aware diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index b6e77d0bd..a2b4a00af 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -102,9 +102,6 @@ struct isert_wr { }; } ____cacheline_aligned; -#define ISER_MAX_SGE 128 -#define ISER_MAX_RDMAS 5 - #define ISER_SQ_SIZE 128 #define ISER_MAX_WCE 2048 @@ -115,8 +112,10 @@ struct isert_cmnd { struct isert_buf buf; struct isert_buf rdma_buf; - struct isert_wr wr[ISER_MAX_RDMAS]; - struct ib_sge sg_pool[ISER_MAX_SGE]; + struct isert_wr *wr; + struct ib_sge *sg_pool; + int n_wr; + int n_sge; struct isert_hdr *isert_hdr ____cacheline_aligned; struct iscsi_hdr *bhs; diff --git a/iscsi-scst/kernel/isert-scst/iser_pdu.c b/iscsi-scst/kernel/isert-scst/iser_pdu.c index 44da27172..6abffee68 100644 --- a/iscsi-scst/kernel/isert-scst/iser_pdu.c +++ b/iscsi-scst/kernel/isert-scst/iser_pdu.c @@ -166,6 +166,50 @@ static inline int isert_pdu_prepare_send(struct isert_connection *isert_conn, return sg_cnt; } +static int isert_alloc_for_rdma(struct isert_cmnd *pdu, int sge_cnt, + struct isert_connection *isert_conn) +{ + struct isert_wr *wr; + struct ib_sge *sg_pool; + int i, ret = 0; + int wr_cnt; + + sg_pool = kmalloc(sizeof(*sg_pool) * sge_cnt, GFP_KERNEL); + if (unlikely(sg_pool == NULL)) { + ret = -ENOMEM; + goto out; + } + + wr_cnt = DIV_ROUND_UP(sge_cnt, isert_conn->max_sge); + wr = kmalloc(sizeof(*wr) * wr_cnt, GFP_KERNEL); + if (unlikely(wr == NULL)) { + ret = -ENOMEM; + goto out_free_sg_pool; + } + + kfree(pdu->wr); + pdu->wr = wr; + + kfree(pdu->sg_pool); + pdu->sg_pool = sg_pool; + + pdu->n_wr = wr_cnt; + pdu->n_sge = sge_cnt; + + for (i = 0; i < wr_cnt; ++i) + isert_wr_set_fields(&pdu->wr[i], isert_conn, pdu); + + for (i = 0; i < sge_cnt; ++i) + pdu->sg_pool[i].lkey = isert_conn->isert_dev->mr->lkey; + + goto out; + +out_free_sg_pool: + kfree(sg_pool); +out: + return ret; +} + static inline void isert_link_send_wrs(struct isert_wr *from_wr, struct isert_wr *to_wr) { @@ -204,10 +248,10 @@ int isert_prepare_rdma(struct isert_cmnd *isert_pdu, else isert_buf->dma_dir = DMA_FROM_DEVICE; - if (unlikely(isert_buf->sg_cnt > ISER_MAX_SGE)) { - pr_err("Scatterlist too large: %d\n", isert_buf->sg_cnt); - wr_cnt = -EOPNOTSUPP; - goto out; + if (unlikely(isert_buf->sg_cnt > isert_pdu->n_sge)) { + wr_cnt = isert_alloc_for_rdma(isert_pdu, isert_buf->sg_cnt, isert_conn); + if (unlikely(wr_cnt)) + goto out; } err = ib_dma_map_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, @@ -245,12 +289,18 @@ out: void isert_pdu_free(struct isert_cmnd *pdu) { - unsigned int i; + int i; list_del(&pdu->pool_node); - for (i = 0; i < ARRAY_SIZE(pdu->wr); ++i) + for (i = 0; i < pdu->n_wr; ++i) isert_wr_release(&pdu->wr[i]); + kfree(pdu->wr); + pdu->wr = NULL; + + kfree(pdu->sg_pool); + pdu->sg_pool = NULL; + isert_pdu_kfree(pdu); } @@ -259,7 +309,6 @@ struct isert_cmnd *isert_rx_pdu_alloc(struct isert_connection *isert_conn, { struct isert_cmnd *pdu = NULL; int err; - unsigned int i; TRACE_ENTRY(); @@ -269,6 +318,12 @@ struct isert_cmnd *isert_rx_pdu_alloc(struct isert_connection *isert_conn, goto out; } + err = isert_alloc_for_rdma(pdu, 4, isert_conn); + if (unlikely(err)) { + pr_err("Failed to alloc sge and wr for rx pdu\n"); + goto out; + } + err = isert_buf_alloc_data_buf(isert_conn->isert_dev->ib_dev, &pdu->buf, size, DMA_FROM_DEVICE); if (unlikely(err)) { @@ -283,12 +338,6 @@ struct isert_cmnd *isert_rx_pdu_alloc(struct isert_connection *isert_conn, goto pdu_init_failed; } - for (i = 0; i < ARRAY_SIZE(pdu->wr); ++i) - isert_wr_set_fields(&pdu->wr[i], isert_conn, pdu); - - for (i = 0; i < ARRAY_SIZE(pdu->sg_pool); ++i) - pdu->sg_pool[i].lkey = isert_conn->isert_dev->mr->lkey; - list_add_tail(&pdu->pool_node, &isert_conn->rx_buf_list); goto out; @@ -308,7 +357,6 @@ struct isert_cmnd *isert_tx_pdu_alloc(struct isert_connection *isert_conn, { struct isert_cmnd *pdu = NULL; int err; - unsigned int i; TRACE_ENTRY(); @@ -318,6 +366,12 @@ struct isert_cmnd *isert_tx_pdu_alloc(struct isert_connection *isert_conn, goto out; } + err = isert_alloc_for_rdma(pdu, 4, isert_conn); + if (unlikely(err)) { + pr_err("Failed to alloc sge and wr for tx pdu\n"); + goto out; + } + err = isert_buf_alloc_data_buf(isert_conn->isert_dev->ib_dev, &pdu->buf, size, DMA_TO_DEVICE); if (unlikely(err)) { @@ -331,14 +385,9 @@ struct isert_cmnd *isert_tx_pdu_alloc(struct isert_connection *isert_conn, &pdu->wr, size, err); goto buf_init_failed; } + isert_tx_pdu_init(pdu, isert_conn); - for (i = 0; i < ARRAY_SIZE(pdu->wr); ++i) - isert_wr_set_fields(&pdu->wr[i], isert_conn, pdu); - - for (i = 0; i < ARRAY_SIZE(pdu->sg_pool); ++i) - pdu->sg_pool[i].lkey = isert_conn->isert_dev->mr->lkey; - isert_pdu_set_hdr_plain(pdu); list_add_tail(&pdu->pool_node, &isert_conn->tx_free_list); diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index d739374d4..a7dae9a56 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1011,21 +1011,6 @@ static int isert_conn_qp_create(struct isert_connection *isert_conn) isert_conn->cq_desc = &isert_dev->cq_desc[cq_idx]; - /* - * A quote from the OFED 1.5.3.1 release notes - * (docs/release_notes/mthca_release_notes.txt), section "Known Issues": - * In mem-free devices, RC QPs can be created with a maximum of - * (max_sge - 1) entries only; UD QPs can be created with a maximum of - * (max_sge - 3) entries. - * A quote from the OFED 1.2.5 release notes - * (docs/mthca_release_notes.txt), section "Known Issues": - * In mem-free devices, RC QPs can be created with a maximum of - * (max_sge - 3) entries only. - */ - isert_conn->max_sge = isert_dev->device_attr.max_sge - 3; - - WARN_ON(isert_conn->max_sge < 1); - qp_attr.cap.max_send_sge = isert_conn->max_sge; qp_attr.cap.max_recv_sge = 3; qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; @@ -1089,6 +1074,21 @@ static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, isert_conn->cm_id = cm_id; isert_conn->isert_dev = isert_dev; + /* + * A quote from the OFED 1.5.3.1 release notes + * (docs/release_notes/mthca_release_notes.txt), section "Known Issues": + * In mem-free devices, RC QPs can be created with a maximum of + * (max_sge - 1) entries only; UD QPs can be created with a maximum of + * (max_sge - 3) entries. + * A quote from the OFED 1.2.5 release notes + * (docs/mthca_release_notes.txt), section "Known Issues": + * In mem-free devices, RC QPs can be created with a maximum of + * (max_sge - 3) entries only. + */ + isert_conn->max_sge = isert_dev->device_attr.max_sge - 3; + + WARN_ON(isert_conn->max_sge < 1); + INIT_LIST_HEAD(&isert_conn->rx_buf_list); INIT_LIST_HEAD(&isert_conn->tx_free_list); INIT_LIST_HEAD(&isert_conn->tx_busy_list);