[stgt] [PATCH 10/12] Handle iscsi tcp events in target's thread

Chandra Seetharaman sekharan at us.ibm.com
Mon Sep 27 07:21:21 CEST 2010


Make iSCSI tcp handler aware of thread per target and make it use the
event handling loop of the target and avaoid using the main process'
event loop. Basically take this target's tcp load off of the main thread.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
Signed-off-by: Chandra Seetharaman <sekharan at us.ibm.com>

---
 usr/iscsi/iscsi_tcp.c |   51 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 46 insertions(+), 5 deletions(-)

Index: tgt-1.0.8.4/usr/iscsi/iscsi_tcp.c
===================================================================
--- tgt-1.0.8.4.orig/usr/iscsi/iscsi_tcp.c
+++ tgt-1.0.8.4/usr/iscsi/iscsi_tcp.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <pthread.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
@@ -43,6 +44,7 @@ static struct iscsi_transport iscsi_tcp;
 
 struct iscsi_tcp_connection {
 	int fd;
+	int pthread;
 
 	struct iscsi_connection iscsi_conn;
 };
@@ -153,6 +155,7 @@ out:
 static void iscsi_tcp_event_handler(int fd, int events, void *data)
 {
 	struct iscsi_connection *conn = (struct iscsi_connection *) data;
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
 
 	if (events & EPOLLIN)
 		iscsi_rx_handler(conn);
@@ -165,7 +168,19 @@ static void iscsi_tcp_event_handler(int 
 
 	if (conn->state == STATE_CLOSE) {
 		dprintf("connection closed %p\n", conn);
-		conn_close(conn);
+		if (tcp_conn->pthread) {
+			struct iscsi_target *target = conn->session->target;
+
+			pthread_mutex_lock(&target->event_lock);
+			do_tgt_event_del(target->efd, &target->events_list,
+					 tcp_conn->fd);
+			pthread_mutex_unlock(&target->event_lock);
+			/* let the main thread handle this */
+			tcp_conn->pthread = 0;
+			tgt_event_modify(tcp_conn->fd, EPOLLIN|EPOLLOUT|EPOLLERR);
+		} else {
+			conn_close(conn);
+		}
 	}
 }
 
@@ -265,7 +280,24 @@ static int iscsi_tcp_conn_login_complete
 
 static void iscsi_tcp_conn_nexus_init(struct iscsi_connection *conn)
 {
-	conn->tp->ep_event_modify(conn, EPOLLIN);
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
+	struct iscsi_target *target = conn->session->target;
+
+	if (iscsi_pthread_per_target()) {
+		/* remove the conn from the main thread. */
+		conn->tp->ep_event_modify(conn, 0);
+
+		tcp_conn->pthread = 1;
+
+		pthread_mutex_lock(&target->event_lock);
+
+		do_tgt_event_add(target->efd, &target->events_list,
+				 tcp_conn->fd, EPOLLIN,
+				 iscsi_tcp_event_handler, conn);
+
+		pthread_mutex_unlock(&target->event_lock);
+	} else
+		conn->tp->ep_event_modify(conn, EPOLLIN);
 }
 
 static size_t iscsi_tcp_read(struct iscsi_connection *conn, void *buf,
@@ -341,9 +373,18 @@ static void iscsi_event_modify(struct is
 	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
 	int ret;
 
-	ret = tgt_event_modify(tcp_conn->fd, events);
-	if (ret)
-		eprintf("tgt_event_modify failed\n");
+	if (tcp_conn->pthread) {
+		struct iscsi_target *target = conn->session->target;
+
+		pthread_mutex_lock(&target->event_lock);
+		do_tgt_event_modify(target->efd, &target->events_list,
+				    tcp_conn->fd, events);
+		pthread_mutex_unlock(&target->event_lock);
+	} else {
+		ret = tgt_event_modify(tcp_conn->fd, events);
+		if (ret)
+			eprintf("tgt_event_modify failed\n");
+	}
 }
 
 static struct iscsi_task *iscsi_tcp_alloc_task(struct iscsi_connection *conn,
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list