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 |