]> git.baikalelectronics.ru Git - kernel.git/commitdiff
scsi: iscsi: Prefer xmit of DataOut over new commands
authorDmitry Bogdanov <d.bogdanov@yadro.com>
Tue, 7 Jun 2022 13:19:53 +0000 (16:19 +0300)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 17 Jun 2022 01:53:39 +0000 (21:53 -0400)
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>
drivers/scsi/libiscsi.c

index 797abf4f53995a124c0c48b586f93f9feb505d25..8d78559ae94a2b9aefb5e84911bfbf489b40dc42 100644 (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;