From dadbf52dda68efda20e6c79890892d4791b10c11 Mon Sep 17 00:00:00 2001 From: Cunyin Chang Date: Sat, 3 Sep 2016 18:02:38 +0800 Subject: [PATCH] iscsi: optimization for read command. flush the data in pdu to client if the pdu are ready and sequential. Change-Id: Idf0ec0c7f6058790a85407dff324900fd36c9527 Signed-off-by: Cunyin Chang --- lib/iscsi/conn.c | 65 ++++++++++++++++++++++++++++++++--------------- lib/iscsi/iscsi.c | 25 ------------------ 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index 75faf2c2a..961160635 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -781,16 +781,43 @@ process_task_mgmt_completion(spdk_event_t event) spdk_iscsi_task_put(task); } +static void +process_completed_read_subtask_list(struct spdk_iscsi_conn *conn, + struct spdk_iscsi_task *primary) +{ + struct spdk_scsi_task *tmp; + + while (!TAILQ_EMPTY(&primary->scsi.subtask_list)) { + tmp = TAILQ_FIRST(&primary->scsi.subtask_list); + if (tmp->offset == primary->scsi.bytes_completed) { + TAILQ_REMOVE(&primary->scsi.subtask_list, tmp, scsi_link); + primary->scsi.bytes_completed += tmp->length; + spdk_iscsi_task_response(conn, (struct spdk_iscsi_task *)tmp); + spdk_iscsi_task_put((struct spdk_iscsi_task *)tmp); + } else { + break; + } + } + +} + static void process_read_task_completion(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task) { struct spdk_iscsi_task *primary; - struct spdk_scsi_task *tmp, *tmp1; + struct spdk_scsi_task *tmp; bool flag = false; primary = spdk_iscsi_task_get_primary(task); if (task != primary) { + if (task->scsi.offset == primary->scsi.bytes_completed) { + primary->scsi.bytes_completed += task->scsi.length; + spdk_iscsi_task_response(conn, task); + spdk_iscsi_task_put(task); + process_completed_read_subtask_list(conn, primary); + return; + } TAILQ_FOREACH(tmp, &primary->scsi.subtask_list, scsi_link) { if (task->scsi.offset < tmp->offset) { TAILQ_INSERT_BEFORE(tmp, &task->scsi, scsi_link); @@ -798,22 +825,13 @@ process_read_task_completion(struct spdk_iscsi_conn *conn, break; } } - if (!flag) + if (!flag) { TAILQ_INSERT_TAIL(&primary->scsi.subtask_list, &task->scsi, scsi_link); - } - - if (primary->scsi.bytes_completed != primary->scsi.transfer_len) - return; - - /* reset this value to 0 */ - primary->scsi.bytes_completed = 0; - spdk_iscsi_task_response(conn, primary); - spdk_iscsi_task_put(primary); - - TAILQ_FOREACH_SAFE(tmp, &primary->scsi.subtask_list, scsi_link, tmp1) { - TAILQ_REMOVE(&primary->scsi.subtask_list, tmp, scsi_link); - spdk_iscsi_task_response(conn, (struct spdk_iscsi_task *)tmp); - spdk_iscsi_task_put((struct spdk_iscsi_task *)tmp); + } + } else { + primary->scsi.bytes_completed += primary->scsi.length; + spdk_iscsi_task_response(conn, primary); + process_completed_read_subtask_list(conn, primary); } } @@ -828,13 +846,12 @@ void process_task_completion(spdk_event_t event) conn->last_activity_tsc = rte_get_timer_cycles(); primary = spdk_iscsi_task_get_primary(task); - primary->scsi.bytes_completed += task->scsi.length; if (spdk_iscsi_task_is_read(primary)) { process_read_task_completion(conn, task); return; } else { - + primary->scsi.bytes_completed += task->scsi.length; if (task->scsi.parent != NULL && task->scsi.status != SPDK_SCSI_STATUS_GOOD) { memcpy(primary->scsi.sense_data, task->scsi.sense_data, task->scsi.sense_data_len); @@ -1016,8 +1033,16 @@ spdk_iscsi_conn_flush_pdus_internal(struct spdk_iscsi_conn *conn) tailq); } else { if (pdu->task) { - if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN && pdu->task->scsi.offset > 0) { - conn->data_in_cnt--; + if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) { + struct spdk_iscsi_task *primary; + + primary = spdk_iscsi_task_get_primary(pdu->task); + if (pdu->task->scsi.offset > 0) { + conn->data_in_cnt--; + } + if (pdu->bhs.flags & ISCSI_DATAIN_STATUS) { + spdk_iscsi_task_put(primary); + } spdk_iscsi_conn_handle_queued_datain(conn); } spdk_iscsi_task_put(pdu->task); diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index b53dc9174..9d5dbca46 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -2846,19 +2846,6 @@ static void spdk_iscsi_queue_mgmt_task(struct spdk_iscsi_conn *conn, spdk_scsi_dev_queue_mgmt_task(conn->dev, &task->scsi); } -static int spdk_iscsi_get_extra_data_in_count(struct spdk_iscsi_task *task) -{ - uint32_t transfer_len; - size_t segment_len; - int data_in_req = 0; - - transfer_len = task->scsi.transfer_len; - segment_len = g_spdk_iscsi.MaxRecvDataSegmentLength; - if (transfer_len) - data_in_req = (transfer_len - 1) / segment_len; - return data_in_req; -} - int spdk_iscsi_conn_handle_queued_datain(struct spdk_iscsi_conn *conn) { struct spdk_iscsi_task *task; @@ -2892,19 +2879,8 @@ int spdk_iscsi_conn_handle_queued_datain(struct spdk_iscsi_conn *conn) static int spdk_iscsi_op_scsi_read(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task) { - int extra_data_in_count; int32_t remaining_size = 0; - extra_data_in_count = spdk_iscsi_get_extra_data_in_count(task); - if (extra_data_in_count > MAX_EXTRA_DATAIN_PER_CONNECTION) { - SPDK_ERRLOG("Unsupported read size\n"); - spdk_scsi_task_set_check_condition(&task->scsi, SPDK_SCSI_SENSE_ILLEGAL_REQUEST, 0x25, 0x00); - task->scsi.bytes_completed = task->scsi.transfer_len; - spdk_iscsi_task_response(conn, task); - spdk_iscsi_task_put(task); - return 0; - } - TAILQ_INIT(&task->scsi.subtask_list); task->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV; task->scsi.parent = NULL; @@ -3134,7 +3110,6 @@ void spdk_iscsi_task_response(struct spdk_iscsi_conn *conn, /* transfer data from logical unit */ /* (direction is view of initiator side) */ if (spdk_iscsi_task_is_read(primary)) { - primary->scsi.bytes_completed += task->scsi.length; if ((task->scsi.status == SPDK_SCSI_STATUS_GOOD) || (task->scsi.sense_data_len != 0)) { rc = spdk_iscsi_transfer_in(conn, task);