[PATCH 10/29] target/iscsi: Refactor target_tx_thread response queue loop

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


Do not lock istate_lock except directly around i_state modifications.

Put entire ISTATE_SEND_DATAIN path within first switch statement, in prep
for further refactoring.

All other cases set use_misc = 1 and will not be using sendpage, so just
use send_tx_data for these and set use_misc param to 1.

map_sg, sent_status, use_misc, and se_cmd vars no longer needed.

Signed-off-by: Andy Grover <agrover@xxxxxxxxxx>
---
 drivers/target/iscsi/iscsi_target.c |  158 ++++++++++++++---------------------
 1 files changed, 63 insertions(+), 95 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 2f44af8..c0e839a 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -2433,10 +2433,19 @@ static int iscsit_send_conn_drop_async_message(
 	return 0;
 }
 
+static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn)
+{
+	if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
+	    (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
+		wait_for_completion_interruptible_timeout(
+					&conn->tx_half_close_comp,
+					ISCSI_TX_THREAD_TCP_TIMEOUT * HZ);
+	}
+}
+
 static int iscsit_send_data_in(
 	struct iscsi_cmd *cmd,
-	struct iscsi_conn *conn,
-	int *eodr)
+	struct iscsi_conn *conn)
 {
 	int iov_ret = 0, set_statsn = 0;
 	u32 iov_count = 0, tx_size = 0;
@@ -2444,6 +2453,8 @@ static int iscsit_send_data_in(
 	struct iscsi_datain_req *dr;
 	struct iscsi_data_rsp *hdr;
 	struct kvec *iov;
+	int eodr = 0;
+	int ret;
 
 	memset(&datain, 0, sizeof(struct iscsi_datain));
 	dr = iscsit_get_datain_values(cmd, &datain);
@@ -2576,13 +2587,26 @@ static int iscsit_send_data_in(
 		cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn),
 		ntohl(hdr->offset), datain.length, conn->cid);
 
+	/* sendpage is preferred but can't insert markers */
+	if (!conn->conn_ops->IFMarker)
+		ret = iscsit_fe_sendpage_sg(cmd, conn);
+	else
+		ret = iscsit_send_tx_data(cmd, conn, 0);
+
+	iscsit_unmap_iovec(cmd);
+
+	if (ret < 0) {
+		iscsit_tx_thread_wait_for_tcp(conn);
+		return ret;
+	}
+
 	if (dr->dr_complete) {
-		*eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ?
+		eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ?
 				2 : 1;
 		iscsit_free_datain_req(cmd, dr);
 	}
 
-	return 0;
+	return eodr;
 }
 
 static int iscsit_send_logout_response(
@@ -2704,16 +2728,6 @@ static int iscsit_send_logout_response(
 	return 0;
 }
 
-static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn)
-{
-	if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
-	    (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
-		wait_for_completion_interruptible_timeout(
-					&conn->tx_half_close_comp,
-					ISCSI_TX_THREAD_TCP_TIMEOUT * HZ);
-	}
-}
-
 /*
  *	Unsolicited NOPIN, either requesting a response or not.
  */
