[Stgt-devel] [PATCH 5/6] iser iscsid changes

Pete Wyckoff pw
Mon Dec 10 16:06:01 CET 2007


Handle the special cases for RDMA in core iscsid code.  These changes
all look at conn->tp->rdma and do not affect TCP code.

    - track RDMA setting at session and verify conns are compatible
    - no status collapse on final data packet
    - all data-in transmits must reenable TX for conn
    - TX state machine finishes tasks without going through epoll
    - TX handler returns status to trigger RDMA flow control

Signed-off-by: Pete Wyckoff <pw at osc.edu>
---
 usr/iscsi/iscsid.c  |   45 ++++++++++++++++++++++++++++++++++-----------
 usr/iscsi/iscsid.h  |    5 ++++-
 usr/iscsi/session.c |    2 ++
 3 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
index df0fec4..b0c1b6d 100644
--- a/usr/iscsi/iscsid.c
+++ b/usr/iscsi/iscsid.c
@@ -511,8 +511,21 @@ static void login_finish(struct iscsi_connection *conn)
 			conn->state = STATE_EXIT;
 			break;
 		}
-		if (!conn->session)
+		if (!conn->session) {
 			session_create(conn);
+		} else {
+			if (conn->tp->rdma ^ conn->session->rdma) {
+				eprintf("new conn rdma %d, but session %d\n",
+					conn->tp->rdma, conn->session->rdma);
+				rsp->flags = 0;
+				rsp->status_class =
+					ISCSI_STATUS_CLS_INITIATOR_ERR;
+				rsp->status_detail =
+					ISCSI_LOGIN_STATUS_INVALID_REQUEST;
+				conn->state = STATE_EXIT;
+				break;
+			}
+		}
 		memcpy(conn->isid, conn->session->isid, sizeof(conn->isid));
 		conn->tsih = conn->session->tsih;
 		break;
@@ -965,7 +978,8 @@ static int iscsi_data_rsp_build(struct iscsi_task *task)
 
 		/* collapse status into final packet if successful */
 		if (result == SAM_STAT_GOOD &&
-		    scsi_get_data_dir(&task->scmd) != DATA_BIDIRECTIONAL) {
+		    scsi_get_data_dir(&task->scmd) != DATA_BIDIRECTIONAL &&
+		    !conn->tp->rdma) {
 			rsp->flags |= ISCSI_FLAG_DATA_STATUS;
 			rsp->cmd_status = result;
 			rsp->statsn = cpu_to_be32(conn->stat_sn++);
@@ -1720,8 +1734,9 @@ static int iscsi_scsi_cmd_tx_done(struct iscsi_connection *conn)
 		break;
 	case ISCSI_OP_SCSI_DATA_IN:
 		if (task->offset < task->len ||
-		    scsi_get_result(&task->scmd) != SAM_STAT_GOOD
-		    || scsi_get_data_dir(&task->scmd) == DATA_BIDIRECTIONAL) {
+		    scsi_get_result(&task->scmd) != SAM_STAT_GOOD ||
+		    scsi_get_data_dir(&task->scmd) == DATA_BIDIRECTIONAL ||
+		    conn->tp->rdma) {
 			dprintf("more data or sense or bidir %x\n", hdr->itt);
 			list_add_tail(&task->c_list, &task->conn->tx_clist);
 			return 0;
@@ -1996,7 +2011,7 @@ again:
 	return 0;
 }
 
-void iscsi_tx_handler(struct iscsi_connection *conn)
+int iscsi_tx_handler(struct iscsi_connection *conn)
 {
 	int ret = 0, hdigest, ddigest;
 	uint32_t crc;
@@ -2011,9 +2026,10 @@ void iscsi_tx_handler(struct iscsi_connection *conn)
 	if (conn->state == STATE_SCSI && !conn->tx_task) {
 		ret = iscsi_task_tx_start(conn);
 		if (ret)
-			return;
+			goto out;
 	}
 
+again:
 	switch (conn->tx_iostate) {
 	case IOSTATE_TX_BHS:
 		ret = do_send(conn, IOSTATE_TX_INIT_AHS);
@@ -2069,7 +2085,7 @@ void iscsi_tx_handler(struct iscsi_connection *conn)
 		ret = do_send(conn, ddigest ?
 			      IOSTATE_TX_INIT_DDIGEST : IOSTATE_TX_END);
 		if (ret < 0)
-			return;
+			goto out;
 		if (conn->tx_iostate != IOSTATE_TX_INIT_DDIGEST)
 			break;
 	case IOSTATE_TX_INIT_DDIGEST:
@@ -2089,10 +2105,14 @@ void iscsi_tx_handler(struct iscsi_connection *conn)
 		exit(1);
 	}
 
-	if (ret < 0 ||
-	    conn->tx_iostate != IOSTATE_TX_END ||
-	    conn->state == STATE_CLOSE)
-		return;
+	if (ret < 0 || conn->state == STATE_CLOSE)
+		goto out;
+
+	if (conn->tx_iostate != IOSTATE_TX_END) {
+		if (conn->tp->rdma)
+			goto again;  /* avoid event loop, just push */
+		goto out;
+	}
 
 	if (conn->tx_size) {
 		eprintf("error %d %d %d\n", conn->state, conn->tx_iostate,
@@ -2125,6 +2145,9 @@ void iscsi_tx_handler(struct iscsi_connection *conn)
 		conn->tp->ep_event_modify(conn, EPOLLIN);
 		break;
 	}
+
+out:
+	return ret;
 }
 
 static struct tgt_driver iscsi = {
diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
index 3fabfba..de681f7 100644
--- a/usr/iscsi/iscsid.h
+++ b/usr/iscsi/iscsid.h
@@ -91,6 +91,9 @@ struct iscsi_session {
 	struct param session_param[ISCSI_PARAM_MAX];
 
 	char *info;
+
+	/* if this session uses rdma connections */
+	int rdma;
 };
 
 struct iscsi_task {
@@ -258,7 +261,7 @@ extern void conn_add_to_session(struct iscsi_connection *conn, struct iscsi_sess
 extern char *text_key_find(struct iscsi_connection *conn, char *searchKey);
 extern void text_key_add(struct iscsi_connection *conn, char *key, char *value);
 extern void conn_read_pdu(struct iscsi_connection *conn);
-extern void iscsi_tx_handler(struct iscsi_connection *conn);
+extern int iscsi_tx_handler(struct iscsi_connection *conn);
 extern void iscsi_rx_handler(struct iscsi_connection *conn);
 extern int iscsi_scsi_cmd_execute(struct iscsi_task *task);
 
diff --git a/usr/iscsi/session.c b/usr/iscsi/session.c
index 3b1650d..028d538 100644
--- a/usr/iscsi/session.c
+++ b/usr/iscsi/session.c
@@ -128,6 +128,8 @@ int session_create(struct iscsi_connection *conn)
 	memcpy(session->isid, conn->isid, sizeof(session->isid));
 	session->tsih = last_tsih = tsih;
 
+	session->rdma = conn->tp->rdma;
+
 	conn_add_to_session(conn, session);
 
 	dprintf("session_create: %#" PRIx64 "\n", sid64(conn->isid, session->tsih));
-- 
1.5.3.4




More information about the stgt mailing list