iscsi: optimization of large read process.

This patch move the spdk_iscsi_conn_handle_queued_tasks() to the main
loop of connection poller, make the logic more clear, it will also fix
one issue of hotplug:
for large read command, it has the potential risk:
one task will be split into N subtaks, when primary task return error and
try to send data in pdu, it will call spdk_iscsi_conn_handle_queued_tasks(),
the primary task is pending now, and all the subtasks will return error from
lun layer synchronous, this make the primary task return from the function
spdk_iscsi_transfer_in() after all the other subtaks, but when the N - 1 subtask
return from function spdk_iscsi_transfer_in(), it meet the condition:
primary->bytes_completed == primary->scsi.transfer_len
then it will send response pdu, after this, the primary task return from
spdk_iscsi_transfer_in(), it also meet the condition, so it will also try
to send response pdu, this will make the application run into error.

Change-Id: I72206c1ce303f5fb6bd650713742d5819a88a30f
Signed-off-by: Cunyin Chang <cunyin.chang@intel.com>
Reviewed-on: https://review.gerrithub.io/370339
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Cunyin Chang 2017-07-19 22:26:03 +08:00 committed by Daniel Verkamp
parent 8c3fadc282
commit 40b74cd343
2 changed files with 2 additions and 3 deletions

View File

@ -416,7 +416,6 @@ spdk_iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pd
conn->data_in_cnt--;
spdk_iscsi_task_put(spdk_iscsi_task_get_primary(pdu->task));
}
spdk_iscsi_conn_handle_queued_tasks(conn);
}
} else if (pdu->bhs.opcode == ISCSI_OP_SCSI_RSP &&
pdu->task->scsi.status != SPDK_SCSI_STATUS_GOOD) {
@ -1261,6 +1260,8 @@ spdk_iscsi_conn_execute(struct spdk_iscsi_conn *conn)
}
}
spdk_iscsi_conn_handle_queued_tasks(conn);
if (conn_active) {
return 1;
}

View File

@ -2722,12 +2722,10 @@ spdk_iscsi_transfer_in(struct spdk_iscsi_conn *conn,
if (task->scsi.status != SPDK_SCSI_STATUS_GOOD) {
if (task != primary) {
conn->data_in_cnt--;
spdk_iscsi_conn_handle_queued_tasks(conn);
} else {
/* handle the case that it is a primary task which has subtasks */
if (primary->scsi.transfer_len != task->scsi.length) {
conn->data_in_cnt--;
spdk_iscsi_conn_handle_queued_tasks(conn);
}
}