diff --git a/0018-preload-support-thread-hijacking-mode.patch b/0018-preload-support-thread-hijacking-mode.patch new file mode 100644 index 0000000..fe75ba7 --- /dev/null +++ b/0018-preload-support-thread-hijacking-mode.patch @@ -0,0 +1,646 @@ +From 7c6d623f4009ec40349504281b9af396d05418ec Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 9 Oct 2023 11:36:34 +0800 +Subject: [PATCH] preload: support thread hijacking mode + +--- + src/lstack/api/lstack_wrap.c | 208 ++++++++++------------------ + src/lstack/core/lstack_cfg.c | 3 +- + src/lstack/core/lstack_init.c | 2 +- + src/lstack/core/lstack_preload.c | 114 ++++++++++++++- + src/lstack/include/lstack_preload.h | 9 ++ + 5 files changed, 202 insertions(+), 134 deletions(-) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 236c689..ab39a68 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -40,73 +40,15 @@ + #include "gazelle_base_func.h" + #include "lstack_thread_rpc.h" + ++#include "lstack_preload.h" ++ + #ifndef SOCK_TYPE_MASK + #define SOCK_TYPE_MASK 0xf + #endif + +-enum KERNEL_LWIP_PATH { +- PATH_KERNEL = 0, +- PATH_LWIP, +- PATH_UNKNOW, +-}; +- +-static inline enum KERNEL_LWIP_PATH select_path(int fd, struct lwip_sock **socket) +-{ +- if (unlikely(posix_api == NULL)) { +- /* +- * posix api maybe call before gazelle init +- * So, we must call posix_api_init at the head of select_path +- */ +- if (posix_api_init() != 0) { +- LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n"); +- } +- return PATH_KERNEL; +- } +- +- if (unlikely(posix_api->ues_posix)) { +- return PATH_KERNEL; +- } +- +- struct lwip_sock *sock = get_socket_by_fd(fd); +- +- /* AF_UNIX case */ +- if (!sock || !sock->conn || CONN_TYPE_IS_HOST(sock->conn)) { +- return PATH_KERNEL; +- } +- +- if (socket) { +- *socket = sock; +- } +- +- if (likely(CONN_TYPE_IS_LIBOS(sock->conn))) { +- return PATH_LWIP; +- } +- +- if (NETCONN_IS_UDP(sock)) { +- return PATH_LWIP; +- } else { +- struct tcp_pcb *pcb = sock->conn->pcb.tcp; +- /* after lwip connect, call send immediately, pcb->state is SYN_SENT, need return PATH_LWIP */ +- /* pcb->state default value is CLOSED when call socket, need return PATH_UNKNOW */ +- if (pcb != NULL && pcb->state <= ESTABLISHED && pcb->state >= LISTEN) { +- return PATH_LWIP; +- } +- } +- +- return PATH_UNKNOW; +-} +- + static inline int32_t do_epoll_create1(int32_t flags) + { +- if (posix_api == NULL) { +- /* posix api maybe call before gazelle init */ +- if (posix_api_init() != 0) { +- LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n"); +- } +- return posix_api->epoll_create1_fn(flags); +- } +- +- if (unlikely(posix_api->ues_posix)) { ++ if (select_posix_path() == PATH_KERNEL) { + return posix_api->epoll_create1_fn(flags); + } + +@@ -115,15 +57,7 @@ static inline int32_t do_epoll_create1(int32_t flags) + + static inline int32_t do_epoll_create(int32_t size) + { +- if (posix_api == NULL) { +- /* posix api maybe call before gazelle init */ +- if (posix_api_init() != 0) { +- LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n"); +- } +- return posix_api->epoll_create_fn(size); +- } +- +- if (unlikely(posix_api->ues_posix)) { ++ if (select_posix_path() == PATH_KERNEL) { + return posix_api->epoll_create_fn(size); + } + +@@ -132,7 +66,7 @@ static inline int32_t do_epoll_create(int32_t size) + + static inline int32_t do_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event* event) + { +- if (unlikely(posix_api->ues_posix)) { ++ if (select_posix_path() == PATH_KERNEL) { + return posix_api->epoll_ctl_fn(epfd, op, fd, event); + } + +@@ -141,7 +75,7 @@ static inline int32_t do_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct + + static inline int32_t do_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout) + { +- if (unlikely(posix_api->ues_posix)) { ++ if (select_posix_path() == PATH_KERNEL) { + return posix_api->epoll_wait_fn(epfd, events, maxevents, timeout); + } + +@@ -158,8 +92,7 @@ static inline int32_t do_epoll_wait(int32_t epfd, struct epoll_event* events, in + + static inline int32_t do_accept(int32_t s, struct sockaddr *addr, socklen_t *addrlen) + { +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_KERNEL) { ++ if (select_fd_posix_path(s, NULL) == PATH_KERNEL) { + return posix_api->accept_fn(s, addr, addrlen); + } + +@@ -177,8 +110,7 @@ static int32_t do_accept4(int32_t s, struct sockaddr *addr, socklen_t *addrlen, + GAZELLE_RETURN(EINVAL); + } + +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_KERNEL) { ++ if (select_fd_posix_path(s, NULL) == PATH_KERNEL) { + return posix_api->accept4_fn(s, addr, addrlen, flags); + } + +@@ -219,22 +151,21 @@ static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen + } + + struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_KERNEL) { ++ if (select_fd_posix_path(s, &sock) == PATH_KERNEL) { + return posix_api->bind_fn(s, name, namelen); + } + +- int32_t ret = posix_api->bind_fn(s, name, namelen); +- if (ret < 0) { +- /* ip is not lstack, just return */ +- if (!match_host_addr(((struct sockaddr_in *)name)->sin_addr.s_addr)) { +- return ret; ++ if (match_host_addr(((struct sockaddr_in *)name)->sin_addr.s_addr)) { ++ /* maybe kni addr */ ++ posix_api->bind_fn(s, name, namelen); ++ if (NETCONN_IS_UDP(sock) && get_global_cfg_params()->listen_shadow) { ++ return stack_broadcast_bind(s, name, namelen); ++ } else { ++ return stack_single_bind(s, name, namelen); + } +- } +- +- if (NETCONN_IS_UDP(sock) && get_global_cfg_params()->listen_shadow) { +- return stack_broadcast_bind(s, name, namelen); + } else { +- return stack_single_bind(s, name, namelen); ++ SET_CONN_TYPE_HOST(sock->conn); ++ return posix_api->bind_fn(s, name, namelen); + } + } + +@@ -299,7 +230,7 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name + } + + struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_KERNEL) { ++ if (select_fd_posix_path(s, &sock) == PATH_KERNEL) { + return posix_api->connect_fn(s, name, namelen); + } + +@@ -309,6 +240,7 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name + } + + if (!netconn_is_nonblocking(sock->conn)) { ++ LSTACK_LOG(ERR, LSTACK, "connect does not support blocking fd currently\n"); + GAZELLE_RETURN(EINVAL); + } + +@@ -330,8 +262,7 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name + + static inline int32_t do_listen(int32_t s, int32_t backlog) + { +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_KERNEL) { ++ if (select_fd_posix_path(s, NULL) == PATH_KERNEL) { + return posix_api->listen_fn(s, backlog); + } + +@@ -355,8 +286,7 @@ static inline int32_t do_getpeername(int32_t s, struct sockaddr *name, socklen_t + GAZELLE_RETURN(EINVAL); + } + +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_LWIP) { ++ if (select_fd_posix_path(s, NULL) == PATH_LWIP) { + return rpc_call_getpeername(s, name, namelen); + } + +@@ -369,8 +299,7 @@ static inline int32_t do_getsockname(int32_t s, struct sockaddr *name, socklen_t + GAZELLE_RETURN(EINVAL); + } + +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_LWIP) { ++ if (select_fd_posix_path(s, NULL) == PATH_LWIP) { + return rpc_call_getsockname(s, name, namelen); + } + +@@ -391,8 +320,7 @@ static bool unsupport_optname(int32_t optname) + + static inline int32_t do_getsockopt(int32_t s, int32_t level, int32_t optname, void *optval, socklen_t *optlen) + { +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_LWIP && !unsupport_optname(optname)) { ++ if (select_fd_posix_path(s, NULL) == PATH_LWIP && !unsupport_optname(optname)) { + return rpc_call_getsockopt(s, level, optname, optval, optlen); + } + +@@ -401,8 +329,7 @@ static inline int32_t do_getsockopt(int32_t s, int32_t level, int32_t optname, v + + static inline int32_t do_setsockopt(int32_t s, int32_t level, int32_t optname, const void *optval, socklen_t optlen) + { +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_KERNEL || unsupport_optname(optname)) { ++ if (select_fd_posix_path(s, NULL) == PATH_KERNEL || unsupport_optname(optname)) { + return posix_api->setsockopt_fn(s, level, optname, optval, optlen); + } + +@@ -417,13 +344,27 @@ static inline int32_t do_setsockopt(int32_t s, int32_t level, int32_t optname, c + + static inline int32_t do_socket(int32_t domain, int32_t type, int32_t protocol) + { +- if ((domain != AF_INET && domain != AF_UNSPEC) +- || ((type & SOCK_DGRAM) && !get_global_cfg_params()->udp_enable) +- || posix_api->ues_posix) { ++ int32_t ret; ++ /* process not init completed or not hajacking thread */ ++ if (select_posix_path() == PATH_KERNEL) { ++ return posix_api->socket_fn(domain, type, protocol); ++ } ++ ++ if ((domain != AF_INET && domain != AF_UNSPEC) || ++ ((type & SOCK_DGRAM) && !get_global_cfg_params()->udp_enable)) { + return posix_api->socket_fn(domain, type, protocol); + } + +- return rpc_call_socket(domain, type, protocol); ++ ret = rpc_call_socket(domain, type, protocol); ++ /* if udp_enable = 1 in lstack.conf, udp protocol must be in user path currently */ ++ if ((ret >= 0) && (type & SOCK_DGRAM)) { ++ struct lwip_sock *sock = get_socket(ret); ++ if (sock != NULL && sock->conn != NULL) { ++ SET_CONN_TYPE_LIBOS(sock->conn); ++ } ++ } ++ ++ return ret; + } + + static inline ssize_t do_recv(int32_t sockfd, void *buf, size_t len, int32_t flags) +@@ -436,12 +377,12 @@ static inline ssize_t do_recv(int32_t sockfd, void *buf, size_t len, int32_t fla + return 0; + } + +- struct lwip_sock *sock = NULL; +- if (select_path(sockfd, &sock) == PATH_LWIP) { +- return do_lwip_read_from_stack(sockfd, buf, len, flags, NULL, NULL); ++ if (select_posix_path() == PATH_KERNEL || // maybe fd is created by open before posix_api_init called ++ select_fd_posix_path(sockfd, NULL) == PATH_KERNEL) { ++ return posix_api->recv_fn(sockfd, buf, len, flags); + } + +- return posix_api->recv_fn(sockfd, buf, len, flags); ++ return do_lwip_read_from_stack(sockfd, buf, len, flags, NULL, NULL); + } + + static inline ssize_t do_read(int32_t s, void *mem, size_t len) +@@ -454,17 +395,18 @@ static inline ssize_t do_read(int32_t s, void *mem, size_t len) + return 0; + } + +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_LWIP) { +- return do_lwip_read_from_stack(s, mem, len, 0, NULL, NULL); ++ if (select_posix_path() == PATH_KERNEL || ++ select_fd_posix_path(s, NULL) == PATH_KERNEL) { ++ return posix_api->read_fn(s, mem, len); + } +- return posix_api->read_fn(s, mem, len); ++ ++ return do_lwip_read_from_stack(s, mem, len, 0, NULL, NULL); + } + + static inline ssize_t do_readv(int32_t s, const struct iovec *iov, int iovcnt) + { +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) != PATH_LWIP) { ++ if (select_posix_path() == PATH_KERNEL || ++ select_fd_posix_path(s, NULL) == PATH_KERNEL) { + return posix_api->readv_fn(s, iov, iovcnt); + } + +@@ -487,8 +429,8 @@ static inline ssize_t do_readv(int32_t s, const struct iovec *iov, int iovcnt) + + static inline ssize_t do_send(int32_t sockfd, const void *buf, size_t len, int32_t flags) + { +- struct lwip_sock *sock = NULL; +- if (select_path(sockfd, &sock) != PATH_LWIP) { ++ if (select_posix_path() == PATH_KERNEL || ++ select_fd_posix_path(sockfd, NULL) == PATH_KERNEL) { + return posix_api->send_fn(sockfd, buf, len, flags); + } + +@@ -497,8 +439,8 @@ static inline ssize_t do_send(int32_t sockfd, const void *buf, size_t len, int32 + + static inline ssize_t do_write(int32_t s, const void *mem, size_t size) + { +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) != PATH_LWIP) { ++ if (select_posix_path() == PATH_KERNEL || ++ select_fd_posix_path(s, NULL) == PATH_KERNEL) { + return posix_api->write_fn(s, mem, size); + } + +@@ -507,8 +449,9 @@ static inline ssize_t do_write(int32_t s, const void *mem, size_t size) + + static inline ssize_t do_writev(int32_t s, const struct iovec *iov, int iovcnt) + { +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) != PATH_LWIP) { ++ struct lwip_sock *sock; ++ if (select_posix_path() == PATH_KERNEL || ++ select_fd_posix_path(s, &sock) == PATH_KERNEL) { + return posix_api->writev_fn(s, iov, iovcnt); + } + +@@ -530,12 +473,12 @@ static inline ssize_t do_recvmsg(int32_t s, struct msghdr *message, int32_t flag + GAZELLE_RETURN(EINVAL); + } + +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_LWIP) { +- return do_lwip_recvmsg_from_stack(s, message, flags); ++ if (select_posix_path() == PATH_KERNEL || ++ select_fd_posix_path(s, NULL) == PATH_KERNEL) { ++ return posix_api->recv_msg(s, message, flags); + } + +- return posix_api->recv_msg(s, message, flags); ++ return do_lwip_recvmsg_from_stack(s, message, flags); + } + + static inline ssize_t do_sendmsg(int32_t s, const struct msghdr *message, int32_t flags) +@@ -544,12 +487,13 @@ static inline ssize_t do_sendmsg(int32_t s, const struct msghdr *message, int32_ + GAZELLE_RETURN(EINVAL); + } + +- struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_LWIP) { +- return do_lwip_sendmsg_to_stack(sock, s, message, flags); ++ struct lwip_sock *sock; ++ if (select_posix_path() == PATH_KERNEL || ++ select_fd_posix_path(s, &sock) == PATH_KERNEL) { ++ return posix_api->send_msg(s, message, flags); + } + +- return posix_api->send_msg(s, message, flags); ++ return do_lwip_sendmsg_to_stack(sock, s, message, flags); + } + + static inline ssize_t udp_recvfrom(struct lwip_sock *sock, int32_t sockfd, void *buf, size_t len, int32_t flags, +@@ -596,7 +540,7 @@ static inline ssize_t do_recvfrom(int32_t sockfd, void *buf, size_t len, int32_t + } + + struct lwip_sock *sock = NULL; +- if (select_path(sockfd, &sock) == PATH_LWIP) { ++ if (select_fd_posix_path(sockfd, &sock) == PATH_LWIP) { + if (NETCONN_IS_UDP(sock)) { + return udp_recvfrom(sock, sockfd, buf, len, flags, addr, addrlen); + } else { +@@ -611,7 +555,7 @@ static inline ssize_t do_sendto(int32_t sockfd, const void *buf, size_t len, int + const struct sockaddr *addr, socklen_t addrlen) + { + struct lwip_sock *sock = NULL; +- if (select_path(sockfd, &sock) != PATH_LWIP) { ++ if (select_fd_posix_path(sockfd, &sock) != PATH_LWIP) { + return posix_api->send_to(sockfd, buf, len, flags, addr, addrlen); + } + +@@ -621,7 +565,8 @@ static inline ssize_t do_sendto(int32_t sockfd, const void *buf, size_t len, int + static inline int32_t do_close(int32_t s) + { + struct lwip_sock *sock = NULL; +- if (select_path(s, &sock) == PATH_KERNEL) { ++ if (select_posix_path() == PATH_KERNEL || ++ select_fd_posix_path(s, &sock) == PATH_KERNEL) { + /* we called lwip_socket, even if kernel fd */ + if (posix_api != NULL && !posix_api->ues_posix && + /* contain posix_api->close_fn if success */ +@@ -639,7 +584,7 @@ static inline int32_t do_close(int32_t s) + + static int32_t do_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout) + { +- if (unlikely(posix_api->ues_posix) || fds == NULL || nfds == 0) { ++ if ((select_posix_path() == PATH_KERNEL) || fds == NULL || nfds == 0) { + return posix_api->poll_fn(fds, nfds, timeout); + } + +@@ -684,7 +629,8 @@ static int32_t do_sigaction(int32_t signum, const struct sigaction *act, struct + val = va_arg(ap, typeof(val)); \ + va_end(ap); \ + struct lwip_sock *sock = NULL; \ +- if (select_path(_fd, &sock) == PATH_KERNEL) \ ++ if (select_posix_path() == PATH_KERNEL || \ ++ select_fd_posix_path(_fd, &sock) == PATH_KERNEL) \ + return _fcntl_fn(_fd, _cmd, val); \ + int32_t ret = _fcntl_fn(_fd, _cmd, val); \ + if (ret == -1) \ +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 0eca86e..189459a 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -223,7 +223,8 @@ static int32_t parse_host_addr(void) + int32_t match_host_addr(uint32_t addr) + { + /* network byte order */ +- if (addr == g_config_params.host_addr.addr) { ++ if (addr == g_config_params.host_addr.addr || ++ addr == INADDR_ANY) { + return 1; + } + return 0; +diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c +index 2183e3a..b6e9bf1 100644 +--- a/src/lstack/core/lstack_init.c ++++ b/src/lstack/core/lstack_init.c +@@ -285,7 +285,7 @@ __attribute__((constructor)) void gazelle_network_init(void) + } + + if (stack_thread_setup() != 0) { +- LSTACK_EXIT(1, "stack_init_in_setup failed\n"); ++ LSTACK_EXIT(1, "stack_thread_setup failed\n"); + } + + /* lwip initialization */ +diff --git a/src/lstack/core/lstack_preload.c b/src/lstack/core/lstack_preload.c +index e3a98fc..1d68501 100644 +--- a/src/lstack/core/lstack_preload.c ++++ b/src/lstack/core/lstack_preload.c +@@ -12,8 +12,13 @@ + #include + #include + #include ++#define __USE_GNU ++#include ++#include + +-#include "securec.h" ++#include ++#include ++#include + + #include "lstack_log.h" + #include "lstack_preload.h" +@@ -22,10 +27,17 @@ + #define LSTACK_SO_NAME "liblstack.so" + #define LSTACK_PRELOAD_NAME_LEN PATH_MAX + #define LSTACK_PRELOAD_ENV_PROC "GAZELLE_BIND_PROCNAME" ++#define LSTACK_PRELOAD_ENV_THRD "GAZELLE_THREAD_NAME" ++ ++#define EXCLUDE_THRD_CNT 1 ++const static char *g_exclude_thread[EXCLUDE_THRD_CNT] = {"eal-intr-thread"}; ++static PER_THREAD enum KERNEL_LWIP_PATH g_preload_thrdpath = PATH_UNKNOW; + + struct lstack_preload { + int32_t preload_switch; + char env_procname[LSTACK_PRELOAD_NAME_LEN]; ++ bool get_thrdname; ++ char env_thrdname[LSTACK_PRELOAD_NAME_LEN]; + }; + static struct lstack_preload g_preload_info = {0}; + +@@ -52,12 +64,104 @@ static int32_t preload_check_bind_proc(void) + return -1; + } + ++static void preload_get_thrdname(void) ++{ ++ g_preload_info.get_thrdname = true; ++ ++ char *enval = NULL; ++ enval = getenv(LSTACK_PRELOAD_ENV_THRD); ++ if (enval == NULL) { ++ return; ++ } ++ if (strcpy_s(g_preload_info.env_thrdname, LSTACK_PRELOAD_NAME_LEN, enval) != EOK) { ++ return; ++ } ++ ++ LSTACK_PRE_LOG(LSTACK_INFO, "thread name=%s ok\n", g_preload_info.env_thrdname); ++} ++ ++enum KERNEL_LWIP_PATH select_fd_posix_path(int32_t fd, struct lwip_sock **socket) ++{ ++ struct lwip_sock *sock = get_socket_by_fd(fd); ++ ++ /* AF_UNIX case */ ++ if (!sock || !sock->conn || CONN_TYPE_IS_HOST(sock->conn)) { ++ return PATH_KERNEL; ++ } ++ ++ if (socket) { ++ *socket = sock; ++ } ++ ++ if (likely(CONN_TYPE_IS_LIBOS(sock->conn))) { ++ return PATH_LWIP; ++ } ++ ++ return PATH_UNKNOW; ++} ++ ++enum KERNEL_LWIP_PATH select_posix_path(void) ++{ ++ if (unlikely(posix_api == NULL)) { ++ /* ++ * posix api maybe call before gazelle init ++ * So, we must call posix_api_init at the head of select_path ++ */ ++ if (posix_api_init() != 0) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n"); ++ } ++ return PATH_KERNEL; ++ } ++ ++ if (unlikely(posix_api->ues_posix)) { ++ return PATH_KERNEL; ++ } ++ ++ if (g_preload_thrdpath != PATH_UNKNOW) { ++ return g_preload_thrdpath; ++ } ++ ++ if (!g_preload_info.get_thrdname) { ++ preload_get_thrdname(); ++ } ++ ++ char thread_name[PATH_MAX] = {0}; ++ if (pthread_getname_np(pthread_self(), thread_name, PATH_MAX) != 0) { ++ g_preload_thrdpath = PATH_KERNEL; ++ return PATH_KERNEL; ++ } ++ ++ /* exclude dpdk thread */ ++ for (int i = 0; i < EXCLUDE_THRD_CNT; i++) { ++ if (strstr(thread_name, g_exclude_thread[i]) != NULL) { ++ g_preload_thrdpath = PATH_KERNEL; ++ return PATH_KERNEL; ++ } ++ } ++ ++ /* not set GAZELLE_THREAD_NAME, select all thread */ ++ if (g_preload_info.env_thrdname[0] == '\0') { ++ g_preload_thrdpath = PATH_LWIP; ++ return PATH_LWIP; ++ } ++ ++ if (strstr(thread_name, g_preload_info.env_thrdname) == NULL) { ++ g_preload_thrdpath = PATH_KERNEL; ++ return PATH_KERNEL; ++ } ++ ++ g_preload_thrdpath = PATH_LWIP; ++ return PATH_LWIP; ++} ++ + int preload_info_init(void) + { + char *enval = NULL; + + g_preload_info.preload_switch = 0; + ++ preload_get_thrdname(); ++ + enval = getenv(LSTACK_PRELOAD_ENV_SYS); + if (enval == NULL) { + return 0; +@@ -75,6 +179,14 @@ int preload_info_init(void) + return -1; + } + ++ enval = getenv(LSTACK_PRELOAD_ENV_THRD); ++ if (enval != NULL) { ++ if (strcpy_s(g_preload_info.env_thrdname, LSTACK_PRELOAD_NAME_LEN, enval) != EOK) { ++ return -1; ++ } ++ g_preload_info.get_thrdname = true; ++ } ++ + g_preload_info.preload_switch = 1; + LSTACK_PRE_LOG(LSTACK_INFO, "LD_PRELOAD ok\n"); + return preload_check_bind_proc(); +diff --git a/src/lstack/include/lstack_preload.h b/src/lstack/include/lstack_preload.h +index 4ba6525..0ad7877 100644 +--- a/src/lstack/include/lstack_preload.h ++++ b/src/lstack/include/lstack_preload.h +@@ -11,6 +11,15 @@ + */ + #ifndef __LSTACK_PRELOAD_H__ + #define __LSTACK_PRELOAD_H__ ++#include + ++enum KERNEL_LWIP_PATH { ++ PATH_KERNEL = 0, ++ PATH_LWIP, ++ PATH_UNKNOW, ++}; ++ ++enum KERNEL_LWIP_PATH select_posix_path(void); ++enum KERNEL_LWIP_PATH select_fd_posix_path(int32_t fd, struct lwip_sock **socket); + int preload_info_init(void); + #endif +-- +2.23.0 + diff --git a/0019-cfg-add-run-to-completion-mode-configure.patch b/0019-cfg-add-run-to-completion-mode-configure.patch new file mode 100644 index 0000000..b11a79d --- /dev/null +++ b/0019-cfg-add-run-to-completion-mode-configure.patch @@ -0,0 +1,91 @@ +From 3208a2f1ada7c8c388bdea356d38c9edef1e05dd Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Sun, 8 Oct 2023 19:48:45 +0800 +Subject: [PATCH] cfg: add run-to-completion mode configure + +--- + src/lstack/core/lstack_cfg.c | 30 ++++++++++++++++++++++++++++++ + src/lstack/include/lstack_cfg.h | 1 + + src/lstack/lstack.conf | 2 ++ + 3 files changed, 33 insertions(+) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 0eca86e..951e6e8 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -76,6 +76,7 @@ static int32_t parse_use_sockmap(void); + static int32_t parse_udp_enable(void); + static int32_t parse_nic_rxqueue_size(void); + static int32_t parse_nic_txqueue_size(void); ++static int32_t parse_stack_thread_mode(void); + + #define PARSE_ARG(_arg, _arg_string, _default_val, _min_val, _max_val, _ret) \ + do { \ +@@ -135,6 +136,7 @@ static struct config_vector_t g_config_tbl[] = { + { "udp_enable", parse_udp_enable }, + { "nic_rxqueue_size", parse_nic_rxqueue_size}, + { "nic_txqueue_size", parse_nic_txqueue_size}, ++ { "stack_thread_mode", parse_stack_thread_mode }, + { NULL, NULL } + }; + +@@ -1183,3 +1185,31 @@ static int32_t parse_nic_txqueue_size(void) + NIC_QUEUE_SIZE_MIN, NIC_QUEUE_SIZE_MAX, ret); + return ret; + } ++ ++static int32_t parse_stack_thread_mode(void) ++{ ++ const config_setting_t *thread_mode = NULL; ++ const char *args = NULL; ++ ++ thread_mode = config_lookup(&g_config, "stack_thread_mode"); ++ if (thread_mode == NULL) { ++ g_config_params.stack_mode_rtc = false; ++ return 0; ++ } ++ ++ args = config_setting_get_string(thread_mode); ++ if (args == NULL) { ++ return -EINVAL; ++ } ++ ++ if (strncmp(args, "run-to-completion", strlen("run-to-completion") + 1) == 0) { ++ g_config_params.stack_mode_rtc = true; ++ } else if (strncmp(args, "run-to-wakeup", strlen("run-to-wakeup") + 1) == 0) { ++ g_config_params.stack_mode_rtc = false; ++ } else { ++ LSTACK_LOG(ERR, LSTACK, "stack_mode_rtc only support run-to-completion or run-to-wakeup\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index e48a501..1d895ec 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -116,6 +116,7 @@ struct cfg_params { + bool use_sockmap; + bool udp_enable; + struct cfg_nic_params nic; ++ bool stack_mode_rtc; + }; + + struct cfg_params *get_global_cfg_params(void); +diff --git a/src/lstack/lstack.conf b/src/lstack/lstack.conf +index ad574e1..48973fe 100644 +--- a/src/lstack/lstack.conf ++++ b/src/lstack/lstack.conf +@@ -10,6 +10,8 @@ + + dpdk_args=["--socket-mem", "2048,0,0,0", "--huge-dir", "/mnt/hugepages-lstack", "--proc-type", "primary", "--legacy-mem", "--map-perfect"] + ++stack_thread_mode="run-to-wakeup" ++ + use_ltran=1 + kni_switch=0 + +-- +2.23.0 + diff --git a/gazelle.spec b/gazelle.spec index 0255cb5..ac6ae46 100644 --- a/gazelle.spec +++ b/gazelle.spec @@ -2,7 +2,7 @@ Name: gazelle Version: 1.0.2 -Release: 7 +Release: 8 Summary: gazelle is a high performance user-mode stack License: MulanPSL-2.0 URL: https://gitee.com/openeuler/gazelle @@ -33,6 +33,8 @@ Patch9014: 0014-init-remove-sync-sem-between-lstack-thread-and-main-.patch Patch9015: 0015-lstack_lwip-external-api-start-with-do_lwip_-prefix.patch Patch9016: 0016-cfg-nic-rx-tx-queue-size-configure.patch Patch9017: 0017-epoll-distinguish-add-del_sock_event-and-add-del_soc.patch +Patch9018: 0018-preload-support-thread-hijacking-mode.patch +Patch9019: 0019-cfg-add-run-to-completion-mode-configure.patch %description %{name} is a high performance user-mode stack. @@ -74,6 +76,10 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b %config(noreplace) %{conf_path}/ltran.conf %changelog +* Mon Oct 30 2023 yangchenCloud - 1.0.2-8 +- cfg: add run-to-completion mode configure +- preload: support thread hijacking mode + * Mon Oct 30 2023 hantwofish - 1.0.2-7 - epoll: distinguish add/del_sock_event and add/del_sock_event_nolock - cfg: nic rx/tx queue size configure