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

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

 



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@xxxxxxxxxxxxx>
Signed-off-by: Chandra Seetharaman <sekharan@xxxxxxxxxx>

---
 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@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux