iscsi: Clear R2T tasks after completing SCSI layer in task management request
Current immediate calls of clear_all_transfer_task() and del_transfer_task() will cause unexpected behavior during heavy workload which cause repeated reset operation. Observed behavior is similar to Github issue #457. Change-Id: Ide2b05bff8300872881c8b039f7a62af48d16cfd Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/434760 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Ziye Yang <optimistyzy@gmail.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
187e2dfbbf
commit
f550dbe893
@ -2969,6 +2969,37 @@ spdk_iscsi_op_scsi(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_abort_transfer_task_in_task_mgmt_resp(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_iscsi_task *task)
|
||||
{
|
||||
struct iscsi_bhs_task_req *reqh;
|
||||
struct spdk_iscsi_pdu *pdu;
|
||||
uint32_t ref_task_tag;
|
||||
uint8_t function;
|
||||
|
||||
pdu = spdk_iscsi_task_get_pdu(task);
|
||||
reqh = (struct iscsi_bhs_task_req *)&pdu->bhs;
|
||||
function = reqh->flags & ISCSI_TASK_FUNCTION_MASK;
|
||||
ref_task_tag = from_be32(&reqh->ref_task_tag);
|
||||
|
||||
switch (function) {
|
||||
/* abort task identified by Reference Task Tag field */
|
||||
case ISCSI_TASK_FUNC_ABORT_TASK:
|
||||
spdk_del_transfer_task(conn, ref_task_tag);
|
||||
break;
|
||||
|
||||
/* abort all tasks issued via this session on the LUN */
|
||||
case ISCSI_TASK_FUNC_ABORT_TASK_SET:
|
||||
spdk_clear_all_transfer_task(conn, task->scsi.lun);
|
||||
break;
|
||||
|
||||
case ISCSI_TASK_FUNC_LOGICAL_UNIT_RESET:
|
||||
spdk_clear_all_transfer_task(conn, task->scsi.lun);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
spdk_iscsi_task_mgmt_response(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_iscsi_task *task)
|
||||
@ -2993,9 +3024,11 @@ spdk_iscsi_task_mgmt_response(struct spdk_iscsi_conn *conn,
|
||||
rsph->flags |= 0x80; /* bit 0 default to 1 */
|
||||
switch (task->scsi.response) {
|
||||
case SPDK_SCSI_TASK_MGMT_RESP_COMPLETE:
|
||||
spdk_abort_transfer_task_in_task_mgmt_resp(conn, task);
|
||||
rsph->response = ISCSI_TASK_FUNC_RESP_COMPLETE;
|
||||
break;
|
||||
case SPDK_SCSI_TASK_MGMT_RESP_SUCCESS:
|
||||
spdk_abort_transfer_task_in_task_mgmt_resp(conn, task);
|
||||
rsph->response = ISCSI_TASK_FUNC_RESP_COMPLETE;
|
||||
break;
|
||||
case SPDK_SCSI_TASK_MGMT_RESP_REJECT:
|
||||
@ -3196,7 +3229,6 @@ spdk_iscsi_op_task(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
task->scsi.abort_id = ref_task_tag;
|
||||
|
||||
spdk_iscsi_queue_mgmt_task(conn, task, SPDK_SCSI_TASK_FUNC_ABORT_TASK);
|
||||
spdk_del_transfer_task(conn, ref_task_tag);
|
||||
|
||||
return SPDK_SUCCESS;
|
||||
|
||||
@ -3205,7 +3237,6 @@ spdk_iscsi_op_task(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
SPDK_NOTICELOG("ABORT_TASK_SET\n");
|
||||
|
||||
spdk_iscsi_queue_mgmt_task(conn, task, SPDK_SCSI_TASK_FUNC_ABORT_TASK_SET);
|
||||
spdk_clear_all_transfer_task(conn, task->scsi.lun);
|
||||
|
||||
return SPDK_SUCCESS;
|
||||
|
||||
@ -3223,7 +3254,7 @@ spdk_iscsi_op_task(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
SPDK_NOTICELOG("LOGICAL_UNIT_RESET\n");
|
||||
|
||||
spdk_iscsi_queue_mgmt_task(conn, task, SPDK_SCSI_TASK_FUNC_LUN_RESET);
|
||||
spdk_clear_all_transfer_task(conn, task->scsi.lun);
|
||||
|
||||
return SPDK_SUCCESS;
|
||||
|
||||
case ISCSI_TASK_FUNC_TARGET_WARM_RESET:
|
||||
|
Loading…
x
Reference in New Issue
Block a user