@@ -3497,11 +3511,7 @@ static inline void iscsit_thread_check_cpumask(
 int iscsi_target_tx_thread(void *arg)
 {
 	u8 state;
-	int eodr = 0;
 	int ret = 0;
-	int sent_status = 0;
-	int use_misc = 0;
-	int map_sg = 0;
 	struct iscsi_cmd *cmd = NULL;
 	struct iscsi_conn *conn;
 	struct iscsi_queue_req *qr = NULL;
@@ -3517,7 +3527,7 @@ restart:
 	if (!conn)
 		goto out;
 
-	eodr = map_sg = ret = sent_status = use_misc = 0;
+	ret = 0;
 
 	while (!kthread_should_stop()) {
 		/*
@@ -3581,45 +3591,50 @@ restart:
 			state = qr->state;
 			kmem_cache_free(lio_qr_cache, qr);
 
-			spin_lock_bh(&cmd->istate_lock);
 check_rsp_state:
 			switch (state) {
 			case ISTATE_SEND_DATAIN:
-				spin_unlock_bh(&cmd->istate_lock);
-				ret = iscsit_send_data_in(cmd, conn,
-							  &eodr);
-				map_sg = 1;
+				ret = iscsit_send_data_in(cmd, conn);
+				if (ret < 0)
+					goto transport_err;
+				else if (!ret)
+					/* more drs */
+					goto check_rsp_state;
+				else if (ret == 1) {
+					/* all done */
+					spin_lock_bh(&cmd->istate_lock);
+					cmd->i_state = ISTATE_SENT_STATUS;
+					spin_unlock_bh(&cmd->istate_lock);
+					continue;
+				} else if (ret == 2) {
+					/* Still must send status,
+					   SCF_TRANSPORT_TASK_SENSE was set */
+					spin_lock_bh(&cmd->istate_lock);
+					cmd->i_state = ISTATE_SEND_STATUS;
+					spin_unlock_bh(&cmd->istate_lock);
+					state = ISTATE_SEND_STATUS;
+					goto check_rsp_state;
+				}
+
 				break;
 			case ISTATE_SEND_STATUS:
 			case ISTATE_SEND_STATUS_RECOVERY:
-				spin_unlock_bh(&cmd->istate_lock);
-				use_misc = 1;
 				ret = iscsit_send_status(cmd, conn);
 				break;
 			case ISTATE_SEND_LOGOUTRSP:
-				spin_unlock_bh(&cmd->istate_lock);
-				use_misc = 1;
 				ret = iscsit_send_logout_response(cmd, conn);
 				break;
 			case ISTATE_SEND_ASYNCMSG:
-				spin_unlock_bh(&cmd->istate_lock);
-				use_misc = 1;
 				ret = iscsit_send_conn_drop_async_message(
 						cmd, conn);
 				break;
 			case ISTATE_SEND_NOPIN:
-				spin_unlock_bh(&cmd->istate_lock);
-				use_misc = 1;
 				ret = iscsit_send_nopin_response(cmd, conn);
 				break;
 			case ISTATE_SEND_REJECT:
-				spin_unlock_bh(&cmd->istate_lock);
-				use_misc = 1;
 				ret = iscsit_send_reject(cmd, conn);
 				break;
 			case ISTATE_SEND_TASKMGTRSP:
-				spin_unlock_bh(&cmd->istate_lock);
-				use_misc = 1;
 				ret = iscsit_send_task_mgt_rsp(cmd, conn);
 				if (ret != 0)
 					break;
@@ -3628,8 +3643,6 @@ check_rsp_state:
 					iscsit_fall_back_to_erl0(conn->sess);
 				break;
 			case ISTATE_SEND_TEXTRSP:
-				spin_unlock_bh(&cmd->istate_lock);
-				use_misc = 1;
 				ret = iscsit_send_text_rsp(cmd, conn);
 				break;
 			default:
@@ -3637,94 +3650,49 @@ check_rsp_state:
 					" 0x%08x, i_state: %d on CID: %hu\n",
 					cmd->iscsi_opcode, cmd->init_task_tag,
 					state, conn->cid);
-				spin_unlock_bh(&cmd->istate_lock);
 				goto transport_err;
 			}
 			if (ret < 0)
 				goto transport_err;
 
-			if (map_sg && !conn->conn_ops->IFMarker) {
-				if (iscsit_fe_sendpage_sg(cmd, conn) < 0) {
-					iscsit_tx_thread_wait_for_tcp(conn);
-					iscsit_unmap_iovec(cmd);
-					goto transport_err;
-				}
-			} else {
-				if (iscsit_send_tx_data(cmd, conn, use_misc) < 0) {
-					iscsit_tx_thread_wait_for_tcp(conn);
-					iscsit_unmap_iovec(cmd);
-					goto transport_err;
-				}
+			if (iscsit_send_tx_data(cmd, conn, 1) < 0) {
+				iscsit_tx_thread_wait_for_tcp(conn);
+				iscsit_unmap_iovec(cmd);
+				goto transport_err;
 			}
-			map_sg = 0;
 			iscsit_unmap_iovec(cmd);
 
-			spin_lock_bh(&cmd->istate_lock);
 			switch (state) {
-			case ISTATE_SEND_DATAIN:
-				if (!eodr)
-					goto check_rsp_state;
-
-				if (eodr == 1) {
-					cmd->i_state = ISTATE_SENT_LAST_DATAIN;
-					sent_status = 1;
-					eodr = use_misc = 0;
-				} else if (eodr == 2) {
-					cmd->i_state = state =
-							ISTATE_SEND_STATUS;
-					sent_status = 0;
-					eodr = use_misc = 0;
-					goto check_rsp_state;
-				}
-				break;
+			case ISTATE_SEND_LOGOUTRSP:
+				if (!iscsit_logout_post_handler(cmd, conn))
+					goto restart;
+				/* fall through */
 			case ISTATE_SEND_STATUS:
-				use_misc = 0;
-				sent_status = 1;
-				break;
 			case ISTATE_SEND_ASYNCMSG:
 			case ISTATE_SEND_NOPIN:
 			case ISTATE_SEND_STATUS_RECOVERY:
 			case ISTATE_SEND_TEXTRSP:
-				use_misc = 0;
-				sent_status = 1;
+			case ISTATE_SEND_TASKMGTRSP:
+				spin_lock_bh(&cmd->istate_lock);
+				cmd->i_state = ISTATE_SENT_STATUS;
+				spin_unlock_bh(&cmd->istate_lock);
 				break;
 			case ISTATE_SEND_REJECT:
-				use_misc = 0;
 				if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) {
 					cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN;
-					spin_unlock_bh(&cmd->istate_lock);
 					complete(&cmd->reject_comp);
 					goto transport_err;
 				}
 				complete(&cmd->reject_comp);
 				break;
-			case ISTATE_SEND_TASKMGTRSP:
-				use_misc = 0;
-				sent_status = 1;
-				break;
-			case ISTATE_SEND_LOGOUTRSP:
-				spin_unlock_bh(&cmd->istate_lock);
-				if (!iscsit_logout_post_handler(cmd, conn))
-					goto restart;
-				spin_lock_bh(&cmd->istate_lock);
-				use_misc = 0;
-				sent_status = 1;
-				break;
 			default:
 				pr_err("Unknown Opcode: 0x%02x ITT:"
 					" 0x%08x, i_state: %d on CID: %hu\n",
 					cmd->iscsi_opcode, cmd->init_task_tag,
 					cmd->i_state, conn->cid);
-				spin_unlock_bh(&cmd->istate_lock);
 				goto transport_err;
 			}
 
-			if (sent_status) {
-				cmd->i_state = ISTATE_SENT_STATUS;
-				sent_status = 0;
-			}
-			spin_unlock_bh(&cmd->istate_lock);
-
 			if (atomic_read(&conn->check_immediate_queue))
 				break;
 		}
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Photos]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

Add to Google Powered by Linux