Commit 65080c51 authored by Dmitry Bogdanov's avatar Dmitry Bogdanov Committed by Martin K. Petersen

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.comReviewed-by: default avatarKonstantin Shelekhin <k.shelekhin@yadro.com>
Reviewed-by: default avatarMike Christie <michael.christie@oracle.com>
Signed-off-by: default avatarDmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c0d93b12
......@@ -1567,6 +1567,28 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
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 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
*/
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment