[PATCH 02/40] scsi: libiscsi: fix write starvation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We currently handle R2Ts after handling new cmds. This can lead to
starving existing WRITEs waiting for R2T handling, if apps are sending
new cmds so quickly cmdqueue is never empty.

Signed-off-by: Mike Christie <michael.christie@xxxxxxxxxx>
---
 drivers/scsi/libiscsi.c | 53 ++++++++++++++++++++++++++---------------
 1 file changed, 34 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 04633e5157e9..643edc4eb6fe 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1525,7 +1525,7 @@ EXPORT_SYMBOL_GPL(iscsi_requeue_task);
 static int iscsi_data_xmit(struct iscsi_conn *conn)
 {
 	struct iscsi_task *task;
-	int rc = 0;
+	int rc = 0, cnt;
 
 	spin_lock_bh(&conn->session->frwd_lock);
 	if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) {
@@ -1562,7 +1562,30 @@ 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 */
+	cnt = 0;
 	while (!list_empty(&conn->cmdqueue)) {
 		task = list_entry(conn->cmdqueue.next, struct iscsi_task,
 				  running);
@@ -1589,28 +1612,20 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
 		 */
 		if (!list_empty(&conn->mgmtqueue))
 			goto check_mgmt;
-	}
-
-	while (!list_empty(&conn->requeue)) {
 		/*
-		 * we always do fastlogout - conn stop code will clean up.
+		 * Avoid starving the requeue list if new cmds keep coming in.
+		 * Incase the app tried to batch cmds to us, we allow up to
+		 * queueing limit.
 		 */
-		if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
-			break;
+		cnt++;
+		if (cnt == conn->session->host->cmd_per_lun) {
+			cnt = 0;
 
-		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;
+			if (!list_empty(&conn->requeue))
+				goto check_requeue;
+		}
 	}
+
 	spin_unlock_bh(&conn->session->frwd_lock);
 	return -ENODATA;
 
-- 
2.25.1




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux