@@ -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;
@@ -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);
@@ -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;
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(-)