scsi: iscsi: Prefer xmit of DataOut over new commands

iscsi_data_xmit() (TX worker) is iterating over the queue of new SCSI
commands concurrently with the queue being replenished. Only after the
queue is emptied will we start sending pending DataOut PDUs. That leads to
DataOut timeout on the target side and to connection reinstatement.

Give priority to pending DataOut commands over new commands.

Link: https://lore.kernel.org/r/20220607131953.11584-1-d.bogdanov@yadro.com
Reviewed-by: Konstantin Shelekhin <k.shelekhin@yadro.com>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Dmitry Bogdanov 2022-06-07 16:19:53 +03:00 committed by Martin K. Petersen
parent c0d93b12f3
commit 65080c51fd

View File

@ -1567,6 +1567,28 @@ check_mgmt:
goto done;
}
check_requeue:
while (!list_empty(&conn->requeue)) {
/*
* we always do fastlogout - conn stop code will clean up.
*/
if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
break;
task = list_entry(conn->requeue.next, struct iscsi_task,
running);
if (iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_DATA_OUT))
break;
list_del_init(&task->running);
rc = iscsi_xmit_task(conn, task, true);
if (rc)
goto done;
if (!list_empty(&conn->mgmtqueue))
goto check_mgmt;
}
/* process pending command queue */
while (!list_empty(&conn->cmdqueue)) {
task = list_entry(conn->cmdqueue.next, struct iscsi_task,
@ -1594,28 +1616,10 @@ check_mgmt:
*/
if (!list_empty(&conn->mgmtqueue))
goto check_mgmt;
if (!list_empty(&conn->requeue))
goto check_requeue;
}
while (!list_empty(&conn->requeue)) {
/*
* we always do fastlogout - conn stop code will clean up.
*/
if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
break;
task = list_entry(conn->requeue.next, struct iscsi_task,
running);
if (iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_DATA_OUT))
break;
list_del_init(&task->running);
rc = iscsi_xmit_task(conn, task, true);
if (rc)
goto done;
if (!list_empty(&conn->mgmtqueue))
goto check_mgmt;
}
spin_unlock_bh(&conn->session->frwd_lock);
return -ENODATA;