Commit 83a544c2 authored by Ziye Yang's avatar Ziye Yang Committed by Tomasz Zawadzki
Browse files

lib/iscsi: Support the Datain pdu sending in out of order case.



According to 12.19 in iSCSI 3720.
"If DataSequenceInOrder is set to No, Data PDU sequences may be
transferred in any order."

So if the DataSequence is negotiated with "No", then we can
send Datainpdu in out of order manner. And the initiator will
handle this case.

Signed-off-by: default avatarZiye Yang <ziye.yang@intel.com>
Change-Id: Ia15f56c606e4f97af019f91fa1118cc9cac5daa7
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5719


Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
parent 6238e1a2
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -1096,7 +1096,7 @@ iscsi_task_copy_from_rsp_scsi_status(struct spdk_scsi_task *task,
}

static void
process_completed_read_subtask_list(struct spdk_iscsi_conn *conn,
process_completed_read_subtask_list_in_order(struct spdk_iscsi_conn *conn,
		struct spdk_iscsi_task *primary)
{
	struct spdk_iscsi_task *subtask, *tmp;
@@ -1148,7 +1148,15 @@ process_read_task_completion(struct spdk_iscsi_conn *conn,
		assert(primary->bytes_completed == task->scsi.transfer_len);
		iscsi_task_response(conn, task);
		iscsi_task_put(task);
	} else if (!conn->sess->DataSequenceInOrder) {
		primary->bytes_completed += task->scsi.length;
		if (primary->bytes_completed == primary->scsi.transfer_len) {
			iscsi_task_put(primary);
		}
		iscsi_task_response(conn, task);
		iscsi_task_put(task);
	} else {

		if (task->scsi.offset != primary->bytes_completed) {
			TAILQ_FOREACH(tmp, &primary->subtask_list, subtask_link) {
				if (task->scsi.offset < tmp->scsi.offset) {
@@ -1160,7 +1168,7 @@ process_read_task_completion(struct spdk_iscsi_conn *conn,
			TAILQ_INSERT_TAIL(&primary->subtask_list, task, subtask_link);
		} else {
			TAILQ_INSERT_HEAD(&primary->subtask_list, task, subtask_link);
			process_completed_read_subtask_list(conn, primary);
			process_completed_read_subtask_list_in_order(conn, primary);
		}
	}
}
+33 −8
Original line number Diff line number Diff line
@@ -308,6 +308,11 @@ read_task_split_in_order_case(void)
{
	struct spdk_iscsi_task primary = {};
	struct spdk_iscsi_task *task, *tmp;
	struct spdk_iscsi_conn conn = {};
	struct spdk_iscsi_sess sess = {};

	conn.sess = &sess;
	conn.sess->DataSequenceInOrder = true;

	primary.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 8;
	TAILQ_INIT(&primary.subtask_list);
@@ -320,7 +325,7 @@ read_task_split_in_order_case(void)

	TAILQ_FOREACH(task, &g_ut_read_tasks, link) {
		CU_ASSERT(&primary == iscsi_task_get_primary(task));
		process_read_task_completion(NULL, task, &primary);
		process_read_task_completion(&conn, task, &primary);
	}

	CU_ASSERT(primary.bytes_completed == primary.scsi.transfer_len);
@@ -339,6 +344,11 @@ read_task_split_reverse_order_case(void)
{
	struct spdk_iscsi_task primary = {};
	struct spdk_iscsi_task *task, *tmp;
	struct spdk_iscsi_conn conn = {};
	struct spdk_iscsi_sess sess = {};

	conn.sess = &sess;
	conn.sess->DataSequenceInOrder = true;

	primary.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 8;
	TAILQ_INIT(&primary.subtask_list);
@@ -351,7 +361,7 @@ read_task_split_reverse_order_case(void)

	TAILQ_FOREACH_REVERSE(task, &g_ut_read_tasks, read_tasks_head, link) {
		CU_ASSERT(&primary == iscsi_task_get_primary(task));
		process_read_task_completion(NULL, task, &primary);
		process_read_task_completion(&conn, task, &primary);
	}

	CU_ASSERT(primary.bytes_completed == primary.scsi.transfer_len);
@@ -370,6 +380,12 @@ propagate_scsi_error_status_for_split_read_tasks(void)
	struct spdk_iscsi_task primary = {};
	struct spdk_iscsi_task task1 = {}, task2 = {}, task3 = {}, task4 = {}, task5 = {}, task6 = {};

	struct spdk_iscsi_conn conn = {};
	struct spdk_iscsi_sess sess = {};

	conn.sess = &sess;
	conn.sess->DataSequenceInOrder = true;

	primary.scsi.transfer_len = 512 * 6;
	primary.rsp_scsi_status = SPDK_SCSI_STATUS_GOOD;
	TAILQ_INIT(&primary.subtask_list);
@@ -415,12 +431,12 @@ propagate_scsi_error_status_for_split_read_tasks(void)
	 * status is propagated to remaining tasks correctly when these tasks complete
	 * by the following order, task4, task3, task2, task1, primary, task5, and task6.
	 */
	process_read_task_completion(NULL, &task4, &primary);
	process_read_task_completion(NULL, &task3, &primary);
	process_read_task_completion(NULL, &task2, &primary);
	process_read_task_completion(NULL, &task1, &primary);
	process_read_task_completion(NULL, &task5, &primary);
	process_read_task_completion(NULL, &task6, &primary);
	process_read_task_completion(&conn, &task4, &primary);
	process_read_task_completion(&conn, &task3, &primary);
	process_read_task_completion(&conn, &task2, &primary);
	process_read_task_completion(&conn, &task1, &primary);
	process_read_task_completion(&conn, &task5, &primary);
	process_read_task_completion(&conn, &task6, &primary);

	CU_ASSERT(primary.rsp_scsi_status == SPDK_SCSI_STATUS_CHECK_CONDITION);
	CU_ASSERT(task1.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
@@ -725,6 +741,11 @@ abort_queued_datain_task_test(void)
	struct iscsi_bhs_scsi_req *scsi_req;
	int rc;

	struct spdk_iscsi_sess sess = {};

	conn.sess = &sess;
	conn.sess->DataSequenceInOrder = true;

	TAILQ_INIT(&conn.queued_datain_tasks);
	task.scsi.ref = 1;
	task.scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV;
@@ -808,10 +829,14 @@ abort_queued_datain_tasks_test(void)
	uint32_t alloc_cmd_sn;
	struct iscsi_bhs_scsi_req *scsi_req;
	int rc;
	struct spdk_iscsi_sess sess = {};

	TAILQ_INIT(&conn.queued_datain_tasks);
	conn.data_in_cnt = 0;

	conn.sess = &sess;
	conn.sess->DataSequenceInOrder = true;

	g_new_task = &subtask;

	alloc_cmd_sn = 88;