diff mbox series

[40/40] scsi: iscsi_tcp: tell net layer we are sending multiple pdus

Message ID 20210403232333.212927-41-michael.christie@oracle.com
State New
Headers show
Series iscsi lock and refcount fix ups | expand

Commit Message

Mike Christie April 3, 2021, 11:23 p.m. UTC
If we are executing a multiple pdu sequence, tell the network layer we
will have more data.

This also sets MSG_MORE if the app batched cmds and we know we have more
than one that are going to be sent.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/iscsi_tcp.c | 16 +++++++++++-----
 drivers/scsi/libiscsi.c  | 10 ++++++++++
 include/scsi/libiscsi.h  |  1 +
 3 files changed, 22 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index eff5f8456ced..a85688d7ae2b 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -246,7 +246,8 @@  iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_conn *conn)
 /**
  * iscsi_sw_tcp_xmit_segment - transmit segment
  * @tcp_conn: the iSCSI TCP connection
- * @segment: the buffer to transmnit
+ * @task: iscsi task we are transmitting data for
+ * @segment: the buffer to transmit
  *
  * This function transmits as much of the buffer as
  * the network layer will accept, and returns the number of
@@ -257,6 +258,7 @@  iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_conn *conn)
  * it will retrieve the hash value and send it as well.
  */
 static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,
+				     struct iscsi_task *task,
 				     struct iscsi_segment *segment)
 {
 	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
@@ -273,7 +275,10 @@  static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,
 		offset = segment->copied;
 		copy = segment->size - offset;
 
-		if (segment->total_copied + segment->size < segment->total_size)
+		if (segment->total_copied + segment->size <
+		    segment->total_size ||
+		    !(task->hdr->flags & ISCSI_FLAG_CMD_FINAL) ||
+		    !iscsi_xmit_list_is_empty(tcp_conn->iscsi_conn))
 			flags |= MSG_MORE;
 
 		/* Use sendpage if we can; else fall back to sendmsg */
@@ -304,8 +309,9 @@  static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,
 /**
  * iscsi_sw_tcp_xmit - TCP transmit
  * @conn: iscsi connection
+ * @task: iscsi task to send data for
  **/
-static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
+static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn, struct iscsi_task *task)
 {
 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
 	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
@@ -314,7 +320,7 @@  static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
 	int rc = 0;
 
 	while (1) {
-		rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment);
+		rc = iscsi_sw_tcp_xmit_segment(tcp_conn, task, segment);
 		/*
 		 * We may not have been able to send data because the conn
 		 * is getting stopped. libiscsi will know so propagate err
@@ -382,7 +388,7 @@  static int iscsi_sw_tcp_pdu_xmit(struct iscsi_task *task)
 	noreclaim_flag = memalloc_noreclaim_save();
 
 	while (iscsi_sw_tcp_xmit_qlen(conn)) {
-		rc = iscsi_sw_tcp_xmit(conn);
+		rc = iscsi_sw_tcp_xmit(conn, task);
 		if (rc == 0) {
 			rc = -EAGAIN;
 			break;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index dd1e1963dd05..168afcb63bcf 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1609,6 +1609,16 @@  static bool iscsi_move_tasks(struct llist_head *submit_queue,
 	return !list_empty(exec_queue);
 }
 
+inline bool iscsi_xmit_list_is_empty(struct iscsi_conn *conn)
+{
+	if (!list_empty(&conn->cmd_exec_list) ||
+	    !list_empty(&conn->requeue_exec_list))
+		return false;
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(iscsi_xmit_list_is_empty);
+
 static void iscsi_move_all_tasks(struct iscsi_conn *conn)
 {
 	iscsi_move_tasks(&conn->requeue, &conn->requeue_exec_list);
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 12bdaee3b87e..f53f41f032d5 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -491,6 +491,7 @@  extern void iscsi_complete_scsi_task(struct iscsi_task *task,
 extern int iscsi_complete_task(struct iscsi_conn *conn, struct iscsi_task *task,
 			       struct iscsi_hdr *hdr, char *data, int datalen);
 extern int iscsi_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd);
+extern bool iscsi_xmit_list_is_empty(struct iscsi_conn *conn);
 
 struct iscsi_sc_iter_data {
 	struct iscsi_conn *conn;