From 2b9b097c35120b54dd5e5f0d4031823b8209a03b Mon Sep 17 00:00:00 2001 From: wanghonghao Date: Mon, 9 Dec 2019 22:43:06 +0800 Subject: [PATCH 1/2] iser: use `login_resp_buf` until login is finished This commit is to fix compatibility with CHAP. iSER transport only post `login_resp_buf` (which is larger than `rx_desc`) as work request (WR) once, but there may be multiple requests and responses during login phase (e.g. when CHAP is used) and login can't be finished in such cases. Signed-off-by: wanghonghao --- lib/iser.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/iser.c b/lib/iser.c index bf83c92..9dc5711 100644 --- a/lib/iser.c +++ b/lib/iser.c @@ -729,15 +729,6 @@ iser_send_control(struct iser_conn *iser_conn, struct iser_pdu *iser_pdu) { tx_desc->num_sge = 2; } - if (iser_pdu->iscsi_pdu.response_opcode == ISCSI_PDU_LOGIN_RESPONSE || - iscsi->session_type == ISCSI_SESSION_DISCOVERY) { - ret = iser_post_recvl(iser_conn); - if (ret) { - iscsi_set_error(iscsi, "Failed Post Recv login"); - return -1; - } - } - ret = iser_post_send(iser_conn, tx_desc, true); if (ret) { iscsi_set_error(iscsi, "Failed to post send"); @@ -1331,19 +1322,6 @@ iser_rcv_completion(struct iser_rx_desc *rx_desc, in = iscsi_malloc(iscsi, sizeof(*in)); - if ((unsigned char *)rx_desc == iser_conn->login_resp_buf) - if (iscsi->session_type == ISCSI_SESSION_NORMAL) { - if(iser_alloc_rx_descriptors(iser_conn,255)) { - iscsi_set_error(iscsi, "iser_alloc_rx_descriptors Failed\n"); - err = -1; - goto error; - } - err = iser_post_recvm(iser_conn, ISER_MIN_POSTED_RX); - if (err) { - err = -1; - goto error; - } - } in->hdr = (unsigned char*)rx_desc->iscsi_header; in->data_pos = iscsi_get_pdu_data_size(&in->hdr[0]); in->data = (unsigned char*)rx_desc->data; @@ -1401,6 +1379,23 @@ nop_target: goto error; } } + } else if (iscsi->is_loggedin) { + if(iser_alloc_rx_descriptors(iser_conn, 255)) { + iscsi_set_error(iscsi, "iser_alloc_rx_descriptors Failed\n"); + err = -1; + goto error; + } + err = iser_post_recvm(iser_conn, ISER_MIN_POSTED_RX); + if (err) { + err = -1; + goto error; + } + } else { + if (iser_post_recvl(iser_conn)) { + iscsi_set_error(iscsi, "Failed Post Recv login"); + err = -1; + goto error; + } } err = iscsi_process_pdu(iscsi, in); @@ -1559,6 +1554,11 @@ static int iser_connected_handler(struct rdma_cm_id *cma_id) { iser_conn->post_recv_buf_count = 0; iscsi->is_connected = 1; + if (iser_post_recvl(iser_conn)) { + iscsi_set_error(iscsi, "Failed Post Recv login"); + return -1; + } + return 0; } From a22a9bb7dbea1887a2d49333698c1ec2494ba666 Mon Sep 17 00:00:00 2001 From: wanghonghao Date: Tue, 14 Apr 2020 18:02:36 +0800 Subject: [PATCH 2/2] iser: eliminate unnecessary memory allocations Allocate `iser_pdu` from small allocation pool. Lifecycle of `iscsi_in_pdu` is inside the function in iSER transport. Allocate it on stack. Signed-off-by: wanghonghao --- lib/iser.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/lib/iser.c b/lib/iser.c index 9dc5711..3978306 100644 --- a/lib/iser.c +++ b/lib/iser.c @@ -553,7 +553,7 @@ iscsi_iser_new_pdu(struct iscsi_context *iscsi, __attribute__((unused))size_t si struct iscsi_pdu *pdu; struct iser_pdu *iser_pdu; - iser_pdu = iscsi_zmalloc(iscsi, sizeof(*iser_pdu)); + iser_pdu = iscsi_szmalloc(iscsi, sizeof(*iser_pdu)); pdu = &iser_pdu->iscsi_pdu; pdu->indata.data = NULL; @@ -596,7 +596,7 @@ iscsi_iser_free_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) iscsi->outqueue_current = NULL; } - iscsi_free(iscsi, iser_pdu); + iscsi_sfree(iscsi, iser_pdu); } /** @@ -1316,18 +1316,16 @@ static int iser_rcv_completion(struct iser_rx_desc *rx_desc, struct iser_conn *iser_conn) { - struct iscsi_in_pdu *in = NULL; + struct iscsi_in_pdu in; int empty, err; struct iscsi_context *iscsi = iser_conn->cma_id->context; - in = iscsi_malloc(iscsi, sizeof(*in)); + in.hdr = (unsigned char*)rx_desc->iscsi_header; + in.data_pos = iscsi_get_pdu_data_size(&in.hdr[0]); + in.data = (unsigned char*)rx_desc->data; - in->hdr = (unsigned char*)rx_desc->iscsi_header; - in->data_pos = iscsi_get_pdu_data_size(&in->hdr[0]); - in->data = (unsigned char*)rx_desc->data; - - enum iscsi_opcode opcode = in->hdr[0] & 0x3f; - uint32_t itt = scsi_get_uint32(&in->hdr[16]); + enum iscsi_opcode opcode = in.hdr[0] & 0x3f; + uint32_t itt = scsi_get_uint32(&in.hdr[16]); if (opcode == ISCSI_PDU_NOP_IN && itt == 0xffffffff) goto nop_target; @@ -1375,34 +1373,26 @@ nop_target: if (empty >= iser_conn->min_posted_rx) { err = iser_post_recvm(iser_conn, empty); if (err) { - err = -1; - goto error; + return -1; } } } else if (iscsi->is_loggedin) { if(iser_alloc_rx_descriptors(iser_conn, 255)) { iscsi_set_error(iscsi, "iser_alloc_rx_descriptors Failed\n"); - err = -1; - goto error; + return -1; } err = iser_post_recvm(iser_conn, ISER_MIN_POSTED_RX); if (err) { - err = -1; - goto error; + return -1; } } else { if (iser_post_recvl(iser_conn)) { iscsi_set_error(iscsi, "Failed Post Recv login"); - err = -1; - goto error; + return -1; } } - err = iscsi_process_pdu(iscsi, in); - -error: - iscsi_free(iscsi, in); - return err; + return iscsi_process_pdu(iscsi, &in); } /** @@ -1749,6 +1739,11 @@ void iscsi_init_iser_transport(struct iscsi_context *iscsi) /* Update iSCSI params as per iSER transport */ iscsi->initiator_max_recv_data_segment_length = ISCSI_DEF_MAX_RECV_SEG_LEN; iscsi->target_max_recv_data_segment_length = ISCSI_DEF_MAX_RECV_SEG_LEN; + + /* ensure smalloc_size is enough for iser_pdu */ + while (iscsi->smalloc_size < sizeof(struct iser_pdu)) { + iscsi->smalloc_size <<= 1; + } } #endif