[PATCH 2/3] iser generating cmd batches using NOT_LAST bit

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

 



As iser accumulates received scsi commands on a list, scheduling an event which
processes the list, it is able to generate batches of commands submitted to scsi.

This patch uses NOT_LAST bit added to the cmd state to mark all commands in the
batch except the last one NOT_LAST=1. 

It also makes sure that the last command in batch is a regular one:
read/write/sync_cache. Other types of commands may be executed synchronously 
by the scsi engine, and if no commands arrive for some time, the backing store
which did not see the last command may stall submission of the previous commands.

Signed-off-by: Alexander Nezhinsky <alexandern@xxxxxxxxxxxx>
---
 usr/iscsi/iser.c |   22 ++++++++++++++--------
 1 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/usr/iscsi/iser.c b/usr/iscsi/iser.c
index 1c724e6..33112cd 100644
--- a/usr/iscsi/iser.c
+++ b/usr/iscsi/iser.c
@@ -1910,7 +1910,7 @@ static void iser_task_free_dout_tasks(struct iser_task *task)
 	}
 }
 
-static void iser_scsi_cmd_iosubmit(struct iser_task *task)
+static void iser_scsi_cmd_iosubmit(struct iser_task *task, int not_last)
 {
 	struct iscsi_cmd *req_bhs = (struct iscsi_cmd *) task->pdu.bhs;
 	struct scsi_cmd *scmd = &task->scmd;
@@ -1919,6 +1919,8 @@ static void iser_scsi_cmd_iosubmit(struct iser_task *task)
 	struct iser_membuf *data_buf;
 
 	scmd->state = 0;
+	if (not_last)
+		set_cmd_not_last(scmd);
 	scsi_set_in_length(scmd, 0);
 	scsi_set_out_length(scmd, 0);
 
@@ -2094,7 +2096,7 @@ static void iser_sched_buf_alloc(struct event_data *evt)
 	}
 }
 
-static inline int task_batch_type(struct iser_task *task)
+static inline int task_can_batch(struct iser_task *task)
 {
 	struct iscsi_cmd *req_bhs = (struct iscsi_cmd *) task->pdu.bhs;
 
@@ -2118,13 +2120,17 @@ static inline int task_batch_type(struct iser_task *task)
 static void iser_sched_iosubmit(struct event_data *evt)
 {
 	struct iser_conn *conn = (struct iser_conn *) evt->data;
-	struct iser_task *task = NULL;
+	struct iser_task *task, *next_task;
+	int last_in_batch;
 
-	while (!list_empty(&conn->iosubmit_list)) {
-		task = list_first_entry(&conn->iosubmit_list,
-					struct iser_task, exec_list);
+	list_for_each_entry_safe(task, next_task, &conn->iosubmit_list, exec_list) {
+		if (&next_task->exec_list == &conn->iosubmit_list)
+			last_in_batch = 1; /* end of list */
+		else
+			last_in_batch = (task_can_batch(task) &&
+					 task_can_batch(next_task)) ? 0 : 1;
 		list_del(&task->exec_list);
-		iser_scsi_cmd_iosubmit(task);
+		iser_scsi_cmd_iosubmit(task, !last_in_batch);
 	}
 }
 
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux