lib/iscsi: Stop splitting immediately when aborting SCSI read I/O
We changed read I/O submission to stop splitting when detecting LUN hotplug very recently. We can do the same refinement for read I/O abortion. In _iscsi_conn_abort_queued_datain_task(), set all remaining length to the new task and complete it immediately. We keep the code to process the case that queued_datain_task completed but is still in queue, but we can change its if condition to assert. Simplify the corresponding unit tests accordingly, and set task->scsi.transfer_len in abort_queued_datain_tasks_test() to exercise the changed paths. In iscsi_pdu_payload_po_scsi_read(), if task->scsi.transfer_len is not larger than SPDK_BDEV_LARGE_BUF_MAX_SIZE, no minimum calculation is necessary and we can substitute task->scsi.transfer_len to task->scsi.length simply. This change is too small to be an independent patch and is done together. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: Iea93e51b103eae141a007a0abdaf13cbe6d5287f Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/476984 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
bed4cdf6c7
commit
19eb63fcad
@ -3260,7 +3260,7 @@ iscsi_pdu_payload_op_scsi_read(struct spdk_iscsi_conn *conn, struct spdk_iscsi_t
|
||||
if (task->scsi.transfer_len <= SPDK_BDEV_LARGE_BUF_MAX_SIZE) {
|
||||
task->parent = NULL;
|
||||
task->scsi.offset = 0;
|
||||
task->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, task->scsi.transfer_len);
|
||||
task->scsi.length = task->scsi.transfer_len;
|
||||
spdk_scsi_task_set_data(&task->scsi, NULL, 0);
|
||||
|
||||
iscsi_queue_task(conn, task);
|
||||
@ -3562,15 +3562,18 @@ _iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_iscsi_task *subtask;
|
||||
uint32_t remaining_size;
|
||||
|
||||
while (conn->data_in_cnt < MAX_LARGE_DATAIN_PER_CONNECTION) {
|
||||
if (conn->data_in_cnt >= MAX_LARGE_DATAIN_PER_CONNECTION) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(task->current_datain_offset <= task->scsi.transfer_len);
|
||||
/* If any IO is submitted already, abort all subtasks by repetition. */
|
||||
/* Stop split and abort read I/O for remaining data. */
|
||||
if (task->current_datain_offset < task->scsi.transfer_len) {
|
||||
remaining_size = task->scsi.transfer_len - task->current_datain_offset;
|
||||
subtask = spdk_iscsi_task_get(conn, task, spdk_iscsi_task_cpl);
|
||||
assert(subtask != NULL);
|
||||
subtask->scsi.offset = task->current_datain_offset;
|
||||
subtask->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size);
|
||||
subtask->scsi.length = remaining_size;
|
||||
spdk_scsi_task_set_data(&subtask->scsi, NULL, 0);
|
||||
task->current_datain_offset += subtask->scsi.length;
|
||||
|
||||
@ -3579,15 +3582,13 @@ _iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn,
|
||||
spdk_iscsi_task_cpl(&subtask->scsi);
|
||||
}
|
||||
|
||||
/* Remove the primary task from the list if this is the last subtask */
|
||||
if (task->current_datain_offset == task->scsi.transfer_len) {
|
||||
/* Remove the primary task from the list because all subtasks are submitted
|
||||
* or aborted.
|
||||
*/
|
||||
assert(task->current_datain_offset == task->scsi.transfer_len);
|
||||
TAILQ_REMOVE(&conn->queued_datain_tasks, task, link);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn,
|
||||
|
@ -1105,7 +1105,7 @@ static void
|
||||
abort_queued_datain_task_test(void)
|
||||
{
|
||||
struct spdk_iscsi_conn conn = {};
|
||||
struct spdk_iscsi_task *task, *task2, *task3;
|
||||
struct spdk_iscsi_task *task;
|
||||
int rc;
|
||||
|
||||
TAILQ_INIT(&conn.queued_datain_tasks);
|
||||
@ -1124,18 +1124,17 @@ abort_queued_datain_task_test(void)
|
||||
rc = _iscsi_conn_abort_queued_datain_task(&conn, task);
|
||||
CU_ASSERT(rc != 0);
|
||||
CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks));
|
||||
assert(conn.data_in_cnt == MAX_LARGE_DATAIN_PER_CONNECTION);
|
||||
|
||||
/* havs slots for sub read tasks */
|
||||
conn.data_in_cnt = 0;
|
||||
rc = _iscsi_conn_abort_queued_datain_task(&conn, task);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks));
|
||||
assert(conn.data_in_cnt == 0);
|
||||
CU_ASSERT(task->current_datain_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
|
||||
|
||||
/* Case2: Queue one task, and this task is partially executed,
|
||||
* and the slot of sub read tasks are full
|
||||
*/
|
||||
/* Case2: Queue one task, and this task is partially executed */
|
||||
|
||||
/* No slots for sub read tasks */
|
||||
conn.data_in_cnt = MAX_LARGE_DATAIN_PER_CONNECTION;
|
||||
task->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3;
|
||||
task->current_datain_offset = SPDK_BDEV_LARGE_BUF_MAX_SIZE;
|
||||
@ -1143,55 +1142,15 @@ abort_queued_datain_task_test(void)
|
||||
|
||||
rc = _iscsi_conn_abort_queued_datain_task(&conn, task);
|
||||
CU_ASSERT(rc != 0);
|
||||
CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks));
|
||||
|
||||
/* Case3: Queue one task, and this task is partially executed,
|
||||
* and the slot of sub read tasks is not full.
|
||||
*/
|
||||
conn.data_in_cnt = MAX_LARGE_DATAIN_PER_CONNECTION - 2;
|
||||
/* have slots for sub read tasks */
|
||||
conn.data_in_cnt = 0;
|
||||
rc = _iscsi_conn_abort_queued_datain_task(&conn, task);
|
||||
CU_ASSERT(rc == 0);
|
||||
assert(conn.data_in_cnt == MAX_LARGE_DATAIN_PER_CONNECTION - 2);
|
||||
CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks));
|
||||
|
||||
/* Case4: Queue three tasks and abort each task sequentially */
|
||||
conn.data_in_cnt = 0;
|
||||
|
||||
task->tag = 1;
|
||||
task->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3;
|
||||
task->current_datain_offset = 0;
|
||||
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task, link);
|
||||
|
||||
task2 = spdk_iscsi_task_get(&conn, NULL, NULL);
|
||||
SPDK_CU_ASSERT_FATAL(task2 != NULL);
|
||||
task2->tag = 2;
|
||||
task2->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV;
|
||||
task2->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 4;
|
||||
task2->current_datain_offset = SPDK_BDEV_LARGE_BUF_MAX_SIZE;
|
||||
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task2, link);
|
||||
|
||||
task3 = spdk_iscsi_task_get(&conn, NULL, NULL);
|
||||
SPDK_CU_ASSERT_FATAL(task3 != NULL);
|
||||
task3->tag = 3;
|
||||
task3->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV;
|
||||
task3->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 5;
|
||||
task3->current_datain_offset = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 2;
|
||||
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task3, link);
|
||||
|
||||
rc = iscsi_conn_abort_queued_datain_task(&conn, 1);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = iscsi_conn_abort_queued_datain_task(&conn, 2);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = iscsi_conn_abort_queued_datain_task(&conn, 3);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks));
|
||||
assert(conn.data_in_cnt == 0);
|
||||
CU_ASSERT(task->current_datain_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
|
||||
|
||||
spdk_iscsi_task_cpl(&task->scsi);
|
||||
spdk_iscsi_task_cpl(&task2->scsi);
|
||||
spdk_iscsi_task_cpl(&task3->scsi);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -1233,6 +1192,7 @@ abort_queued_datain_tasks_test(void)
|
||||
pdu1->cmd_sn = alloc_cmd_sn;
|
||||
alloc_cmd_sn++;
|
||||
task1->current_datain_offset = 0;
|
||||
task1->scsi.transfer_len = 512;
|
||||
task1->scsi.lun = &lun1;
|
||||
spdk_iscsi_task_set_pdu(task1, pdu1);
|
||||
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task1, link);
|
||||
@ -1245,6 +1205,7 @@ abort_queued_datain_tasks_test(void)
|
||||
pdu2->cmd_sn = alloc_cmd_sn;
|
||||
alloc_cmd_sn++;
|
||||
task2->current_datain_offset = 0;
|
||||
task2->scsi.transfer_len = 512;
|
||||
task2->scsi.lun = &lun2;
|
||||
spdk_iscsi_task_set_pdu(task2, pdu2);
|
||||
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task2, link);
|
||||
@ -1263,6 +1224,7 @@ abort_queued_datain_tasks_test(void)
|
||||
pdu3->cmd_sn = alloc_cmd_sn;
|
||||
alloc_cmd_sn++;
|
||||
task3->current_datain_offset = 0;
|
||||
task3->scsi.transfer_len = 512;
|
||||
task3->scsi.lun = &lun1;
|
||||
spdk_iscsi_task_set_pdu(task3, pdu3);
|
||||
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task3, link);
|
||||
@ -1275,6 +1237,7 @@ abort_queued_datain_tasks_test(void)
|
||||
pdu4->cmd_sn = alloc_cmd_sn;
|
||||
alloc_cmd_sn++;
|
||||
task4->current_datain_offset = 0;
|
||||
task4->scsi.transfer_len = 512;
|
||||
task4->scsi.lun = &lun2;
|
||||
spdk_iscsi_task_set_pdu(task4, pdu4);
|
||||
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task4, link);
|
||||
@ -1287,6 +1250,7 @@ abort_queued_datain_tasks_test(void)
|
||||
pdu5->cmd_sn = alloc_cmd_sn;
|
||||
alloc_cmd_sn++;
|
||||
task5->current_datain_offset = 0;
|
||||
task5->scsi.transfer_len = 512;
|
||||
task5->scsi.lun = &lun1;
|
||||
spdk_iscsi_task_set_pdu(task5, pdu5);
|
||||
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task5, link);
|
||||
@ -1305,6 +1269,7 @@ abort_queued_datain_tasks_test(void)
|
||||
pdu6->cmd_sn = alloc_cmd_sn;
|
||||
alloc_cmd_sn++;
|
||||
task6->current_datain_offset = 0;
|
||||
task6->scsi.transfer_len = 512;
|
||||
task6->scsi.lun = &lun2;
|
||||
spdk_iscsi_task_set_pdu(task6, pdu6);
|
||||
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task6, link);
|
||||
|
Loading…
Reference in New Issue
Block a user