diff --git a/0257-cleancode-refactor-rtc_api-rtw_api-and-dummy_api.patch b/0257-cleancode-refactor-rtc_api-rtw_api-and-dummy_api.patch new file mode 100644 index 0000000..13b6996 --- /dev/null +++ b/0257-cleancode-refactor-rtc_api-rtw_api-and-dummy_api.patch @@ -0,0 +1,1035 @@ +From 85e907b495391a89096bfb7e5c9cb901d0f9f56b Mon Sep 17 00:00:00 2001 +From: Lemmy Huang +Date: Sat, 31 Aug 2024 11:31:13 +0800 +Subject: [PATCH] cleancode: refactor rtc_api rtw_api and dummy_api + +Signed-off-by: Lemmy Huang +--- + src/lstack/api/lstack_dummy_api.c | 32 ++++-- + src/lstack/api/lstack_epoll.c | 2 +- + src/lstack/api/lstack_fork.c | 28 ----- + src/lstack/api/lstack_rtc_api.c | 92 +++++++++++----- + src/lstack/api/lstack_rtw_api.c | 104 +++++++++++------- + .../api/{lstack_signal.c => lstack_unistd.c} | 31 +++++- + src/lstack/api/lstack_wrap.c | 91 ++------------- + src/lstack/core/lstack_init.c | 31 ++---- + src/lstack/core/lstack_lwip.c | 2 +- + src/lstack/core/lstack_protocol_stack.c | 2 +- + src/lstack/core/lstack_stack_stat.c | 2 +- + src/lstack/include/{posix => }/lstack_epoll.h | 0 + src/lstack/include/lstack_rtc_api.h | 43 +------- + src/lstack/include/lstack_rtw_api.h | 35 +----- + .../include/{posix => }/lstack_unistd.h | 13 +-- + src/lstack/include/lstack_wrap.h | 2 +- + 16 files changed, 217 insertions(+), 293 deletions(-) + delete mode 100644 src/lstack/api/lstack_fork.c + rename src/lstack/api/{lstack_signal.c => lstack_unistd.c} (89%) + rename src/lstack/include/{posix => }/lstack_epoll.h (100%) + rename src/lstack/include/{posix => }/lstack_unistd.h (78%) + +diff --git a/src/lstack/api/lstack_dummy_api.c b/src/lstack/api/lstack_dummy_api.c +index f327916..3a867b3 100644 +--- a/src/lstack/api/lstack_dummy_api.c ++++ b/src/lstack/api/lstack_dummy_api.c +@@ -13,6 +13,10 @@ + #include + #include + ++#include ++#include ++#include ++ + #define DUMMY_SLEEP_S 5 + + static inline ssize_t dummy_exit(void) +@@ -22,34 +26,48 @@ static inline ssize_t dummy_exit(void) + return -1; + } + +-int dummy_socket(int domain, int type, int protocol) ++static int dummy_socket(int domain, int type, int protocol) + { + sleep(DUMMY_SLEEP_S); + return -1; + } + +-ssize_t dummy_write(int s, const void *mem, size_t size) ++static ssize_t dummy_write(int s, const void *mem, size_t size) + { + return dummy_exit(); + } + +-ssize_t dummy_writev(int s, const struct iovec *iov, int iovcnt) ++static ssize_t dummy_writev(int s, const struct iovec *iov, int iovcnt) + { + return dummy_exit(); + } + +-ssize_t dummy_send(int sockfd, const void *buf, size_t len, int flags) ++static ssize_t dummy_send(int sockfd, const void *buf, size_t len, int flags) + { + return dummy_exit(); + } + +-ssize_t dummy_sendmsg(int s, const struct msghdr *message, int flags) ++static ssize_t dummy_sendmsg(int s, const struct msghdr *message, int flags) + { + return dummy_exit(); + } + +-ssize_t dummy_sendto(int sockfd, const void *buf, size_t len, int flags, +- const struct sockaddr *addr, socklen_t addrlen) ++static ssize_t dummy_sendto(int sockfd, const void *buf, size_t len, int flags, ++ const struct sockaddr *addr, socklen_t addrlen) + { + return dummy_exit(); + } ++ ++void dummy_api_init(posix_api_t *api) ++{ ++ api->socket_fn = dummy_socket; ++ api->send_fn = dummy_send; ++ api->write_fn = dummy_write; ++ api->writev_fn = dummy_writev; ++ api->sendmsg_fn = dummy_sendmsg; ++ api->sendto_fn = dummy_sendto; ++ ++ rte_wmb(); ++ /* 1: wait until app thread call send functio complete */ ++ sleep(1); ++} +diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c +index 5b0bee4..1c13076 100644 +--- a/src/lstack/api/lstack_epoll.c ++++ b/src/lstack/api/lstack_epoll.c +@@ -35,7 +35,7 @@ + #include "common/gazelle_base_func.h" + #include "lstack_lwip.h" + #include "lstack_protocol_stack.h" +-#include "posix/lstack_epoll.h" ++#include "lstack_epoll.h" + + #define EPOLL_KERNEL_INTERVAL 10 /* ms */ + #define SEC_TO_NSEC 1000000000 +diff --git a/src/lstack/api/lstack_fork.c b/src/lstack/api/lstack_fork.c +deleted file mode 100644 +index f5d0e95..0000000 +--- a/src/lstack/api/lstack_fork.c ++++ /dev/null +@@ -1,28 +0,0 @@ +-/* +-* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. +-* gazelle is licensed under the Mulan PSL v2. +-* You can use this software according to the terms and conditions of the Mulan PSL v2. +-* You may obtain a copy of Mulan PSL v2 at: +-* http://license.coscl.org.cn/MulanPSL2 +-* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +-* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +-* PURPOSE. +-* See the Mulan PSL v2 for more details. +-*/ +- +-#include +-#include +- +-#include +- +-pid_t lstack_fork(void) +-{ +- pid_t pid; +- +- pid = posix_api->fork_fn(); +- /* child not support lwip */ +- if (pid == 0) { +- posix_api->use_kernel = 1; +- } +- return pid; +-} +diff --git a/src/lstack/api/lstack_rtc_api.c b/src/lstack/api/lstack_rtc_api.c +index e30718c..7689c83 100644 +--- a/src/lstack/api/lstack_rtc_api.c ++++ b/src/lstack/api/lstack_rtc_api.c +@@ -10,37 +10,16 @@ + * See the Mulan PSL v2 for more details. + */ + +-#include +-#include +-#include +-#include +-#include + #include +-#include "posix/lstack_epoll.h" ++#include ++ ++#include "lstack_epoll.h" + #include "lstack_log.h" + #include "lstack_cfg.h" + #include "lstack_protocol_stack.h" +-#include "lstack_thread_rpc.h" + #include "lstack_rtc_api.h" + +-int rtc_poll(struct pollfd *fds, nfds_t nfds, int timeout) +-{ +- LSTACK_LOG(ERR, LSTACK, "rtc_poll: rtc currently does not support poll\n"); +- return -1; +-} +- +-int rtc_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) +-{ +- LSTACK_LOG(ERR, LSTACK, "rtc_select: rtc currently does not support select\n"); +- return -1; +-} +- +-int rtc_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout) +-{ +- return lstack_rtc_epoll_wait(epfd, events, maxevents, timeout); +-} +- +-int rtc_socket(int domain, int type, int protocol) ++static int rtc_socket(int domain, int type, int protocol) + { + int ret; + +@@ -53,7 +32,7 @@ int rtc_socket(int domain, int type, int protocol) + return ret; + } + +-int rtc_close(int s) ++static int rtc_close(int s) + { + struct lwip_sock *sock = lwip_get_socket(s); + if (sock != NULL && sock->wakeup != NULL && sock->wakeup->epollfd == s) { +@@ -63,12 +42,12 @@ int rtc_close(int s) + return lwip_close(s); + } + +-int rtc_shutdown(int fd, int how) ++static int rtc_shutdown(int fd, int how) + { + return lwip_shutdown(fd, how); + } + +-int rtc_epoll_create(int flags) ++static int rtc_epoll_create(int flags) + { + if (stack_setup_app_thread() < 0) { + exit(1); +@@ -77,7 +56,7 @@ int rtc_epoll_create(int flags) + return lstack_epoll_create(flags); + } + +-int rtc_epoll_create1(int flags) ++static int rtc_epoll_create1(int flags) + { + if (stack_setup_app_thread() < 0) { + exit(1); +@@ -86,7 +65,60 @@ int rtc_epoll_create1(int flags) + return lstack_epoll_create1(flags); + } + +-int rtc_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) ++static int rtc_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) + { + return lstack_rtc_epoll_ctl(epfd, op, fd, event); + } ++ ++static int rtc_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout) ++{ ++ return lstack_rtc_epoll_wait(epfd, events, maxevents, timeout); ++} ++ ++static int rtc_poll(struct pollfd *fds, nfds_t nfds, int timeout) ++{ ++ LSTACK_LOG(ERR, LSTACK, "rtc_poll: rtc currently does not support poll\n"); ++ return -1; ++} ++ ++static int rtc_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) ++{ ++ LSTACK_LOG(ERR, LSTACK, "rtc_select: rtc currently does not support select\n"); ++ return -1; ++} ++ ++void rtc_api_init(posix_api_t *api) ++{ ++ api->close_fn = rtc_close; ++ api->shutdown_fn = rtc_shutdown; ++ api->socket_fn = rtc_socket; ++ api->accept_fn = lwip_accept; ++ api->accept4_fn = lwip_accept4; ++ api->bind_fn = lwip_bind; ++ api->listen_fn = lwip_listen; ++ api->connect_fn = lwip_connect; ++ ++ api->setsockopt_fn = lwip_setsockopt; ++ api->getsockopt_fn = lwip_getsockopt; ++ api->getpeername_fn = lwip_getpeername; ++ api->getsockname_fn = lwip_getsockname; ++ ++ api->read_fn = lwip_read; ++ api->readv_fn = lwip_readv; ++ api->write_fn = lwip_write; ++ api->writev_fn = lwip_writev; ++ api->recv_fn = lwip_recv; ++ api->send_fn = lwip_send; ++ api->recvmsg_fn = (ssize_t (*)(int, const struct msghdr *, int))lwip_recvmsg; // TODO: fix unnecessary 'const' in lwipgz_posix_api.h ++ api->sendmsg_fn = lwip_sendmsg; ++ api->recvfrom_fn = lwip_recvfrom; ++ api->sendto_fn = lwip_sendto; ++ ++ api->epoll_ctl_fn = rtc_epoll_ctl; ++ api->epoll_create1_fn = rtc_epoll_create1; ++ api->epoll_create_fn = rtc_epoll_create; ++ api->epoll_wait_fn = rtc_epoll_wait; ++ ++ api->poll_fn = rtc_poll; ++ api->select_fn = rtc_select; ++} +diff --git a/src/lstack/api/lstack_rtw_api.c b/src/lstack/api/lstack_rtw_api.c +index 09c4e11..d8634cc 100644 +--- a/src/lstack/api/lstack_rtw_api.c ++++ b/src/lstack/api/lstack_rtw_api.c +@@ -10,23 +10,18 @@ + * See the Mulan PSL v2 for more details. + */ + +-#include +-#include +-#include +-#include +- + #include ++#include + + #include "lstack_thread_rpc.h" +-#include "posix/lstack_epoll.h" ++#include "lstack_epoll.h" + #include "lstack_protocol_stack.h" + #include "lstack_cfg.h" + #include "lstack_lwip.h" + #include "common/gazelle_base_func.h" + #include "lstack_rtw_api.h" + +- +-int rtw_socket(int domain, int type, int protocol) ++static int rtw_socket(int domain, int type, int protocol) + { + struct protocol_stack *stack = get_bind_protocol_stack(); + if (stack == NULL) { +@@ -35,17 +30,17 @@ int rtw_socket(int domain, int type, int protocol) + return rpc_call_socket(&stack->rpc_queue, domain, type, protocol); + } + +-int rtw_accept(int s, struct sockaddr *addr, socklen_t *addrlen) ++static int rtw_accept(int s, struct sockaddr *addr, socklen_t *addrlen) + { + return stack_broadcast_accept(s, addr, addrlen); + } + +-int rtw_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) ++static int rtw_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) + { + return stack_broadcast_accept4(s, addr, addrlen, flags); + } + +-int rtw_bind(int s, const struct sockaddr *name, socklen_t namelen) ++static int rtw_bind(int s, const struct sockaddr *name, socklen_t namelen) + { + struct lwip_sock *sock = lwip_get_socket(s); + +@@ -56,7 +51,7 @@ int rtw_bind(int s, const struct sockaddr *name, socklen_t namelen) + } + } + +-int rtw_listen(int s, int backlog) ++static int rtw_listen(int s, int backlog) + { + if (!get_global_cfg_params()->tuple_filter && + !get_global_cfg_params()->listen_shadow) { +@@ -66,7 +61,7 @@ int rtw_listen(int s, int backlog) + } + } + +-int rtw_connect(int s, const struct sockaddr *name, socklen_t namelen) ++static int rtw_connect(int s, const struct sockaddr *name, socklen_t namelen) + { + struct protocol_stack *stack = get_protocol_stack_by_fd(s); + if (stack == NULL) { +@@ -75,7 +70,7 @@ int rtw_connect(int s, const struct sockaddr *name, socklen_t namelen) + return rpc_call_connect(&stack->rpc_queue, s, name, namelen); + } + +-int rtw_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) ++static int rtw_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) + { + struct protocol_stack *stack = get_protocol_stack_by_fd(s); + if (stack == NULL) { +@@ -84,7 +79,7 @@ int rtw_setsockopt(int s, int level, int optname, const void *optval, socklen_t + return rpc_call_setsockopt(&stack->rpc_queue, s, level, optname, optval, optlen); + } + +-int rtw_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ++static int rtw_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) + { + struct protocol_stack *stack = get_protocol_stack_by_fd(s); + if (stack == NULL) { +@@ -93,7 +88,7 @@ int rtw_getsockopt(int s, int level, int optname, void *optval, socklen_t *optle + return rpc_call_getsockopt(&stack->rpc_queue, s, level, optname, optval, optlen); + } + +-int rtw_getpeername(int s, struct sockaddr *name, socklen_t *namelen) ++static int rtw_getpeername(int s, struct sockaddr *name, socklen_t *namelen) + { + struct protocol_stack *stack = get_protocol_stack_by_fd(s); + if (stack == NULL) { +@@ -102,7 +97,7 @@ int rtw_getpeername(int s, struct sockaddr *name, socklen_t *namelen) + return rpc_call_getpeername(&stack->rpc_queue, s, name, namelen); + } + +-int rtw_getsockname(int s, struct sockaddr *name, socklen_t *namelen) ++static int rtw_getsockname(int s, struct sockaddr *name, socklen_t *namelen) + { + struct protocol_stack *stack = get_protocol_stack_by_fd(s); + if (stack == NULL) { +@@ -111,12 +106,12 @@ int rtw_getsockname(int s, struct sockaddr *name, socklen_t *namelen) + return rpc_call_getsockname(&stack->rpc_queue, s, name, namelen); + } + +-ssize_t rtw_read(int s, void *mem, size_t len) ++static ssize_t rtw_read(int s, void *mem, size_t len) + { + return do_lwip_read_from_stack(s, mem, len, 0, NULL, NULL); + } + +-ssize_t rtw_readv(int s, const struct iovec *iov, int iovcnt) ++static ssize_t rtw_readv(int s, const struct iovec *iov, int iovcnt) + { + struct msghdr msg; + +@@ -130,12 +125,12 @@ ssize_t rtw_readv(int s, const struct iovec *iov, int iovcnt) + return do_lwip_recvmsg_from_stack(s, &msg, 0); + } + +-ssize_t rtw_write(int s, const void *mem, size_t size) ++static ssize_t rtw_write(int s, const void *mem, size_t size) + { + return do_lwip_send_to_stack(s, mem, size, 0, NULL, 0); + } + +-ssize_t rtw_writev(int s, const struct iovec *iov, int iovcnt) ++static ssize_t rtw_writev(int s, const struct iovec *iov, int iovcnt) + { + struct lwip_sock *sock = lwip_get_socket(s); + struct msghdr msg; +@@ -150,22 +145,22 @@ ssize_t rtw_writev(int s, const struct iovec *iov, int iovcnt) + return do_lwip_sendmsg_to_stack(sock, s, &msg, 0); + } + +-ssize_t rtw_recv(int sockfd, void *buf, size_t len, int flags) ++static ssize_t rtw_recv(int sockfd, void *buf, size_t len, int flags) + { + return do_lwip_read_from_stack(sockfd, buf, len, flags, NULL, NULL); + } + +-ssize_t rtw_send(int sockfd, const void *buf, size_t len, int flags) ++static ssize_t rtw_send(int sockfd, const void *buf, size_t len, int flags) + { + return do_lwip_send_to_stack(sockfd, buf, len, flags, NULL, 0); + } + +-ssize_t rtw_recvmsg(int s, const struct msghdr *message, int flags) ++static ssize_t rtw_recvmsg(int s, struct msghdr *message, int flags) + { + return do_lwip_recvmsg_from_stack(s, message, flags); + } + +-ssize_t rtw_sendmsg(int s, const struct msghdr *message, int flags) ++static ssize_t rtw_sendmsg(int s, const struct msghdr *message, int flags) + { + struct lwip_sock *sock = lwip_get_socket(s); + return do_lwip_sendmsg_to_stack(sock, s, message, flags); +@@ -207,8 +202,8 @@ static inline ssize_t rtw_tcp_recvfrom(int sockfd, void *buf, size_t len, int fl + } + + +-ssize_t rtw_recvfrom(int sockfd, void *buf, size_t len, int flags, +- struct sockaddr *addr, socklen_t *addrlen) ++static ssize_t rtw_recvfrom(int sockfd, void *buf, size_t len, int flags, ++ struct sockaddr *addr, socklen_t *addrlen) + { + struct lwip_sock *sock = lwip_get_socket(sockfd); + if (NETCONN_IS_UDP(sock)) { +@@ -218,28 +213,28 @@ ssize_t rtw_recvfrom(int sockfd, void *buf, size_t len, int flags, + } + } + +-ssize_t rtw_sendto(int sockfd, const void *buf, size_t len, int flags, +- const struct sockaddr *addr, socklen_t addrlen) ++static ssize_t rtw_sendto(int sockfd, const void *buf, size_t len, int flags, ++ const struct sockaddr *addr, socklen_t addrlen) + { + return do_lwip_send_to_stack(sockfd, buf, len, flags, addr, addrlen); + } + +-int rtw_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout) ++static int rtw_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout) + { + return lstack_rtw_epoll_wait(epfd, events, maxevents, timeout); + } + +-int rtw_poll(struct pollfd *fds, nfds_t nfds, int timeout) ++static int rtw_poll(struct pollfd *fds, nfds_t nfds, int timeout) + { + return lstack_poll(fds, nfds, timeout); + } + +-int rtw_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) ++static int rtw_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) + { + return lstack_select(nfds, readfds, writefds, exceptfds, timeout); + } + +-int rtw_close(int s) ++static int rtw_close(int s) + { + struct lwip_sock *sock = lwip_get_socket(s); + if (sock && sock->wakeup && sock->wakeup->epollfd == s) { +@@ -248,7 +243,7 @@ int rtw_close(int s) + return stack_broadcast_close(s); + } + +-int rtw_shutdown(int fd, int how) ++static int rtw_shutdown(int fd, int how) + { + struct lwip_sock *sock = lwip_get_socket(fd); + if (sock && sock->wakeup && sock->wakeup->epollfd == fd) { +@@ -258,18 +253,53 @@ int rtw_shutdown(int fd, int how) + return stack_broadcast_shutdown(fd, how); + } + +-int rtw_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) ++static int rtw_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) + { + return lstack_rtw_epoll_ctl(epfd, op, fd, event); + } + +-int rtw_epoll_create1(int flags) ++static int rtw_epoll_create1(int flags) + { + return lstack_epoll_create1(flags); + } + +-int rtw_epoll_create(int flags) ++static int rtw_epoll_create(int flags) + { + return lstack_epoll_create(flags); + } + ++void rtw_api_init(posix_api_t *api) ++{ ++ api->close_fn = rtw_close; ++ api->shutdown_fn = rtw_shutdown; ++ api->socket_fn = rtw_socket; ++ api->accept_fn = rtw_accept; ++ api->accept4_fn = rtw_accept4; ++ api->bind_fn = rtw_bind; ++ api->listen_fn = rtw_listen; ++ api->connect_fn = rtw_connect; ++ ++ api->setsockopt_fn = rtw_setsockopt; ++ api->getsockopt_fn = rtw_getsockopt; ++ api->getpeername_fn = rtw_getpeername; ++ api->getsockname_fn = rtw_getsockname; ++ ++ api->read_fn = rtw_read; ++ api->readv_fn = rtw_readv; ++ api->write_fn = rtw_write; ++ api->writev_fn = rtw_writev; ++ api->recv_fn = rtw_recv; ++ api->send_fn = rtw_send; ++ api->recvmsg_fn = (ssize_t (*)(int, const struct msghdr *, int))rtw_recvmsg; // TODO: fix unnecessary 'const' in lwipgz_posix_api.h ++ api->sendmsg_fn = rtw_sendmsg; ++ api->recvfrom_fn = rtw_recvfrom; ++ api->sendto_fn = rtw_sendto; ++ ++ api->epoll_ctl_fn = rtw_epoll_ctl; ++ api->epoll_create1_fn = rtw_epoll_create1; ++ api->epoll_create_fn = rtw_epoll_create; ++ api->epoll_wait_fn = rtw_epoll_wait; ++ ++ api->poll_fn = rtw_poll; ++ api->select_fn = rtw_select; ++} +\ No newline at end of file +diff --git a/src/lstack/api/lstack_signal.c b/src/lstack/api/lstack_unistd.c +similarity index 89% +rename from src/lstack/api/lstack_signal.c +rename to src/lstack/api/lstack_unistd.c +index 9d0431b..1f78626 100644 +--- a/src/lstack/api/lstack_signal.c ++++ b/src/lstack/api/lstack_unistd.c +@@ -11,22 +11,22 @@ + */ + + #include +-#include +-#include + #include +-#include ++#include ++ + #include + #include + ++#include "lstack_unistd.h" + #include "common/gazelle_base_func.h" +-#include "lstack_cfg.h" +-#include "common/dpdk_common.h" + #include "lstack_log.h" ++#include "lstack_cfg.h" + #include "lstack_control_plane.h" + + static int g_hijack_signal[] = { SIGTERM, SIGINT, SIGSEGV, SIGBUS, SIGFPE, SIGILL, SIGKILL}; + #define HIJACK_SIGNAL_COUNT (sizeof(g_hijack_signal) / sizeof(g_hijack_signal[0])) + #define BACKTRACE_SIZE 64 ++ + static void dump_stack(void) + { + char **stack_trace = NULL; +@@ -71,17 +71,24 @@ static void lstack_sig_default_handler(int sig) + (void)kill(getpid(), sig); + } + +-void lstack_signal_init(void) ++int lstack_signal_init(void) + { + unsigned int i; + struct sigaction action; + ++ /* to prevent crash, just ignore SIGPIPE when socket is closed */ ++ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { ++ return -1; ++ } ++ + sigemptyset(&action.sa_mask); + action.sa_flags = (int)(SA_NODEFER | SA_RESETHAND); + action.sa_handler = lstack_sig_default_handler; + for (i = 0; i < HIJACK_SIGNAL_COUNT; i++) { + posix_api->sigaction_fn(g_hijack_signal[i], &action, NULL); + } ++ ++ return 0; + } + + int lstack_sigaction(int sig_num, const struct sigaction *action, struct sigaction *old_action) +@@ -104,3 +111,15 @@ int lstack_sigaction(int sig_num, const struct sigaction *action, struct sigacti + + return posix_api->sigaction_fn(sig_num, action, old_action); + } ++ ++pid_t lstack_fork(void) ++{ ++ pid_t pid; ++ ++ pid = posix_api->fork_fn(); ++ /* child not support lwip */ ++ if (pid == 0) { ++ posix_api->use_kernel = 1; ++ } ++ return pid; ++} +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 92ce73b..1d5529d 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -10,29 +10,22 @@ + * See the Mulan PSL v2 for more details. + */ + +-#include +-#include ++#include + #include +- +-#include +-#include + #include + #include +-#include + #include +-#include + + #include + #include + #include + +-#include "posix/lstack_unistd.h" ++#include "common/gazelle_base_func.h" + #include "lstack_log.h" + #include "lstack_cfg.h" + #include "lstack_lwip.h" +-#include "common/gazelle_base_func.h" + #include "lstack_preload.h" +- ++#include "lstack_unistd.h" + #include "lstack_rtc_api.h" + #include "lstack_rtw_api.h" + #include "lstack_dummy_api.h" +@@ -45,78 +38,18 @@ void wrap_api_init(void) + if (g_wrap_api != NULL) { + return; + } +- + g_wrap_api = &g_wrap_api_value; ++ + if (get_global_cfg_params()->stack_mode_rtc) { +- g_wrap_api->socket_fn = rtc_socket; +- g_wrap_api->accept_fn = lwip_accept; +- g_wrap_api->accept4_fn = lwip_accept4; +- g_wrap_api->bind_fn = lwip_bind; +- g_wrap_api->listen_fn = lwip_listen; +- g_wrap_api->connect_fn = lwip_connect; +- g_wrap_api->setsockopt_fn = lwip_setsockopt; +- g_wrap_api->getsockopt_fn = lwip_getsockopt; +- g_wrap_api->getpeername_fn = lwip_getpeername; +- g_wrap_api->getsockname_fn = lwip_getsockname; +- g_wrap_api->read_fn = lwip_read; +- g_wrap_api->readv_fn = lwip_readv; +- g_wrap_api->write_fn = lwip_write; +- g_wrap_api->writev_fn = lwip_writev; +- g_wrap_api->recv_fn = lwip_recv; +- g_wrap_api->send_fn = lwip_send; +- g_wrap_api->recvmsg_fn = lwip_recvmsg; +- g_wrap_api->sendmsg_fn = lwip_sendmsg; +- g_wrap_api->recvfrom_fn = lwip_recvfrom; +- g_wrap_api->sendto_fn = lwip_sendto; +- g_wrap_api->epoll_wait_fn = rtc_epoll_wait; +- g_wrap_api->poll_fn = rtc_poll; +- g_wrap_api->close_fn = rtc_close; +- g_wrap_api->shutdown_fn = rtc_shutdown; +- g_wrap_api->epoll_ctl_fn = rtc_epoll_ctl; +- g_wrap_api->epoll_create1_fn = rtc_epoll_create1; +- g_wrap_api->epoll_create_fn = rtc_epoll_create; +- g_wrap_api->select_fn = rtc_select; ++ rtc_api_init(g_wrap_api); + } else { +- g_wrap_api->socket_fn = rtw_socket; +- g_wrap_api->accept_fn = rtw_accept; +- g_wrap_api->accept4_fn = rtw_accept4; +- g_wrap_api->bind_fn = rtw_bind; +- g_wrap_api->listen_fn = rtw_listen; +- g_wrap_api->connect_fn = rtw_connect; +- g_wrap_api->setsockopt_fn = rtw_setsockopt; +- g_wrap_api->getsockopt_fn = rtw_getsockopt; +- g_wrap_api->getpeername_fn = rtw_getpeername; +- g_wrap_api->getsockname_fn = rtw_getsockname; +- g_wrap_api->read_fn = rtw_read; +- g_wrap_api->readv_fn = rtw_readv; +- g_wrap_api->write_fn = rtw_write; +- g_wrap_api->writev_fn = rtw_writev; +- g_wrap_api->recv_fn = rtw_recv; +- g_wrap_api->send_fn = rtw_send; +- g_wrap_api->recvmsg_fn = rtw_recvmsg; +- g_wrap_api->sendmsg_fn = rtw_sendmsg; +- g_wrap_api->recvfrom_fn = rtw_recvfrom; +- g_wrap_api->sendto_fn = rtw_sendto; +- g_wrap_api->epoll_wait_fn = rtw_epoll_wait; +- g_wrap_api->poll_fn = rtw_poll; +- g_wrap_api->close_fn = rtw_close; +- g_wrap_api->shutdown_fn = rtw_shutdown; +- g_wrap_api->epoll_ctl_fn = rtw_epoll_ctl; +- g_wrap_api->epoll_create1_fn = rtw_epoll_create1; +- g_wrap_api->epoll_create_fn = rtw_epoll_create; +- g_wrap_api->select_fn = rtw_select; +- } +-} +- +-void wrap_api_set_dummy(void) +-{ +- g_wrap_api->socket_fn = dummy_socket; +- g_wrap_api->send_fn = dummy_send; +- g_wrap_api->write_fn = dummy_write; +- g_wrap_api->writev_fn = dummy_writev; +- g_wrap_api->sendmsg_fn = dummy_sendmsg; +- g_wrap_api->sendto_fn = dummy_sendto; +- rte_wmb(); ++ rtw_api_init(g_wrap_api); ++ } ++} ++ ++void wrap_api_exit(void) ++{ ++ dummy_api_init(g_wrap_api); + } + + static inline int32_t do_epoll_create1(int32_t flags) +diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c +index e0f7bd7..37264a1 100644 +--- a/src/lstack/core/lstack_init.c ++++ b/src/lstack/core/lstack_init.c +@@ -20,27 +20,26 @@ + #include + #include + #include +-#include + #include + #include + #include + #include + +-#include ++#include ++ + #include + #include + #include + #include + ++#include "lstack_log.h" + #include "lstack_cfg.h" + #include "lstack_control_plane.h" + #include "lstack_ethdev.h" + #include "lstack_dpdk.h" + #include "lstack_stack_stat.h" +-#include "lstack_log.h" + #include "common/dpdk_common.h" +-#include "posix/lstack_epoll.h" +-#include "posix/lstack_unistd.h" ++#include "lstack_unistd.h" + #include "common/gazelle_base_func.h" + #include "lstack_protocol_stack.h" + #include "lstack_preload.h" +@@ -107,9 +106,7 @@ static int32_t check_process_conflict(void) + + void gazelle_exit(void) + { +- wrap_api_set_dummy(); +- /* 1: wait until app thread call send functio complete */ +- sleep(1); ++ wrap_api_exit(); + stack_group_exit(); + } + +@@ -170,18 +167,6 @@ static void create_control_thread(void) + LSTACK_LOG(INFO, LSTACK, "create control_easy_thread success\n"); + } + +-static void gazelle_signal_init(void) +-{ +- /* to prevent crash , just ignore SIGPIPE when socket is closed */ +- if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { +- LSTACK_PRE_LOG(LSTACK_ERR, "signal error, errno:%d.", errno); +- LSTACK_EXIT(1, "signal SIGPIPE SIG_IGN\n"); +- } +- +- /* register core sig handler func to dumped stack */ +- lstack_signal_init(); +-} +- + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + static void set_kni_ip_mac() + { +@@ -278,7 +263,11 @@ __attribute__((constructor)) void gazelle_network_init(void) + } + } + +- gazelle_signal_init(); ++ /* register core sig handler func to dumped stack */ ++ if (lstack_signal_init() != 0) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "signal init failed, errno %d\n", errno); ++ LSTACK_EXIT(1, "signal init failed, errno %d\n", errno); ++ } + + /* Init control plane and dpdk init */ + create_control_thread(); +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index a7b7202..89142a4 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -34,7 +34,7 @@ + #include "lstack_log.h" + #include "lstack_dpdk.h" + #include "lstack_stack_stat.h" +-#include "posix/lstack_epoll.h" ++#include "lstack_epoll.h" + #include "lstack_thread_rpc.h" + #include "common/dpdk_common.h" + #include "lstack_cfg.h" +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 00900e7..f56e911 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -31,7 +31,7 @@ + #include "lstack_lwip.h" + #include "lstack_cfg.h" + #include "lstack_control_plane.h" +-#include "posix/lstack_epoll.h" ++#include "lstack_epoll.h" + #include "lstack_stack_stat.h" + #include "lstack_virtio.h" + #include "lstack_protocol_stack.h" +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index 406e27c..b6619f6 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -26,7 +26,7 @@ + #include "common/gazelle_dfx_msg.h" + #include "lstack_thread_rpc.h" + #include "lstack_protocol_stack.h" +-#include "posix/lstack_epoll.h" ++#include "lstack_epoll.h" + #include "lstack_dpdk.h" + #include "lstack_stack_stat.h" + #include "lstack_virtio.h" +diff --git a/src/lstack/include/posix/lstack_epoll.h b/src/lstack/include/lstack_epoll.h +similarity index 100% +rename from src/lstack/include/posix/lstack_epoll.h +rename to src/lstack/include/lstack_epoll.h +diff --git a/src/lstack/include/lstack_rtc_api.h b/src/lstack/include/lstack_rtc_api.h +index 3a41e6f..b4b7e1c 100644 +--- a/src/lstack/include/lstack_rtc_api.h ++++ b/src/lstack/include/lstack_rtc_api.h +@@ -12,47 +12,14 @@ + + #ifndef _LSTACK_RTC_API_H_ + #define _LSTACK_RTC_API_H_ +-#include +-#include +-#include ++ ++#include + + /* don't include lwip/sockets.h, conflict with sys/socket.h */ +-/* extern lwip_api here */ + extern int lwip_fcntl(int s, int cmd, int val); +-extern int lwip_ioctl(int s, long cmd, ...); +-extern int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +-extern int lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags); +-extern int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); +-extern int lwip_shutdown(int s, int how); +-extern int lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen); +-extern int lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen); +-extern int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); +-extern int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); +-extern int lwip_close(int s); +-extern int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); +-extern int lwip_listen(int s, int backlog); +-extern ssize_t lwip_recv(int s, void *mem, size_t len, int flags); +-extern ssize_t lwip_read(int s, void *mem, size_t len); +-extern ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt); +-extern ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags, +- struct sockaddr *from, socklen_t *fromlen); +-extern ssize_t lwip_recvmsg(int s, const struct msghdr *message, int flags); +-extern ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags); +-extern ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags); +-extern ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, +- const struct sockaddr *to, socklen_t tolen); +-extern int lwip_socket(int domain, int type, int protocol); +-extern ssize_t lwip_write(int s, const void *dataptr, size_t size); +-extern ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt); ++extern int lwip_ioctl(int s, long cmd, void *argp); + +-int rtc_poll(struct pollfd *fds, nfds_t nfds, int timeout); +-int rtc_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout); +-int rtc_socket(int domain, int type, int protocol); +-int rtc_close(int s); +-int rtc_shutdown(int fd, int how); +-int rtc_epoll_create(int flags); +-int rtc_epoll_create1(int flags); +-int rtc_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); +-int rtc_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); ++void dummy_api_init(posix_api_t *api); ++void rtc_api_init(posix_api_t *api); + + #endif /* __LSTACK_RTC_API_H_ */ +diff --git a/src/lstack/include/lstack_rtw_api.h b/src/lstack/include/lstack_rtw_api.h +index a38b656..437901a 100644 +--- a/src/lstack/include/lstack_rtw_api.h ++++ b/src/lstack/include/lstack_rtw_api.h +@@ -13,39 +13,8 @@ + #ifndef _LSTACK_RTW_API_H_ + #define _LSTACK_RTW_API_H_ + +-#include +-#include +-#include ++#include + +-int rtw_socket(int domain, int type, int protocol); +-int rtw_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +-int rtw_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags); +-int rtw_bind(int s, const struct sockaddr *name, socklen_t namelen); +-int rtw_listen(int s, int backlog); +-int rtw_connect(int s, const struct sockaddr *name, socklen_t namelen); +-int rtw_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); +-int rtw_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); +-int rtw_getpeername(int s, struct sockaddr *name, socklen_t *namelen); +-int rtw_getsockname(int s, struct sockaddr *name, socklen_t *namelen); +-ssize_t rtw_read(int s, void *mem, size_t len); +-ssize_t rtw_readv(int s, const struct iovec *iov, int iovcnt); +-ssize_t rtw_write(int s, const void *mem, size_t size); +-ssize_t rtw_writev(int s, const struct iovec *iov, int iovcnt); +-ssize_t rtw_recv(int sockfd, void *buf, size_t len, int flags); +-ssize_t rtw_send(int sockfd, const void *buf, size_t len, int flags); +-ssize_t rtw_recvmsg(int s, const struct msghdr *message, int flags); +-ssize_t rtw_sendmsg(int s, const struct msghdr *message, int flags); +-ssize_t rtw_recvfrom(int sockfd, void *buf, size_t len, int flags, +- struct sockaddr *addr, socklen_t *addrlen); +-ssize_t rtw_sendto(int sockfd, const void *buf, size_t len, int flags, +- const struct sockaddr *addr, socklen_t addrlen); +-int rtw_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout); +-int rtw_poll(struct pollfd *fds, nfds_t nfds, int timeout); +-int rtw_close(int s); +-int rtw_shutdown(int fd, int how); +-int rtw_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); +-int rtw_epoll_create1(int flags); +-int rtw_epoll_create(int flags); +-int rtw_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); ++void rtw_api_init(posix_api_t *api); + + #endif /* _LSTACK_RTW_API_H_ */ +diff --git a/src/lstack/include/posix/lstack_unistd.h b/src/lstack/include/lstack_unistd.h +similarity index 78% +rename from src/lstack/include/posix/lstack_unistd.h +rename to src/lstack/include/lstack_unistd.h +index 484a792..3bcee5a 100644 +--- a/src/lstack/include/posix/lstack_unistd.h ++++ b/src/lstack/include/lstack_unistd.h +@@ -13,16 +13,11 @@ + #ifndef _GAZELLE_UNISTD_H_ + #define _GAZELLE_UNISTD_H_ + +-#ifdef __cplusplus +-extern "C" { +-#endif ++#include ++#include + ++int lstack_signal_init(void); ++int lstack_sigaction(int sig_num, const struct sigaction *action, struct sigaction *old_action); + pid_t lstack_fork(void); +-void lstack_signal_init(void); +-int lstack_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); +- +-#ifdef __cplusplus +-} +-#endif + + #endif /* _GAZELLE_UNISTD_H_ */ +diff --git a/src/lstack/include/lstack_wrap.h b/src/lstack/include/lstack_wrap.h +index dab5222..a45b0d5 100644 +--- a/src/lstack/include/lstack_wrap.h ++++ b/src/lstack/include/lstack_wrap.h +@@ -14,7 +14,7 @@ + #define _LSTACK_WRAP_H_ + + void wrap_api_init(void); +-void wrap_api_set_dummy(void); ++void wrap_api_exit(void); + + #endif + +-- +2.33.0 + diff --git a/0258-cleancode-move-some-API-from-stack-to-rpc-and-rtw.patch b/0258-cleancode-move-some-API-from-stack-to-rpc-and-rtw.patch new file mode 100644 index 0000000..3cce58f --- /dev/null +++ b/0258-cleancode-move-some-API-from-stack-to-rpc-and-rtw.patch @@ -0,0 +1,2604 @@ +From 7e4d7c638681df4f32c0d719c62b4e38ef69c1eb Mon Sep 17 00:00:00 2001 +From: Lemmy Huang +Date: Sat, 31 Aug 2024 14:51:41 +0800 +Subject: [PATCH] cleancode: move some API from stack to rpc and rtw + +Signed-off-by: Lemmy Huang +--- + src/lstack/api/lstack_epoll.c | 17 +- + src/lstack/api/lstack_rtc_api.c | 7 +- + src/lstack/api/lstack_rtw_api.c | 250 ++++++- + src/lstack/api/lstack_wrap.c | 1 - + src/lstack/core/lstack_dpdk.c | 5 +- + src/lstack/core/lstack_lwip.c | 47 +- + src/lstack/core/lstack_protocol_stack.c | 757 ++------------------- + src/lstack/core/lstack_thread_rpc.c | 610 +++++++++++++---- + src/lstack/include/lstack_dpdk.h | 33 +- + src/lstack/include/lstack_epoll.h | 12 +- + src/lstack/include/lstack_lwip.h | 9 +- + src/lstack/include/lstack_protocol_stack.h | 51 +- + src/lstack/include/lstack_rpc_proc.h | 47 -- + src/lstack/include/lstack_thread_rpc.h | 81 +-- + src/lstack/netif/lstack_ethdev.c | 56 ++ + 15 files changed, 927 insertions(+), 1056 deletions(-) + delete mode 100644 src/lstack/include/lstack_rpc_proc.h + +diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c +index 1c13076..ce3d267 100644 +--- a/src/lstack/api/lstack_epoll.c ++++ b/src/lstack/api/lstack_epoll.c +@@ -19,15 +19,9 @@ + #include + #include + +-#include + #include +-#include +-#include +-#include +-#include + #include + +-#include "lstack_ethdev.h" + #include "lstack_stack_stat.h" + #include "lstack_cfg.h" + #include "lstack_log.h" +@@ -306,6 +300,17 @@ int32_t lstack_epoll_create(int32_t flags) + return lstack_do_epoll_create(fd); + } + ++static void stack_broadcast_clean_epoll(struct wakeup_poll *wakeup) ++{ ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ struct protocol_stack *stack = NULL; ++ ++ for (int32_t i = 0; i < stack_group->stack_num; i++) { ++ stack = stack_group->stacks[i]; ++ rpc_call_clean_epoll(&stack->rpc_queue, wakeup); ++ } ++} ++ + int32_t lstack_epoll_close(int32_t fd) + { + struct lwip_sock *sock = lwip_get_socket(fd); +diff --git a/src/lstack/api/lstack_rtc_api.c b/src/lstack/api/lstack_rtc_api.c +index 7689c83..60d3b23 100644 +--- a/src/lstack/api/lstack_rtc_api.c ++++ b/src/lstack/api/lstack_rtc_api.c +@@ -42,11 +42,6 @@ static int rtc_close(int s) + return lwip_close(s); + } + +-static int rtc_shutdown(int fd, int how) +-{ +- return lwip_shutdown(fd, how); +-} +- + static int rtc_epoll_create(int flags) + { + if (stack_setup_app_thread() < 0) { +@@ -90,7 +85,7 @@ static int rtc_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *excep + void rtc_api_init(posix_api_t *api) + { + api->close_fn = rtc_close; +- api->shutdown_fn = rtc_shutdown; ++ api->shutdown_fn = lwip_shutdown; + api->socket_fn = rtc_socket; + api->accept_fn = lwip_accept; + api->accept4_fn = lwip_accept4; +diff --git a/src/lstack/api/lstack_rtw_api.c b/src/lstack/api/lstack_rtw_api.c +index d8634cc..7ceff20 100644 +--- a/src/lstack/api/lstack_rtw_api.c ++++ b/src/lstack/api/lstack_rtw_api.c +@@ -13,14 +13,258 @@ + #include + #include + ++#include "common/gazelle_base_func.h" ++#include "lstack_log.h" ++#include "lstack_cfg.h" + #include "lstack_thread_rpc.h" +-#include "lstack_epoll.h" + #include "lstack_protocol_stack.h" +-#include "lstack_cfg.h" + #include "lstack_lwip.h" +-#include "common/gazelle_base_func.h" ++#include "lstack_epoll.h" + #include "lstack_rtw_api.h" + ++/* when fd is listenfd, listenfd of all protocol stack thread will be closed */ ++static int stack_broadcast_close(int fd) ++{ ++ int ret = 0; ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); ++ if (sock == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ ++ do { ++ sock = sock->listen_next; ++ if (stack == NULL || rpc_call_close(&stack->rpc_queue, fd)) { ++ ret = -1; ++ } ++ ++ if (POSIX_IS_CLOSED(sock)) { ++ break; ++ } ++ fd = sock->conn->callback_arg.socket; ++ stack = get_protocol_stack_by_fd(fd); ++ } while (1); ++ ++ return ret; ++} ++ ++static int stack_broadcast_shutdown(int fd, int how) ++{ ++ int32_t ret = 0; ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); ++ if (sock == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ ++ do { ++ sock = sock->listen_next; ++ if (stack == NULL || rpc_call_shutdown(&stack->rpc_queue, fd, how)) { ++ ret = -1; ++ } ++ ++ if (POSIX_IS_CLOSED(sock)) { ++ break; ++ } ++ fd = sock->conn->callback_arg.socket; ++ stack = get_protocol_stack_by_fd(fd); ++ } while (1); ++ ++ return ret; ++} ++ ++/* choice one stack bind */ ++static int stack_single_bind(int fd, const struct sockaddr *name, socklen_t namelen) ++{ ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ return rpc_call_bind(&stack->rpc_queue, fd, name, namelen); ++} ++ ++/* bind sync to all protocol stack thread, so that any protocol stack thread can build connect */ ++static int stack_broadcast_bind(int fd, const struct sockaddr *name, socklen_t namelen) ++{ ++ struct protocol_stack *cur_stack = get_protocol_stack_by_fd(fd); ++ struct protocol_stack *stack = NULL; ++ int ret, clone_fd; ++ ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ if (sock == NULL || cur_stack == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, %d get sock null or stack null\n", get_stack_tid(), fd); ++ GAZELLE_RETURN(EBADF); ++ } ++ ++ ret = rpc_call_bind(&cur_stack->rpc_queue, fd, name, namelen); ++ if (ret < 0) { ++ close(fd); ++ return ret; ++ } ++ ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ for (int i = 0; i < stack_group->stack_num; ++i) { ++ stack = stack_group->stacks[i]; ++ if (stack != cur_stack) { ++ clone_fd = rpc_call_shadow_fd(&stack->rpc_queue, fd, name, namelen); ++ if (clone_fd < 0) { ++ stack_broadcast_close(fd); ++ return clone_fd; ++ } ++ } ++ } ++ return 0; ++} ++ ++static void inline del_accept_in_event(struct lwip_sock *sock) ++{ ++ pthread_spin_lock(&sock->wakeup->event_list_lock); ++ ++ if (!NETCONN_IS_ACCEPTIN(sock)) { ++ sock->events &= ~EPOLLIN; ++ if (sock->events == 0) { ++ list_del_node(&sock->event_list); ++ } ++ } ++ ++ pthread_spin_unlock(&sock->wakeup->event_list_lock); ++} ++ ++static struct lwip_sock *get_min_accept_sock(int fd) ++{ ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ struct lwip_sock *min_sock = NULL; ++ ++ while (sock) { ++ if (!NETCONN_IS_ACCEPTIN(sock)) { ++ sock = sock->listen_next; ++ continue; ++ } ++ ++ if (min_sock == NULL || min_sock->stack->conn_num > sock->stack->conn_num) { ++ min_sock = sock; ++ } ++ ++ sock = sock->listen_next; ++ } ++ ++ return min_sock; ++} ++ ++/* ergodic the protocol stack thread to find the connection, because all threads are listening */ ++static int stack_broadcast_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags) ++{ ++ int ret = -1; ++ struct lwip_sock *min_sock = NULL; ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ struct protocol_stack *stack = NULL; ++ if (sock == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ ++ if (netconn_is_nonblocking(sock->conn)) { ++ min_sock = get_min_accept_sock(fd); ++ } else { ++ while ((min_sock = get_min_accept_sock(fd)) == NULL) { ++ lstack_block_wait(sock->wakeup, 0); ++ } ++ } ++ ++ if (min_sock && min_sock->conn) { ++ stack = get_protocol_stack_by_fd(min_sock->conn->callback_arg.socket); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ ret = rpc_call_accept(&stack->rpc_queue, min_sock->conn->callback_arg.socket, addr, addrlen, flags); ++ } ++ ++ if (min_sock && min_sock->wakeup && min_sock->wakeup->type == WAKEUP_EPOLL) { ++ del_accept_in_event(min_sock); ++ } ++ ++ if (ret < 0) { ++ errno = EAGAIN; ++ } ++ return ret; ++} ++ ++static int stack_broadcast_accept(int fd, struct sockaddr *addr, socklen_t *addrlen) ++{ ++ if (get_global_cfg_params()->nonblock_mode) ++ return stack_broadcast_accept4(fd, addr, addrlen, O_NONBLOCK); ++ else ++ return stack_broadcast_accept4(fd, addr, addrlen, 0); ++} ++ ++/* choice one stack listen */ ++static int stack_single_listen(int fd, int backlog) ++{ ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); ++ if (stack == NULL) { ++ GAZELLE_RETURN(EBADF); ++ } ++ return rpc_call_listen(&stack->rpc_queue, fd, backlog); ++} ++ ++/* listen sync to all protocol stack thread, so that any protocol stack thread can build connect */ ++static int stack_broadcast_listen(int fd, int backlog) ++{ ++ typedef union sockaddr_union { ++ struct sockaddr sa; ++ struct sockaddr_in in; ++ struct sockaddr_in6 in6; ++ } sockaddr_t; ++ ++ struct protocol_stack *cur_stack = get_protocol_stack_by_fd(fd); ++ struct protocol_stack *stack = NULL; ++ sockaddr_t addr; ++ socklen_t addr_len = sizeof(addr); ++ int ret, clone_fd; ++ ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ if (sock == NULL || cur_stack == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, %d get sock null or stack null\n", get_stack_tid(), fd); ++ GAZELLE_RETURN(EBADF); ++ } ++ ++ ret = rpc_call_getsockname(&cur_stack->rpc_queue, fd, (struct sockaddr *)&addr, &addr_len); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ int min_conn_stk_idx = get_min_conn_stack(stack_group); ++ ++ for (int32_t i = 0; i < stack_group->stack_num; ++i) { ++ stack = stack_group->stacks[i]; ++ if (get_global_cfg_params()->seperate_send_recv && stack->is_send_thread) { ++ continue; ++ } ++ if (stack != cur_stack) { ++ clone_fd = rpc_call_shadow_fd(&stack->rpc_queue, fd, (struct sockaddr *)&addr, addr_len); ++ if (clone_fd < 0) { ++ stack_broadcast_close(fd); ++ return clone_fd; ++ } ++ } else { ++ clone_fd = fd; ++ } ++ ++ if (min_conn_stk_idx == i) { ++ lwip_get_socket(clone_fd)->conn->is_master_fd = 1; ++ } else { ++ lwip_get_socket(clone_fd)->conn->is_master_fd = 0; ++ } ++ ++ ret = rpc_call_listen(&stack->rpc_queue, clone_fd, backlog); ++ if (ret < 0) { ++ stack_broadcast_close(fd); ++ return ret; ++ } ++ } ++ return 0; ++} ++ + static int rtw_socket(int domain, int type, int protocol) + { + struct protocol_stack *stack = get_bind_protocol_stack(); +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 1d5529d..8f80f98 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -14,7 +14,6 @@ + #include + #include + #include +-#include + + #include + #include +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 50fbdf6..f87e362 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -43,7 +43,6 @@ + #include "lstack_log.h" + #include "common/dpdk_common.h" + #include "lstack_protocol_stack.h" +-#include "lstack_thread_rpc.h" + #include "lstack_lwip.h" + #include "lstack_cfg.h" + #include "lstack_virtio.h" +@@ -765,9 +764,9 @@ static int dpdk_bond_create(uint8_t mode, int *slave_port_id, int count) + return 0; + } + +-int32_t init_dpdk_ethdev(void) ++int init_dpdk_ethdev(void) + { +- int32_t ret; ++ int ret; + int slave_port_id[GAZELLE_MAX_BOND_NUM]; + int port_id = 0; + struct cfg_params *cfg = get_global_cfg_params(); +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 89142a4..3454961 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -29,15 +29,12 @@ + #include + + #include "common/gazelle_base_func.h" +-#include "lstack_ethdev.h" +-#include "lstack_protocol_stack.h" + #include "lstack_log.h" +-#include "lstack_dpdk.h" ++#include "lstack_cfg.h" ++#include "lstack_protocol_stack.h" + #include "lstack_stack_stat.h" + #include "lstack_epoll.h" +-#include "lstack_thread_rpc.h" +-#include "common/dpdk_common.h" +-#include "lstack_cfg.h" ++#include "lstack_dpdk.h" + #include "lstack_lwip.h" + + static const uint8_t fin_packet = 0; +@@ -841,43 +838,24 @@ ssize_t gazelle_same_node_ring_send(struct lwip_sock *sock, const void *buf, siz + return act_len; + } + +-PER_THREAD uint16_t stack_sock_num[GAZELLE_MAX_STACK_NUM] = {0}; +-PER_THREAD uint16_t max_sock_stack = 0; +- +-static inline void thread_bind_stack(struct lwip_sock *sock) +-{ +- if (likely(sock->already_bind_numa || !sock->stack)) { +- return; +- } +- sock->already_bind_numa = 1; +- +- if (get_global_cfg_params()->app_bind_numa == 0) { +- return; +- } +- +- stack_sock_num[sock->stack->stack_idx]++; +- if (stack_sock_num[sock->stack->stack_idx] > max_sock_stack) { +- max_sock_stack = stack_sock_num[sock->stack->stack_idx]; +- bind_to_stack_numa(sock->stack); +- } +-} +- + ssize_t do_lwip_send_to_stack(int32_t fd, const void *buf, size_t len, int32_t flags, + const struct sockaddr *addr, socklen_t addrlen) + { ++ struct lwip_sock *sock; + ssize_t send = 0; +- ++ + if (buf == NULL) { + GAZELLE_RETURN(EINVAL); + } +- + if (addr && addr->sa_family != AF_INET && addr->sa_family != AF_INET6) { + GAZELLE_RETURN(EINVAL); + } +- +- struct lwip_sock *sock = lwip_get_socket(fd); + +- thread_bind_stack(sock); ++ sock = lwip_get_socket(fd); ++ if (unlikely(sock->already_bind_numa == 0 && sock->stack)) { ++ thread_bind_stack(sock->stack); ++ sock->already_bind_numa = 1; ++ } + + if (sock->same_node_tx_ring != NULL) { + return gazelle_same_node_ring_send(sock, buf, len, flags); +@@ -1131,7 +1109,10 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags + return -1; + } + +- thread_bind_stack(sock); ++ if (unlikely(sock->already_bind_numa == 0 && sock->stack)) { ++ thread_bind_stack(sock->stack); ++ sock->already_bind_numa = 1; ++ } + + if (sock->same_node_rx_ring != NULL) { + return gazelle_same_node_ring_recv(sock, buf, len, flags); +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index f56e911..bcca1a7 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -22,14 +22,12 @@ + #include + + #include "common/gazelle_base_func.h" +-#include "lstack_thread_rpc.h" + #include "common/dpdk_common.h" + #include "lstack_log.h" ++#include "lstack_cfg.h" + #include "lstack_dpdk.h" + #include "lstack_ethdev.h" +-#include "lstack_vdev.h" + #include "lstack_lwip.h" +-#include "lstack_cfg.h" + #include "lstack_control_plane.h" + #include "lstack_epoll.h" + #include "lstack_stack_stat.h" +@@ -64,18 +62,6 @@ static void stack_wait_quit(struct protocol_stack *stack) + } + } + +-void bind_to_stack_numa(struct protocol_stack *stack) +-{ +- int32_t ret; +- pthread_t tid = pthread_self(); +- +- ret = pthread_setaffinity_np(tid, sizeof(stack->idle_cpuset), &stack->idle_cpuset); +- if (ret != 0) { +- LSTACK_LOG(ERR, LSTACK, "thread %d setaffinity to stack %hu failed\n", rte_gettid(), stack->queue_id); +- return; +- } +-} +- + static inline void set_stack_idx(uint16_t idx) + { + g_stack_p = g_stack_group.stacks[idx]; +@@ -97,27 +83,6 @@ struct protocol_stack_group *get_protocol_stack_group(void) + return &g_stack_group; + } + +-int get_min_conn_stack(struct protocol_stack_group *stack_group) +-{ +- int min_conn_stk_idx = 0; +- int min_conn_num = GAZELLE_MAX_CLIENTS; +- for (int i = 0; i < stack_group->stack_num; i++) { +- struct protocol_stack* stack = stack_group->stacks[i]; +- if (get_global_cfg_params()->seperate_send_recv) { +- if (!stack->is_send_thread && stack->conn_num < min_conn_num) { +- min_conn_stk_idx = i; +- min_conn_num = stack->conn_num; +- } +- } else { +- if (stack->conn_num < min_conn_num) { +- min_conn_stk_idx = i; +- min_conn_num = stack->conn_num; +- } +- } +- } +- return min_conn_stk_idx; +-} +- + struct protocol_stack *get_protocol_stack(void) + { + return g_stack_p; +@@ -179,6 +144,57 @@ struct protocol_stack *get_bind_protocol_stack(void) + return stack_group->stacks[index]; + } + ++int get_min_conn_stack(struct protocol_stack_group *stack_group) ++{ ++ struct protocol_stack* stack; ++ int min_conn_stk_idx = 0; ++ int min_conn_num = GAZELLE_MAX_CLIENTS; ++ ++ for (int i = 0; i < stack_group->stack_num; i++) { ++ stack = stack_group->stacks[i]; ++ if (get_global_cfg_params()->seperate_send_recv) { ++ if (!stack->is_send_thread && stack->conn_num < min_conn_num) { ++ min_conn_stk_idx = i; ++ min_conn_num = stack->conn_num; ++ } ++ } else { ++ if (stack->conn_num < min_conn_num) { ++ min_conn_stk_idx = i; ++ min_conn_num = stack->conn_num; ++ } ++ } ++ } ++ return min_conn_stk_idx; ++} ++ ++void bind_to_stack_numa(struct protocol_stack *stack) ++{ ++ int32_t ret; ++ pthread_t tid = pthread_self(); ++ ++ ret = pthread_setaffinity_np(tid, sizeof(stack->idle_cpuset), &stack->idle_cpuset); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "thread %d setaffinity to stack %hu failed\n", rte_gettid(), stack->queue_id); ++ return; ++ } ++} ++ ++void thread_bind_stack(struct protocol_stack *stack) ++{ ++ static PER_THREAD uint16_t stack_sock_num[GAZELLE_MAX_STACK_NUM] = {0}; ++ static PER_THREAD uint16_t max_sock_stack = 0; ++ ++ if (get_global_cfg_params()->app_bind_numa == 0) { ++ return; ++ } ++ ++ stack_sock_num[stack->stack_idx]++; ++ if (stack_sock_num[stack->stack_idx] > max_sock_stack) { ++ max_sock_stack = stack_sock_num[stack->stack_idx]; ++ bind_to_stack_numa(stack); ++ } ++} ++ + static uint32_t get_protocol_traffic(struct protocol_stack *stack) + { + if (use_ltran()) { +@@ -232,6 +248,11 @@ void low_power_idling(struct protocol_stack *stack) + } + } + ++struct thread_params { ++ uint16_t queue_id; ++ uint16_t idx; ++}; ++ + static int32_t create_thread(void *arg, char *thread_name, stack_thread_func func) + { + /* thread may run slow, if arg is temp var maybe have relese */ +@@ -373,7 +394,7 @@ static int32_t init_stack_value(struct protocol_stack *stack, void *arg) + return 0; + } + +-void wait_sem_value(sem_t *sem, int32_t wait_value) ++static void wait_sem_value(sem_t *sem, int32_t wait_value) + { + int32_t sem_val; + do { +@@ -546,7 +567,7 @@ static void* gazelle_stack_thread(void *arg) + return NULL; + } + +-int32_t stack_group_init_mempool(void) ++static int stack_group_init_mempool(void) + { + struct cfg_params *cfg_params = get_global_cfg_params(); + uint32_t total_mbufs = 0; +@@ -702,655 +723,9 @@ OUT2: + return -1; + } + +-void stack_arp(struct rpc_msg *msg) +-{ +- struct rte_mbuf *mbuf = (struct rte_mbuf *)msg->args[MSG_ARG_0].p; +- struct protocol_stack *stack = get_protocol_stack(); +- +- eth_dev_recv(mbuf, stack); +-} +- +-void stack_socket(struct rpc_msg *msg) +-{ +- msg->result = lwip_socket(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i); +- if (msg->result < 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, %ld socket failed\n", get_stack_tid(), msg->result); +- } +-} +- +-void stack_close(struct rpc_msg *msg) +-{ +- int32_t fd = msg->args[MSG_ARG_0].i; +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct lwip_sock *sock = lwip_get_socket(fd); +- +- if (sock && __atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) > 0) { +- msg->recall_flag = 1; +- rpc_call(&stack->rpc_queue, msg); /* until stack_send recall finish */ +- return; +- } +- +- msg->result = lwip_close(fd); +- if (msg->result != 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d failed %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); +- } +-} +- +-void stack_shutdown(struct rpc_msg *msg) +-{ +- int fd = msg->args[MSG_ARG_0].i; +- int how = msg->args[MSG_ARG_1].i; +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- struct lwip_sock *sock = lwip_get_socket(fd); +- +- if (sock && __atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) > 0) { +- msg->recall_flag = 1; +- rpc_call(&stack->rpc_queue, msg); +- return; +- } +- +- msg->result = lwip_shutdown(fd, how); +- if (msg->result != 0 && errno != ENOTCONN) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d fail %ld\n", get_stack_tid(), fd, msg->result); +- } +- +- posix_api->shutdown_fn(fd, how); +-} +- +-void stack_bind(struct rpc_msg *msg) +-{ +- msg->result = lwip_bind(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].cp, msg->args[MSG_ARG_2].socklen); +- if (msg->result != 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d failed %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); +- } +-} +- +-void stack_listen(struct rpc_msg *msg) +-{ +- int32_t fd = msg->args[MSG_ARG_0].i; +- int32_t backlog = msg->args[MSG_ARG_1].i; +- +- struct lwip_sock *sock = lwip_get_socket(fd); +- if (sock == NULL) { +- msg->result = -1; +- return; +- } +- +- /* new listen add to stack listen list */ +- msg->result = lwip_listen(fd, backlog); +- if (msg->result != 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d failed %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); +- } +-} +- +-void stack_accept(struct rpc_msg *msg) +-{ +- int32_t fd = msg->args[MSG_ARG_0].i; +- msg->result = -1; +- struct protocol_stack *stack = get_protocol_stack(); +- +- int32_t accept_fd = lwip_accept4(fd, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].p, msg->args[MSG_ARG_3].i); +- if (accept_fd < 0) { +- stack->stats.accept_fail++; +- LSTACK_LOG(ERR, LSTACK, "fd %d ret %d\n", fd, accept_fd); +- return; +- } +- +- struct lwip_sock *sock = lwip_get_socket(accept_fd); +- if (sock == NULL || sock->stack == NULL) { +- lwip_close(accept_fd); +- LSTACK_LOG(ERR, LSTACK, "fd %d ret %d\n", fd, accept_fd); +- return; +- } +- +- msg->result = accept_fd; +- sock->stack->conn_num++; +- if (rte_ring_count(sock->conn->recvmbox->ring)) { +- do_lwip_add_recvlist(accept_fd); +- } +-} +- +-void stack_connect(struct rpc_msg *msg) +-{ +- msg->result = lwip_connect(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].socklen); +- if (msg->result < 0) { +- msg->result = -errno; +- } +-} +- +-void stack_getpeername(struct rpc_msg *msg) +-{ +- msg->result = lwip_getpeername(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].p); +- if (msg->result != 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d fail %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); +- } +-} +- +-void stack_getsockname(struct rpc_msg *msg) +-{ +- msg->result = lwip_getsockname(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].p); +- if (msg->result != 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d fail %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); +- } +-} +- +-void stack_getsockopt(struct rpc_msg *msg) +-{ +- msg->result = lwip_getsockopt(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, +- msg->args[MSG_ARG_3].p, msg->args[MSG_ARG_4].p); +- if (msg->result != 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d, level %d, optname %d, fail %ld\n", get_stack_tid(), +- msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, msg->result); +- } +-} +- +-void stack_setsockopt(struct rpc_msg *msg) +-{ +- msg->result = lwip_setsockopt(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, +- msg->args[MSG_ARG_3].cp, msg->args[MSG_ARG_4].socklen); +- if (msg->result != 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d, level %d, optname %d, fail %ld\n", get_stack_tid(), +- msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, msg->result); +- } +-} +- +-void stack_fcntl(struct rpc_msg *msg) +-{ +- msg->result = lwip_fcntl(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].l); +- if (msg->result != 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d fail %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); +- } +-} +- +-void stack_ioctl(struct rpc_msg *msg) +-{ +- msg->result = lwip_ioctl(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].l, msg->args[MSG_ARG_2].p); +- if (msg->result != 0) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d fail %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); +- } +-} +- +-void stack_recv(struct rpc_msg *msg) +-{ +- msg->result = lwip_recv(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].size, +- msg->args[MSG_ARG_3].i); +-} +- +-void stack_tcp_send(struct rpc_msg *msg) +-{ +- int32_t fd = msg->args[MSG_ARG_0].i; +- size_t len = msg->args[MSG_ARG_1].size; +- struct protocol_stack *stack = get_protocol_stack(); +- int replenish_again; +- +- struct lwip_sock *sock = lwip_get_socket(fd); +- if (POSIX_IS_CLOSED(sock)) { +- msg->result = -1; +- return; +- } +- +- if (get_protocol_stack_group()->latency_start) { +- calculate_sock_latency(&stack->latency, sock, GAZELLE_LATENCY_WRITE_RPC_MSG); +- } +- +- replenish_again = do_lwip_send(stack, sock->conn->callback_arg.socket, sock, len, 0); +- if (replenish_again < 0) { +- __sync_fetch_and_sub(&sock->call_num, 1); +- return; +- } +- +- if (NETCONN_IS_DATAOUT(sock) || replenish_again > 0) { +- if (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 1) { +- msg->recall_flag = 1; +- rpc_call(&stack->rpc_queue, msg); +- return; +- } +- } +- +- __sync_fetch_and_sub(&sock->call_num, 1); +- return; +-} +- +-void stack_udp_send(struct rpc_msg *msg) +-{ +- int32_t fd = msg->args[MSG_ARG_0].i; +- size_t len = msg->args[MSG_ARG_1].size; +- struct protocol_stack *stack = get_protocol_stack(); +- int replenish_again; +- +- struct lwip_sock *sock = lwip_get_socket(fd); +- if (POSIX_IS_CLOSED(sock)) { +- msg->result = -1; +- return; +- } +- +- if (get_protocol_stack_group()->latency_start) { +- calculate_sock_latency(&stack->latency, sock, GAZELLE_LATENCY_WRITE_RPC_MSG); +- } +- +- replenish_again = do_lwip_send(stack, sock->conn->callback_arg.socket, sock, len, 0); +- if ((replenish_again > 0) && (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 1)) { +- rpc_call_replenish(&stack->rpc_queue, sock); +- return; +- } +- +- __sync_fetch_and_sub(&sock->call_num, 1); +- return; +-} +- +-/* any protocol stack thread receives arp packet and sync it to other threads so that it can have the arp table */ +-void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack) +-{ +- struct protocol_stack_group *stack_group = get_protocol_stack_group(); +- struct rte_mbuf *mbuf_copy = NULL; +- struct protocol_stack *stack = NULL; +- int32_t ret; +- +- for (int32_t i = 0; i < stack_group->stack_num; i++) { +- stack = stack_group->stacks[i]; +- if (cur_stack == stack) { +- continue; +- } +- +- /* stack maybe not init in app thread yet */ +- if (stack == NULL || !(netif_is_up(&stack->netif))) { +- continue; +- } +- +- ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); +- if (ret != 0) { +- stack->stats.rx_allocmbuf_fail++; +- return; +- } +- copy_mbuf(mbuf_copy, mbuf); +- +- ret = rpc_call_arp(&stack->rpc_queue, mbuf_copy); +- if (ret != 0) { +- rte_pktmbuf_free(mbuf_copy); +- return; +- } +- } +-#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) +- if (get_global_cfg_params()->kni_switch) { +- ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); +- if (ret != 0) { +- cur_stack->stats.rx_allocmbuf_fail++; +- return; +- } +- copy_mbuf(mbuf_copy, mbuf); +- kni_handle_tx(mbuf_copy); +- } +-#endif +- if (get_global_cfg_params()->flow_bifurcation) { +- ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); +- if (ret != 0) { +- cur_stack->stats.rx_allocmbuf_fail++; +- return; +- } +- copy_mbuf(mbuf_copy, mbuf); +- virtio_tap_process_tx(cur_stack->queue_id, mbuf_copy); +- } +- return; +-} +- +-void stack_broadcast_clean_epoll(struct wakeup_poll *wakeup) +-{ +- struct protocol_stack_group *stack_group = get_protocol_stack_group(); +- struct protocol_stack *stack = NULL; +- +- for (int32_t i = 0; i < stack_group->stack_num; i++) { +- stack = stack_group->stacks[i]; +- rpc_call_clean_epoll(&stack->rpc_queue, wakeup); +- } +-} +- +-void stack_clean_epoll(struct rpc_msg *msg) +-{ +- struct protocol_stack *stack = get_protocol_stack(); +- struct wakeup_poll *wakeup = (struct wakeup_poll *)msg->args[MSG_ARG_0].p; +- +- list_del_node(&wakeup->wakeup_list[stack->stack_idx]); +-} +- +-void stack_mempool_size(struct rpc_msg *msg) +-{ +- struct protocol_stack *stack = get_protocol_stack(); +- +- msg->result = rte_mempool_avail_count(stack->rxtx_mbuf_pool); +-} +- +-void stack_create_shadow_fd(struct rpc_msg *msg) +-{ +- int32_t fd = msg->args[MSG_ARG_0].i; +- struct sockaddr *addr = msg->args[MSG_ARG_1].p; +- socklen_t addr_len = msg->args[MSG_ARG_2].socklen; +- +- int32_t clone_fd = 0; +- struct lwip_sock *sock = lwip_get_socket(fd); +- if (sock == NULL) { +- LSTACK_LOG(ERR, LSTACK, "get sock null fd=%d\n", fd); +- msg->result = -1; +- return; +- } +- +- int domain = addr->sa_family; +- int type = NETCONN_IS_UDP(sock) ? SOCK_DGRAM : SOCK_STREAM; +- clone_fd = lwip_socket(domain, type, 0); +- if (clone_fd < 0) { +- LSTACK_LOG(ERR, LSTACK, "clone socket failed clone_fd=%d errno=%d\n", clone_fd, errno); +- msg->result = clone_fd; +- return; +- } +- +- struct lwip_sock *clone_sock = lwip_get_socket(clone_fd); +- if (clone_sock == NULL) { +- LSTACK_LOG(ERR, LSTACK, "get sock null fd=%d clone_fd=%d\n", fd, clone_fd); +- msg->result = -1; +- return; +- } +- +- do_lwip_clone_sockopt(clone_sock, sock); +- +- while (sock->listen_next) { +- sock = sock->listen_next; +- } +- sock->listen_next = clone_sock; +- +- int32_t ret = lwip_bind(clone_fd, addr, addr_len); +- if (ret < 0) { +- LSTACK_LOG(ERR, LSTACK, "clone bind failed clone_fd=%d errno=%d\n", clone_fd, errno); +- msg->result = ret; +- return; +- } +- +- msg->result = clone_fd; +-} +- +-void stack_replenish_sendring(struct rpc_msg *msg) +-{ +- struct protocol_stack *stack = get_protocol_stack(); +- struct lwip_sock *sock = (struct lwip_sock *)msg->args[MSG_ARG_0].p; +- +- msg->result = do_lwip_replenish_sendring(stack, sock); +- if (msg->result == true) { +- msg->recall_flag = 1; +- rpc_call(&stack->rpc_queue, msg); +- } +-} +- +-void stack_get_conntable(struct rpc_msg *msg) +-{ +- struct gazelle_stat_lstack_conn_info *conn = (struct gazelle_stat_lstack_conn_info *)msg->args[MSG_ARG_0].p; +- uint32_t max_num = msg->args[MSG_ARG_1].u; +- +- msg->result = do_lwip_get_conntable(conn, max_num); +-} +- +-void stack_get_connnum(struct rpc_msg *msg) +-{ +- msg->result = do_lwip_get_connnum(); +-} +- +-void stack_recvlist_count(struct rpc_msg *msg) +-{ +- struct protocol_stack *stack = get_protocol_stack(); +- struct list_node *list = &stack->recv_list; +- uint32_t count = 0; +- struct list_node *node; +- struct list_node *temp; +- +- list_for_each_node(node, temp, list) { +- count++; +- } +- +- msg->result = count; +-} +- +-/* when fd is listenfd, listenfd of all protocol stack thread will be closed */ +-int32_t stack_broadcast_close(int32_t fd) +-{ +- int32_t ret = 0; +- struct lwip_sock *sock = lwip_get_socket(fd); +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- if (sock == NULL) { +- GAZELLE_RETURN(EBADF); +- } +- +- do { +- sock = sock->listen_next; +- if (stack == NULL || rpc_call_close(&stack->rpc_queue, fd)) { +- ret = -1; +- } +- +- if (POSIX_IS_CLOSED(sock)) { +- break; +- } +- fd = sock->conn->callback_arg.socket; +- stack = get_protocol_stack_by_fd(fd); +- } while (1); +- +- return ret; +-} +- +-int stack_broadcast_shutdown(int fd, int how) +-{ +- int32_t ret = 0; +- struct lwip_sock *sock = lwip_get_socket(fd); +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- if (sock == NULL) { +- GAZELLE_RETURN(EBADF); +- } +- +- do { +- sock = sock->listen_next; +- if (stack == NULL || rpc_call_shutdown(&stack->rpc_queue, fd, how)) { +- ret = -1; +- } +- +- if (POSIX_IS_CLOSED(sock)) { +- break; +- } +- fd = sock->conn->callback_arg.socket; +- stack = get_protocol_stack_by_fd(fd); +- } while (1); +- +- return ret; +-} +- +-/* choice one stack listen */ +-int32_t stack_single_listen(int32_t fd, int32_t backlog) +-{ +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- if (stack == NULL) { +- GAZELLE_RETURN(EBADF); +- } +- return rpc_call_listen(&stack->rpc_queue, fd, backlog); +-} +- +-/* listen sync to all protocol stack thread, so that any protocol stack thread can build connect */ +-int32_t stack_broadcast_listen(int32_t fd, int32_t backlog) +-{ +- typedef union sockaddr_union { +- struct sockaddr sa; +- struct sockaddr_in in; +- struct sockaddr_in6 in6; +- } sockaddr_t; +- +- struct protocol_stack *cur_stack = get_protocol_stack_by_fd(fd); +- struct protocol_stack *stack = NULL; +- sockaddr_t addr; +- socklen_t addr_len = sizeof(addr); +- int32_t ret, clone_fd; +- +- struct lwip_sock *sock = lwip_get_socket(fd); +- if (sock == NULL || cur_stack == NULL) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, %d get sock null or stack null\n", get_stack_tid(), fd); +- GAZELLE_RETURN(EBADF); +- } +- +- ret = rpc_call_getsockname(&cur_stack->rpc_queue, fd, (struct sockaddr *)&addr, &addr_len); +- if (ret != 0) { +- return ret; +- } +- +- struct protocol_stack_group *stack_group = get_protocol_stack_group(); +- int min_conn_stk_idx = get_min_conn_stack(stack_group); +- +- for (int32_t i = 0; i < stack_group->stack_num; ++i) { +- stack = stack_group->stacks[i]; +- if (get_global_cfg_params()->seperate_send_recv && stack->is_send_thread) { +- continue; +- } +- if (stack != cur_stack) { +- clone_fd = rpc_call_shadow_fd(&stack->rpc_queue, fd, (struct sockaddr *)&addr, addr_len); +- if (clone_fd < 0) { +- stack_broadcast_close(fd); +- return clone_fd; +- } +- } else { +- clone_fd = fd; +- } +- +- if (min_conn_stk_idx == i) { +- lwip_get_socket(clone_fd)->conn->is_master_fd = 1; +- } else { +- lwip_get_socket(clone_fd)->conn->is_master_fd = 0; +- } +- +- ret = rpc_call_listen(&stack->rpc_queue, clone_fd, backlog); +- if (ret < 0) { +- stack_broadcast_close(fd); +- return ret; +- } +- } +- return 0; +-} +- +-static struct lwip_sock *get_min_accept_sock(int32_t fd) +-{ +- struct lwip_sock *sock = lwip_get_socket(fd); +- struct lwip_sock *min_sock = NULL; +- +- while (sock) { +- if (!NETCONN_IS_ACCEPTIN(sock)) { +- sock = sock->listen_next; +- continue; +- } +- +- if (min_sock == NULL || min_sock->stack->conn_num > sock->stack->conn_num) { +- min_sock = sock; +- } +- +- sock = sock->listen_next; +- } +- +- return min_sock; +-} +- +-static void inline del_accept_in_event(struct lwip_sock *sock) +-{ +- pthread_spin_lock(&sock->wakeup->event_list_lock); +- +- if (!NETCONN_IS_ACCEPTIN(sock)) { +- sock->events &= ~EPOLLIN; +- if (sock->events == 0) { +- list_del_node(&sock->event_list); +- } +- } +- +- pthread_spin_unlock(&sock->wakeup->event_list_lock); +-} +- +-/* choice one stack bind */ +-int32_t stack_single_bind(int32_t fd, const struct sockaddr *name, socklen_t namelen) +-{ +- struct protocol_stack *stack = get_protocol_stack_by_fd(fd); +- if (stack == NULL) { +- GAZELLE_RETURN(EBADF); +- } +- return rpc_call_bind(&stack->rpc_queue, fd, name, namelen); +-} +- +-/* bind sync to all protocol stack thread, so that any protocol stack thread can build connect */ +-int32_t stack_broadcast_bind(int32_t fd, const struct sockaddr *name, socklen_t namelen) +-{ +- struct protocol_stack *cur_stack = get_protocol_stack_by_fd(fd); +- struct protocol_stack *stack = NULL; +- int32_t ret, clone_fd; +- +- struct lwip_sock *sock = lwip_get_socket(fd); +- if (sock == NULL || cur_stack == NULL) { +- LSTACK_LOG(ERR, LSTACK, "tid %ld, %d get sock null or stack null\n", get_stack_tid(), fd); +- GAZELLE_RETURN(EBADF); +- } +- +- ret = rpc_call_bind(&cur_stack->rpc_queue, fd, name, namelen); +- if (ret < 0) { +- close(fd); +- return ret; +- } +- +- struct protocol_stack_group *stack_group = get_protocol_stack_group(); +- for (int32_t i = 0; i < stack_group->stack_num; ++i) { +- stack = stack_group->stacks[i]; +- if (stack != cur_stack) { +- clone_fd = rpc_call_shadow_fd(&stack->rpc_queue, fd, name, namelen); +- if (clone_fd < 0) { +- stack_broadcast_close(fd); +- return clone_fd; +- } +- } +- } +- return 0; +-} +- +-/* ergodic the protocol stack thread to find the connection, because all threads are listening */ +-int32_t stack_broadcast_accept4(int32_t fd, struct sockaddr *addr, socklen_t *addrlen, int flags) +-{ +- int32_t ret = -1; +- struct lwip_sock *min_sock = NULL; +- struct lwip_sock *sock = lwip_get_socket(fd); +- struct protocol_stack *stack = NULL; +- if (sock == NULL) { +- GAZELLE_RETURN(EBADF); +- } +- +- if (netconn_is_nonblocking(sock->conn)) { +- min_sock = get_min_accept_sock(fd); +- } else { +- while ((min_sock = get_min_accept_sock(fd)) == NULL) { +- lstack_block_wait(sock->wakeup, 0); +- } +- } +- +- if (min_sock && min_sock->conn) { +- stack = get_protocol_stack_by_fd(min_sock->conn->callback_arg.socket); +- if (stack == NULL) { +- GAZELLE_RETURN(EBADF); +- } +- ret = rpc_call_accept(&stack->rpc_queue, min_sock->conn->callback_arg.socket, addr, addrlen, flags); +- } +- +- if (min_sock && min_sock->wakeup && min_sock->wakeup->type == WAKEUP_EPOLL) { +- del_accept_in_event(min_sock); +- } +- +- if (ret < 0) { +- errno = EAGAIN; +- } +- return ret; +-} +- +-int32_t stack_broadcast_accept(int32_t fd, struct sockaddr *addr, socklen_t *addrlen) +-{ +- if (get_global_cfg_params()->nonblock_mode) +- return stack_broadcast_accept4(fd, addr, addrlen, O_NONBLOCK); +- else +- return stack_broadcast_accept4(fd, addr, addrlen, 0); +-} +- +-static void stack_all_fds_close(void) ++void stack_exit(void) + { ++ /* close all fd */ + for (int i = 3; i < GAZELLE_MAX_CLIENTS + GAZELLE_RESERVED_CLIENTS; i++) { + struct lwip_sock *sock = lwip_get_socket(i); + if (!POSIX_IS_CLOSED(sock) && sock->stack == get_protocol_stack()) { +@@ -1359,16 +734,6 @@ static void stack_all_fds_close(void) + } + } + +-static void stack_exit(void) +-{ +- stack_all_fds_close(); +-} +- +-void stack_exit_by_rpc(struct rpc_msg *msg) +-{ +- stack_exit(); +-} +- + void stack_group_exit(void) + { + int i; +diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c +index 8ac06cb..3e9889a 100644 +--- a/src/lstack/core/lstack_thread_rpc.c ++++ b/src/lstack/core/lstack_thread_rpc.c +@@ -13,22 +13,27 @@ + #include + #include + ++#include "lwip/lwipgz_posix_api.h" ++ + #include "lstack_log.h" + #include "lstack_cfg.h" + #include "lstack_dpdk.h" +-#include "lstack_rpc_proc.h" + #include "lstack_stack_stat.h" + #include "lstack_protocol_stack.h" + #include "lstack_thread_rpc.h" ++#include "lstack_epoll.h" ++#include "lstack_lwip.h" + + static PER_THREAD struct rpc_msg_pool *g_rpc_pool = NULL; + static struct rpc_stats g_rpc_stats; ++ + struct rpc_stats *rpc_stats_get(void) + { + return &g_rpc_stats; + } + +-static inline __attribute__((always_inline)) struct rpc_msg *get_rpc_msg(struct rpc_msg_pool *rpc_pool) ++__rte_always_inline ++static struct rpc_msg *get_rpc_msg(struct rpc_msg_pool *rpc_pool) + { + int ret; + struct rpc_msg *msg = NULL; +@@ -42,23 +47,11 @@ static inline __attribute__((always_inline)) struct rpc_msg *get_rpc_msg(struct + + static void rpc_msg_init(struct rpc_msg *msg, rpc_msg_func func, struct rpc_msg_pool *pool) + { +- msg->rpcpool = pool; +- pthread_spin_init(&msg->lock, PTHREAD_PROCESS_PRIVATE); +- msg->func = func; +- msg->sync_flag = 1; ++ msg->func = func; ++ msg->rpcpool = pool; ++ msg->sync_flag = 1; + msg->recall_flag = 0; +-} +- +-static struct rpc_msg *rpc_msg_alloc_except(rpc_msg_func func) +-{ +- struct rpc_msg *msg = calloc(1, sizeof(struct rpc_msg)); +- if (msg == NULL) { +- return NULL; +- } +- +- rpc_msg_init(msg, func, NULL); +- +- return msg; ++ pthread_spin_init(&msg->lock, PTHREAD_PROCESS_PRIVATE); + } + + static struct rpc_msg *rpc_msg_alloc(rpc_msg_func func) +@@ -92,9 +85,27 @@ static struct rpc_msg *rpc_msg_alloc(rpc_msg_func func) + return msg; + } + +-static inline __attribute__((always_inline)) int32_t rpc_sync_call(rpc_queue *queue, struct rpc_msg *msg) ++__rte_always_inline ++static void rpc_msg_free(struct rpc_msg *msg) ++{ ++ pthread_spin_destroy(&msg->lock); ++ if (msg->rpcpool != NULL && msg->rpcpool->mempool != NULL) { ++ rte_mempool_put(msg->rpcpool->mempool, (void *)msg); ++ } else { ++ free(msg); ++ } ++} ++ ++__rte_always_inline ++static void rpc_call(rpc_queue *queue, struct rpc_msg *msg) + { +- int32_t ret; ++ lockless_queue_mpsc_push(queue, &msg->queue_node); ++} ++ ++__rte_always_inline ++static int rpc_sync_call(rpc_queue *queue, struct rpc_msg *msg) ++{ ++ int ret; + + pthread_spin_trylock(&msg->lock); + rpc_call(queue, msg); +@@ -107,12 +118,39 @@ static inline __attribute__((always_inline)) int32_t rpc_sync_call(rpc_queue *qu + return ret; + } + +-int32_t rpc_msgcnt(rpc_queue *queue) ++int rpc_msgcnt(rpc_queue *queue) + { + return lockless_queue_count(queue); + } + +-int rpc_poll_msg(rpc_queue *queue, uint32_t max_num) ++static struct rpc_msg *rpc_msg_alloc_except(rpc_msg_func func) ++{ ++ struct rpc_msg *msg = calloc(1, sizeof(struct rpc_msg)); ++ if (msg == NULL) { ++ return NULL; ++ } ++ ++ rpc_msg_init(msg, func, NULL); ++ return msg; ++} ++ ++static void stack_exit_by_rpc(struct rpc_msg *msg) ++{ ++ stack_exit(); ++} ++ ++int rpc_call_stack_exit(rpc_queue *queue) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc_except(stack_exit_by_rpc); ++ if (msg == NULL) { ++ return -1; ++ } ++ ++ rpc_call(queue, msg); ++ return 0; ++} ++ ++int rpc_poll_msg(rpc_queue *queue, int max_num) + { + int force_quit = 0; + struct rpc_msg *msg = NULL; +@@ -149,101 +187,165 @@ int rpc_poll_msg(rpc_queue *queue, uint32_t max_num) + return force_quit; + } + +-int32_t rpc_call_conntable(rpc_queue *queue, void *conn_table, uint32_t max_conn) ++ ++static void callback_socket(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_get_conntable); +- if (msg == NULL) { +- return -1; ++ msg->result = lwip_socket(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i); ++ if (msg->result < 0) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, %ld socket failed\n", get_stack_tid(), msg->result); + } +- +- msg->args[MSG_ARG_0].p = conn_table; +- msg->args[MSG_ARG_1].u = max_conn; +- +- return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_connnum(rpc_queue *queue) ++static void callback_close(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_get_connnum); +- if (msg == NULL) { +- return -1; ++ int fd = msg->args[MSG_ARG_0].i; ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ ++ if (sock && __atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) > 0) { ++ msg->recall_flag = 1; ++ rpc_call(&stack->rpc_queue, msg); /* until stack_send recall finish */ ++ return; + } + +- return rpc_sync_call(queue, msg); ++ msg->result = lwip_close(fd); ++ if (msg->result != 0) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d failed %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); ++ } + } + +-int32_t rpc_call_shadow_fd(rpc_queue *queue, int32_t fd, const struct sockaddr *addr, socklen_t addrlen) ++static void callback_shutdown(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_create_shadow_fd); +- if (msg == NULL) { +- return -1; ++ int fd = msg->args[MSG_ARG_0].i; ++ int how = msg->args[MSG_ARG_1].i; ++ struct protocol_stack *stack = get_protocol_stack_by_fd(fd); ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ ++ if (sock && __atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) > 0) { ++ msg->recall_flag = 1; ++ rpc_call(&stack->rpc_queue, msg); ++ return; + } + +- msg->args[MSG_ARG_0].i = fd; +- msg->args[MSG_ARG_1].cp = addr; +- msg->args[MSG_ARG_2].socklen = addrlen; ++ msg->result = lwip_shutdown(fd, how); ++ if (msg->result != 0 && errno != ENOTCONN) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d fail %ld\n", get_stack_tid(), fd, msg->result); ++ } + +- return rpc_sync_call(queue, msg); ++ posix_api->shutdown_fn(fd, how); + } + +-int32_t rpc_call_thread_regphase1(rpc_queue *queue, void *conn) ++static void callback_bind(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(thread_register_phase1); +- if (msg == NULL) { +- return -1; ++ msg->result = lwip_bind(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].cp, msg->args[MSG_ARG_2].socklen); ++ if (msg->result != 0) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d failed %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); + } +- msg->args[MSG_ARG_0].p = conn; +- return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_thread_regphase2(rpc_queue *queue, void *conn) ++static void callback_listen(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(thread_register_phase2); +- if (msg == NULL) { +- return -1; ++ int fd = msg->args[MSG_ARG_0].i; ++ int backlog = msg->args[MSG_ARG_1].i; ++ ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ if (sock == NULL) { ++ msg->result = -1; ++ return; ++ } ++ ++ /* new listen add to stack listen list */ ++ msg->result = lwip_listen(fd, backlog); ++ if (msg->result != 0) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d failed %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); + } +- msg->args[MSG_ARG_0].p = conn; +- return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_mbufpoolsize(rpc_queue *queue) ++static void callback_create_shadow_fd(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_mempool_size); +- if (msg == NULL) { +- return -1; ++ int fd = msg->args[MSG_ARG_0].i; ++ struct sockaddr *addr = msg->args[MSG_ARG_1].p; ++ socklen_t addr_len = msg->args[MSG_ARG_2].socklen; ++ ++ int clone_fd = 0; ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ if (sock == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "get sock null fd=%d\n", fd); ++ msg->result = -1; ++ return; + } + +- return rpc_sync_call(queue, msg); +-} ++ int domain = addr->sa_family; ++ int type = NETCONN_IS_UDP(sock) ? SOCK_DGRAM : SOCK_STREAM; ++ clone_fd = lwip_socket(domain, type, 0); ++ if (clone_fd < 0) { ++ LSTACK_LOG(ERR, LSTACK, "clone socket failed clone_fd=%d errno=%d\n", clone_fd, errno); ++ msg->result = clone_fd; ++ return; ++ } + +-int32_t rpc_call_recvlistcnt(rpc_queue *queue) +-{ +- struct rpc_msg *msg = rpc_msg_alloc(stack_recvlist_count); +- if (msg == NULL) { +- return -1; ++ struct lwip_sock *clone_sock = lwip_get_socket(clone_fd); ++ if (clone_sock == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "get sock null fd=%d clone_fd=%d\n", fd, clone_fd); ++ msg->result = -1; ++ return; + } + +- return rpc_sync_call(queue, msg); ++ do_lwip_clone_sockopt(clone_sock, sock); ++ ++ while (sock->listen_next) { ++ sock = sock->listen_next; ++ } ++ sock->listen_next = clone_sock; ++ ++ int ret = lwip_bind(clone_fd, addr, addr_len); ++ if (ret < 0) { ++ LSTACK_LOG(ERR, LSTACK, "clone bind failed clone_fd=%d errno=%d\n", clone_fd, errno); ++ msg->result = ret; ++ return; ++ } ++ ++ msg->result = clone_fd; + } + +-int32_t rpc_call_arp(rpc_queue *queue, void *mbuf) ++static void callback_accept(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_arp); +- if (msg == NULL) { +- return -1; ++ int fd = msg->args[MSG_ARG_0].i; ++ msg->result = -1; ++ struct protocol_stack *stack = get_protocol_stack(); ++ ++ int accept_fd = lwip_accept4(fd, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].p, msg->args[MSG_ARG_3].i); ++ if (accept_fd < 0) { ++ stack->stats.accept_fail++; ++ LSTACK_LOG(ERR, LSTACK, "fd %d ret %d\n", fd, accept_fd); ++ return; + } + +- msg->sync_flag = 0; +- msg->args[MSG_ARG_0].p = mbuf; ++ struct lwip_sock *sock = lwip_get_socket(accept_fd); ++ if (sock == NULL || sock->stack == NULL) { ++ lwip_close(accept_fd); ++ LSTACK_LOG(ERR, LSTACK, "fd %d ret %d\n", fd, accept_fd); ++ return; ++ } + +- rpc_call(queue, msg); ++ msg->result = accept_fd; ++ sock->stack->conn_num++; ++ if (rte_ring_count(sock->conn->recvmbox->ring)) { ++ do_lwip_add_recvlist(accept_fd); ++ } ++} + +- return 0; ++static void callback_connect(struct rpc_msg *msg) ++{ ++ msg->result = lwip_connect(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].socklen); ++ if (msg->result < 0) { ++ msg->result = -errno; ++ } + } + +-int32_t rpc_call_socket(rpc_queue *queue, int32_t domain, int32_t type, int32_t protocol) ++int rpc_call_socket(rpc_queue *queue, int domain, int type, int protocol) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_socket); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_socket); + if (msg == NULL) { + return -1; + } +@@ -255,9 +357,9 @@ int32_t rpc_call_socket(rpc_queue *queue, int32_t domain, int32_t type, int32_t + return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_close(rpc_queue *queue, int fd) ++int rpc_call_close(rpc_queue *queue, int fd) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_close); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_close); + if (msg == NULL) { + return -1; + } +@@ -267,20 +369,9 @@ int32_t rpc_call_close(rpc_queue *queue, int fd) + return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_stack_exit(rpc_queue *queue) ++int rpc_call_shutdown(rpc_queue *queue, int fd, int how) + { +- struct rpc_msg *msg = rpc_msg_alloc_except(stack_exit_by_rpc); +- if (msg == NULL) { +- return -1; +- } +- +- rpc_call(queue, msg); +- return 0; +-} +- +-int32_t rpc_call_shutdown(rpc_queue *queue, int fd, int how) +-{ +- struct rpc_msg *msg = rpc_msg_alloc(stack_shutdown); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_shutdown); + if (msg == NULL) { + return -1; + } +@@ -291,48 +382,50 @@ int32_t rpc_call_shutdown(rpc_queue *queue, int fd, int how) + return rpc_sync_call(queue, msg); + } + +-void rpc_call_clean_epoll(rpc_queue *queue, void *wakeup) ++int rpc_call_bind(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_clean_epoll); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_bind); + if (msg == NULL) { +- return; ++ return -1; + } + +- msg->args[MSG_ARG_0].p = wakeup; ++ msg->args[MSG_ARG_0].i = fd; ++ msg->args[MSG_ARG_1].cp = addr; ++ msg->args[MSG_ARG_2].socklen = addrlen; + +- rpc_sync_call(queue, msg); ++ return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_bind(rpc_queue *queue, int32_t fd, const struct sockaddr *addr, socklen_t addrlen) ++int rpc_call_listen(rpc_queue *queue, int s, int backlog) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_bind); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_listen); + if (msg == NULL) { + return -1; + } + +- msg->args[MSG_ARG_0].i = fd; +- msg->args[MSG_ARG_1].cp = addr; +- msg->args[MSG_ARG_2].socklen = addrlen; ++ msg->args[MSG_ARG_0].i = s; ++ msg->args[MSG_ARG_1].i = backlog; + + return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_listen(rpc_queue *queue, int s, int backlog) ++int rpc_call_shadow_fd(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_listen); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_create_shadow_fd); + if (msg == NULL) { + return -1; + } + +- msg->args[MSG_ARG_0].i = s; +- msg->args[MSG_ARG_1].i = backlog; ++ msg->args[MSG_ARG_0].i = fd; ++ msg->args[MSG_ARG_1].cp = addr; ++ msg->args[MSG_ARG_2].socklen = addrlen; + + return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_accept(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen, int flags) ++int rpc_call_accept(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen, int flags) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_accept); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_accept); + if (msg == NULL) { + return -1; + } +@@ -345,9 +438,9 @@ int32_t rpc_call_accept(rpc_queue *queue, int fd, struct sockaddr *addr, socklen + return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_connect(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen) ++int rpc_call_connect(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_connect); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_connect); + if (msg == NULL) { + return -1; + } +@@ -356,7 +449,7 @@ int32_t rpc_call_connect(rpc_queue *queue, int fd, const struct sockaddr *addr, + msg->args[MSG_ARG_1].cp = addr; + msg->args[MSG_ARG_2].socklen = addrlen; + +- int32_t ret = rpc_sync_call(queue, msg); ++ int ret = rpc_sync_call(queue, msg); + if (ret < 0) { + errno = -ret; + return -1; +@@ -364,9 +457,45 @@ int32_t rpc_call_connect(rpc_queue *queue, int fd, const struct sockaddr *addr, + return ret; + } + +-int32_t rpc_call_getpeername(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen) ++static void callback_getpeername(struct rpc_msg *msg) ++{ ++ msg->result = lwip_getpeername(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].p); ++ if (msg->result != 0) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d fail %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); ++ } ++} ++ ++static void callback_getsockname(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_getpeername); ++ msg->result = lwip_getsockname(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].p); ++ if (msg->result != 0) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d fail %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); ++ } ++} ++ ++static void callback_getsockopt(struct rpc_msg *msg) ++{ ++ msg->result = lwip_getsockopt(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, ++ msg->args[MSG_ARG_3].p, msg->args[MSG_ARG_4].p); ++ if (msg->result != 0) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d, level %d, optname %d, fail %ld\n", get_stack_tid(), ++ msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, msg->result); ++ } ++} ++ ++static void callback_setsockopt(struct rpc_msg *msg) ++{ ++ msg->result = lwip_setsockopt(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, ++ msg->args[MSG_ARG_3].cp, msg->args[MSG_ARG_4].socklen); ++ if (msg->result != 0) { ++ LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d, level %d, optname %d, fail %ld\n", get_stack_tid(), ++ msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, msg->result); ++ } ++} ++ ++int rpc_call_getpeername(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(callback_getpeername); + if (msg == NULL) { + return -1; + } +@@ -378,9 +507,9 @@ int32_t rpc_call_getpeername(rpc_queue *queue, int fd, struct sockaddr *addr, so + return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_getsockname(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen) ++int rpc_call_getsockname(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_getsockname); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_getsockname); + if (msg == NULL) { + return -1; + } +@@ -392,9 +521,9 @@ int32_t rpc_call_getsockname(rpc_queue *queue, int fd, struct sockaddr *addr, so + return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_getsockopt(rpc_queue *queue, int fd, int level, int optname, void *optval, socklen_t *optlen) ++int rpc_call_getsockopt(rpc_queue *queue, int fd, int level, int optname, void *optval, socklen_t *optlen) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_getsockopt); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_getsockopt); + if (msg == NULL) { + return -1; + } +@@ -408,9 +537,9 @@ int32_t rpc_call_getsockopt(rpc_queue *queue, int fd, int level, int optname, vo + return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_setsockopt(rpc_queue *queue, int fd, int level, int optname, const void *optval, socklen_t optlen) ++int rpc_call_setsockopt(rpc_queue *queue, int fd, int level, int optname, const void *optval, socklen_t optlen) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_setsockopt); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_setsockopt); + if (msg == NULL) { + return -1; + } +@@ -424,51 +553,91 @@ int32_t rpc_call_setsockopt(rpc_queue *queue, int fd, int level, int optname, co + return rpc_sync_call(queue, msg); + } + +-int32_t rpc_call_fcntl(rpc_queue *queue, int fd, int cmd, long val) ++static void callback_tcp_send(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_fcntl); +- if (msg == NULL) { +- return -1; ++ int fd = msg->args[MSG_ARG_0].i; ++ size_t len = msg->args[MSG_ARG_1].size; ++ struct protocol_stack *stack = get_protocol_stack(); ++ int replenish_again; ++ ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ if (POSIX_IS_CLOSED(sock)) { ++ msg->result = -1; ++ return; + } + +- msg->args[MSG_ARG_0].i = fd; +- msg->args[MSG_ARG_1].i = cmd; +- msg->args[MSG_ARG_2].l = val; ++ if (get_protocol_stack_group()->latency_start) { ++ calculate_sock_latency(&stack->latency, sock, GAZELLE_LATENCY_WRITE_RPC_MSG); ++ } + +- return rpc_sync_call(queue, msg); ++ replenish_again = do_lwip_send(stack, sock->conn->callback_arg.socket, sock, len, 0); ++ if (replenish_again < 0) { ++ __sync_fetch_and_sub(&sock->call_num, 1); ++ return; ++ } ++ ++ if (NETCONN_IS_DATAOUT(sock) || replenish_again > 0) { ++ if (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 1) { ++ msg->recall_flag = 1; ++ rpc_call(&stack->rpc_queue, msg); ++ return; ++ } ++ } ++ ++ __sync_fetch_and_sub(&sock->call_num, 1); ++ return; + } + +-int32_t rpc_call_ioctl(rpc_queue *queue, int fd, long cmd, void *argp) ++static void callback_udp_send(struct rpc_msg *msg) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_ioctl); +- if (msg == NULL) { +- return -1; ++ int fd = msg->args[MSG_ARG_0].i; ++ size_t len = msg->args[MSG_ARG_1].size; ++ struct protocol_stack *stack = get_protocol_stack(); ++ int replenish_again; ++ ++ struct lwip_sock *sock = lwip_get_socket(fd); ++ if (POSIX_IS_CLOSED(sock)) { ++ msg->result = -1; ++ return; + } + +- msg->args[MSG_ARG_0].i = fd; +- msg->args[MSG_ARG_1].l = cmd; +- msg->args[MSG_ARG_2].p = argp; ++ if (get_protocol_stack_group()->latency_start) { ++ calculate_sock_latency(&stack->latency, sock, GAZELLE_LATENCY_WRITE_RPC_MSG); ++ } + +- return rpc_sync_call(queue, msg); ++ replenish_again = do_lwip_send(stack, sock->conn->callback_arg.socket, sock, len, 0); ++ if ((replenish_again > 0) && (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 1)) { ++ rpc_call_replenish(&stack->rpc_queue, sock); ++ return; ++ } ++ ++ __sync_fetch_and_sub(&sock->call_num, 1); ++ return; + } + +-int32_t rpc_call_replenish(rpc_queue *queue, void *sock) ++int rpc_call_udp_send(rpc_queue *queue, int fd, size_t len, int flags) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_replenish_sendring); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_udp_send); + if (msg == NULL) { + return -1; + } + +- msg->args[MSG_ARG_0].p = sock; ++ if (get_protocol_stack_group()->latency_start) { ++ time_stamp_into_rpcmsg(lwip_get_socket(fd)); ++ } ++ ++ msg->args[MSG_ARG_0].i = fd; ++ msg->args[MSG_ARG_1].size = len; ++ msg->args[MSG_ARG_2].i = flags; + msg->sync_flag = 0; + + rpc_call(queue, msg); + return 0; + } + +-int32_t rpc_call_tcp_send(rpc_queue *queue, int fd, size_t len, int flags) ++int rpc_call_tcp_send(rpc_queue *queue, int fd, size_t len, int flags) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_tcp_send); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_tcp_send); + if (msg == NULL) { + return -1; + } +@@ -483,28 +652,173 @@ int32_t rpc_call_tcp_send(rpc_queue *queue, int fd, size_t len, int flags) + msg->sync_flag = 0; + + rpc_call(queue, msg); ++ return 0; ++} ++ ++static void callback_replenish_sendring(struct rpc_msg *msg) ++{ ++ struct protocol_stack *stack = get_protocol_stack(); ++ struct lwip_sock *sock = (struct lwip_sock *)msg->args[MSG_ARG_0].p; ++ ++ msg->result = do_lwip_replenish_sendring(stack, sock); ++ if (msg->result == true) { ++ msg->recall_flag = 1; ++ rpc_call(&stack->rpc_queue, msg); ++ } ++} ++ ++int rpc_call_replenish(rpc_queue *queue, void *sock) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(callback_replenish_sendring); ++ if (msg == NULL) { ++ return -1; ++ } + ++ msg->args[MSG_ARG_0].p = sock; ++ msg->sync_flag = 0; ++ ++ rpc_call(queue, msg); + return 0; + } + +-int32_t rpc_call_udp_send(rpc_queue *queue, int fd, size_t len, int flags) ++static void callback_recvlist_count(struct rpc_msg *msg) ++{ ++ struct protocol_stack *stack = get_protocol_stack(); ++ struct list_node *list = &stack->recv_list; ++ int count = 0; ++ struct list_node *node; ++ struct list_node *temp; ++ ++ list_for_each_node(node, temp, list) { ++ count++; ++ } ++ msg->result = count; ++} ++ ++int rpc_call_recvlistcnt(rpc_queue *queue) + { +- struct rpc_msg *msg = rpc_msg_alloc(stack_udp_send); ++ struct rpc_msg *msg = rpc_msg_alloc(callback_recvlist_count); + if (msg == NULL) { + return -1; + } + +- if (get_protocol_stack_group()->latency_start) { +- time_stamp_into_rpcmsg(lwip_get_socket(fd)); ++ return rpc_sync_call(queue, msg); ++} ++ ++static void callback_clean_epoll(struct rpc_msg *msg) ++{ ++ struct protocol_stack *stack = get_protocol_stack(); ++ struct wakeup_poll *wakeup = (struct wakeup_poll *)msg->args[MSG_ARG_0].p; ++ ++ list_del_node(&wakeup->wakeup_list[stack->stack_idx]); ++} ++ ++void rpc_call_clean_epoll(rpc_queue *queue, void *wakeup) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(callback_clean_epoll); ++ if (msg == NULL) { ++ return; ++ } ++ ++ msg->args[MSG_ARG_0].p = wakeup; ++ ++ rpc_sync_call(queue, msg); ++} ++ ++static void callback_arp(struct rpc_msg *msg) ++{ ++ struct rte_mbuf *mbuf = (struct rte_mbuf *)msg->args[MSG_ARG_0].p; ++ struct protocol_stack *stack = get_protocol_stack(); ++ ++ eth_dev_recv(mbuf, stack); ++} ++ ++int rpc_call_arp(rpc_queue *queue, void *mbuf) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(callback_arp); ++ if (msg == NULL) { ++ return -1; + } + +- msg->args[MSG_ARG_0].i = fd; +- msg->args[MSG_ARG_1].size = len; +- msg->args[MSG_ARG_2].i = flags; + msg->sync_flag = 0; ++ msg->args[MSG_ARG_0].p = mbuf; + + rpc_call(queue, msg); + + return 0; + } + ++static void callback_mempool_size(struct rpc_msg *msg) ++{ ++ struct protocol_stack *stack = get_protocol_stack(); ++ ++ msg->result = rte_mempool_avail_count(stack->rxtx_mbuf_pool); ++} ++ ++static void callback_get_conntable(struct rpc_msg *msg) ++{ ++ struct gazelle_stat_lstack_conn_info *conn = (struct gazelle_stat_lstack_conn_info *)msg->args[MSG_ARG_0].p; ++ unsigned max_num = msg->args[MSG_ARG_1].u; ++ ++ msg->result = do_lwip_get_conntable(conn, max_num); ++} ++ ++static void callback_get_connnum(struct rpc_msg *msg) ++{ ++ msg->result = do_lwip_get_connnum(); ++} ++ ++int rpc_call_conntable(rpc_queue *queue, void *conn_table, unsigned max_conn) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(callback_get_conntable); ++ if (msg == NULL) { ++ return -1; ++ } ++ ++ msg->args[MSG_ARG_0].p = conn_table; ++ msg->args[MSG_ARG_1].u = max_conn; ++ ++ return rpc_sync_call(queue, msg); ++} ++ ++int rpc_call_connnum(rpc_queue *queue) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(callback_get_connnum); ++ if (msg == NULL) { ++ return -1; ++ } ++ ++ return rpc_sync_call(queue, msg); ++} ++ ++int rpc_call_mbufpoolsize(rpc_queue *queue) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(callback_mempool_size); ++ if (msg == NULL) { ++ return -1; ++ } ++ ++ return rpc_sync_call(queue, msg); ++} ++ ++extern void thread_register_phase1(struct rpc_msg *msg); ++int rpc_call_thread_regphase1(rpc_queue *queue, void *conn) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(thread_register_phase1); ++ if (msg == NULL) { ++ return -1; ++ } ++ msg->args[MSG_ARG_0].p = conn; ++ return rpc_sync_call(queue, msg); ++} ++ ++extern void thread_register_phase2(struct rpc_msg *msg); ++int rpc_call_thread_regphase2(rpc_queue *queue, void *conn) ++{ ++ struct rpc_msg *msg = rpc_msg_alloc(thread_register_phase2); ++ if (msg == NULL) { ++ return -1; ++ } ++ msg->args[MSG_ARG_0].p = conn; ++ return rpc_sync_call(queue, msg); ++} +diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h +index d058409..965a0cb 100644 +--- a/src/lstack/include/lstack_dpdk.h ++++ b/src/lstack/include/lstack_dpdk.h +@@ -13,7 +13,10 @@ + #ifndef _GAZELLE_DPDK_H_ + #define _GAZELLE_DPDK_H_ + +-#include ++#include ++#include ++#include ++ + #include "common/gazelle_opt.h" + #include "common/gazelle_dfx_msg.h" + +@@ -32,32 +35,34 @@ + */ + #define MBUF_MAX_NUM 0xfffffff + ++struct protocol_stack; ++ ++int32_t dpdk_eal_init(void); ++void lstack_log_level_init(void); ++ ++int dpdk_ethdev_init(int port_id); ++int dpdk_ethdev_start(void); ++int init_dpdk_ethdev(void); ++ + int thread_affinity_default(void); + int thread_affinity_init(int cpu_id); + +-struct protocol_stack; +-struct rte_mempool; +-struct rte_ring; +-struct rte_mbuf; ++int32_t create_shared_ring(struct protocol_stack *stack); + int32_t fill_mbuf_to_ring(struct rte_mempool *mempool, struct rte_ring *ring, uint32_t mbuf_num); +-int32_t dpdk_eal_init(void); + int32_t pktmbuf_pool_init(struct protocol_stack *stack); + struct rte_mempool *create_mempool(const char *name, uint32_t count, uint32_t size, + uint32_t flags, int32_t idx); +-int32_t create_shared_ring(struct protocol_stack *stack); +-void lstack_log_level_init(void); +-int dpdk_ethdev_init(int port_id); +-int dpdk_ethdev_start(void); ++struct rte_mempool *create_pktmbuf_mempool(const char *name, uint32_t nb_mbuf, ++ uint32_t mbuf_cache_size, uint16_t queue_id, unsigned numa_id); ++int32_t dpdk_alloc_pktmbuf(struct rte_mempool *pool, struct rte_mbuf **mbufs, uint32_t num, bool reserve); ++ + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) + void dpdk_skip_nic_init(void); + void dpdk_restore_pci(void); + #endif + int32_t dpdk_init_lstack_kni(void); +-bool port_in_stack_queue(gz_addr_t *src_ip, gz_addr_t *dst_ip, uint16_t src_port, uint16_t dst_port); +-struct rte_mempool *create_pktmbuf_mempool(const char *name, uint32_t nb_mbuf, +- uint32_t mbuf_cache_size, uint16_t queue_id, unsigned numa_id); + + void dpdk_nic_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id); +-int32_t dpdk_alloc_pktmbuf(struct rte_mempool *pool, struct rte_mbuf **mbufs, uint32_t num, bool reserve); + void dpdk_nic_features_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id); ++ + #endif /* GAZELLE_DPDK_H */ +diff --git a/src/lstack/include/lstack_epoll.h b/src/lstack/include/lstack_epoll.h +index 6e02615..e7ae26b 100644 +--- a/src/lstack/include/lstack_epoll.h ++++ b/src/lstack/include/lstack_epoll.h +@@ -19,14 +19,11 @@ + #include + + #include ++#include + + #include "common/gazelle_dfx_msg.h" + #include "common/gazelle_opt.h" + +-#ifdef __cplusplus +-extern "C" { +-#endif +- + enum wakeup_type { + WAKEUP_EPOLL = 0, + WAKEUP_POLL, +@@ -61,9 +58,6 @@ struct wakeup_poll { + pthread_spinlock_t event_list_lock; + }; + +-struct netconn; +-struct lwip_sock; +- + void add_sock_event(struct lwip_sock *sock, uint32_t event); + void add_sock_event_nolock(struct lwip_sock *sock, uint32_t event); + void del_sock_event(struct lwip_sock *sock, uint32_t event); +@@ -91,8 +85,4 @@ static inline void lstack_block_wakeup(struct wakeup_poll *wakeup) + } + } + +-#ifdef __cplusplus +-} +-#endif +- + #endif /* _GAZELLE_EPOLL_H_ */ +diff --git a/src/lstack/include/lstack_lwip.h b/src/lstack/include/lstack_lwip.h +index b972f11..0c7bb62 100644 +--- a/src/lstack/include/lstack_lwip.h ++++ b/src/lstack/include/lstack_lwip.h +@@ -15,8 +15,12 @@ + #include + + #include "common/gazelle_dfx_msg.h" ++#include "common/dpdk_common.h" + + struct lwip_sock; ++struct rpc_msg; ++struct protocol_stack; ++ + unsigned same_node_ring_count(struct lwip_sock *sock); + + #define NETCONN_IS_ACCEPTIN(sock) (((sock)->conn->acceptmbox != NULL) && !sys_mbox_empty((sock)->conn->acceptmbox)) +@@ -25,11 +29,6 @@ unsigned same_node_ring_count(struct lwip_sock *sock); + #define NETCONN_IS_OUTIDLE(sock) gazelle_ring_readable_count((sock)->send_ring) + #define NETCONN_IS_UDP(sock) (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) == NETCONN_UDP) + +-struct rte_mempool; +-struct rpc_msg; +-struct rte_mbuf; +-struct protocol_stack; +- + void do_lwip_clone_sockopt(struct lwip_sock *dst_sock, struct lwip_sock *src_sock); + + struct pbuf *do_lwip_tcp_get_from_sendring(struct lwip_sock *sock, uint16_t remain_size); +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index 7dce757..fdd5388 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -17,6 +17,10 @@ + #include + #include + ++#include ++#include ++#include ++ + #include + #include + +@@ -35,10 +39,6 @@ + + #define MBUFPOOL_RESERVE_NUM (get_global_cfg_params()->nic.rxqueue_size + 1024) + +-struct rte_mempool; +-struct rte_ring; +-struct rte_mbuf; +- + struct protocol_stack { + uint32_t tid; + uint16_t queue_id; +@@ -111,50 +111,23 @@ struct protocol_stack_group { + }; + + long get_stack_tid(void); ++ + struct protocol_stack *get_protocol_stack(void); + struct protocol_stack *get_protocol_stack_by_fd(int32_t fd); + struct protocol_stack *get_bind_protocol_stack(void); + struct protocol_stack_group *get_protocol_stack_group(void); + ++int get_min_conn_stack(struct protocol_stack_group *stack_group); ++void bind_to_stack_numa(struct protocol_stack *stack); ++void thread_bind_stack(struct protocol_stack *stack); ++ + int32_t stack_group_init(void); + void stack_group_exit(void); ++void stack_exit(void); ++ + int32_t stack_setup_thread(void); + int32_t stack_setup_app_thread(void); + +-void bind_to_stack_numa(struct protocol_stack *stack); +-int32_t init_dpdk_ethdev(void); +- +-void wait_sem_value(sem_t *sem, int32_t wait_value); +- +-/* any protocol stack thread receives arp packet and sync it to other threads so that it can have the arp table */ +-void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack); +- +-/* when fd is listenfd, listenfd of all protocol stack thread will be closed */ +-int32_t stack_broadcast_close(int32_t fd); +- +-int stack_broadcast_shutdown(int fd, int how); +- +-/* listen sync to all protocol stack thread, so that any protocol stack thread can build connect */ +-int32_t stack_broadcast_listen(int32_t fd, int backlog); +-int32_t stack_single_listen(int32_t fd, int32_t backlog); +- +-/* bind sync to all protocol stack thread, only for udp protocol */ +-int32_t stack_broadcast_bind(int32_t fd, const struct sockaddr *name, socklen_t namelen); +-int32_t stack_single_bind(int32_t fd, const struct sockaddr *name, socklen_t namelen); +- +-/* ergodic the protocol stack thread to find the connection, because all threads are listening */ +-int32_t stack_broadcast_accept(int32_t fd, struct sockaddr *addr, socklen_t *addrlen); +-int32_t stack_broadcast_accept4(int32_t fd, struct sockaddr *addr, socklen_t *addrlen, int32_t flags); +- +-struct wakeup_poll; +-void stack_broadcast_clean_epoll(struct wakeup_poll *wakeup); +- +-void stack_send_pkts(struct protocol_stack *stack); +- +-struct thread_params { +- uint16_t queue_id; +- uint16_t idx; +-}; +- + int stack_polling(uint32_t wakeup_tick); ++ + #endif +diff --git a/src/lstack/include/lstack_rpc_proc.h b/src/lstack/include/lstack_rpc_proc.h +deleted file mode 100644 +index 77b18bd..0000000 +--- a/src/lstack/include/lstack_rpc_proc.h ++++ /dev/null +@@ -1,47 +0,0 @@ +-/* +-* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. +-* gazelle is licensed under the Mulan PSL v2. +-* You can use this software according to the terms and conditions of the Mulan PSL v2. +-* You may obtain a copy of Mulan PSL v2 at: +-* http://license.coscl.org.cn/MulanPSL2 +-* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +-* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +-* PURPOSE. +-* See the Mulan PSL v2 for more details. +-*/ +- +-#ifndef __GAZELLE_RPC_PROC_H__ +-#define __GAZELLE_RPC_PROC_H__ +-#include "lstack_thread_rpc.h" +- +-void stack_clean_epoll(struct rpc_msg *msg); +-void stack_arp(struct rpc_msg *msg); +-void stack_socket(struct rpc_msg *msg); +-void stack_close(struct rpc_msg *msg); +-void stack_shutdown(struct rpc_msg *msg); +-void stack_bind(struct rpc_msg *msg); +-void stack_listen(struct rpc_msg *msg); +-void stack_accept(struct rpc_msg *msg); +-void stack_connect(struct rpc_msg *msg); +-void stack_recv(struct rpc_msg *msg); +-void stack_getpeername(struct rpc_msg *msg); +-void stack_getsockname(struct rpc_msg *msg); +-void stack_getsockopt(struct rpc_msg *msg); +-void stack_setsockopt(struct rpc_msg *msg); +-void stack_fcntl(struct rpc_msg *msg); +-void stack_ioctl(struct rpc_msg *msg); +-void stack_tcp_send(struct rpc_msg *msg); +-void stack_udp_send(struct rpc_msg *msg); +-void stack_mempool_size(struct rpc_msg *msg); +-void stack_rpcpool_size(struct rpc_msg *msg); +-void stack_create_shadow_fd(struct rpc_msg *msg); +-void stack_replenish_sendring(struct rpc_msg *msg); +-void stack_get_conntable(struct rpc_msg *msg); +-void stack_get_connnum(struct rpc_msg *msg); +-void stack_recvlist_count(struct rpc_msg *msg); +-void stack_exit_by_rpc(struct rpc_msg *msg); +- +-void thread_register_phase1(struct rpc_msg *msg); +-void thread_register_phase2(struct rpc_msg *msg); +- +-#endif +diff --git a/src/lstack/include/lstack_thread_rpc.h b/src/lstack/include/lstack_thread_rpc.h +index d268366..c2654bb 100644 +--- a/src/lstack/include/lstack_thread_rpc.h ++++ b/src/lstack/include/lstack_thread_rpc.h +@@ -35,8 +35,8 @@ struct rpc_stats { + struct rpc_msg; + typedef void (*rpc_msg_func)(struct rpc_msg *msg); + union rpc_msg_arg { +- int32_t i; +- uint32_t u; ++ int i; ++ unsigned int u; + long l; + unsigned long ul; + void *p; +@@ -63,50 +63,43 @@ static inline void rpc_queue_init(rpc_queue *queue) + { + lockless_queue_init(queue); + } +- + struct rpc_stats *rpc_stats_get(void); +-int32_t rpc_msgcnt(rpc_queue *queue); +-int rpc_poll_msg(rpc_queue *queue, uint32_t max_num); ++int rpc_msgcnt(rpc_queue *queue); ++int rpc_poll_msg(rpc_queue *queue, int max_num); ++ ++int rpc_call_stack_exit(rpc_queue *queue); ++ ++/* #include will conflict with lwip/sockets.h */ ++struct sockaddr; ++ ++int rpc_call_close(rpc_queue *queue, int fd); ++int rpc_call_shutdown(rpc_queue *queue, int fd, int how); ++int rpc_call_socket(rpc_queue *queue, int domain, int type, int protocol); ++int rpc_call_bind(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen); ++int rpc_call_listen(rpc_queue *queue, int s, int backlog); ++int rpc_call_shadow_fd(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen); ++int rpc_call_accept(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen, int flags); ++int rpc_call_connect(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen); ++ ++int rpc_call_getpeername(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen); ++int rpc_call_getsockname(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen); ++int rpc_call_getsockopt(rpc_queue *queue, int fd, int level, int optname, void *optval, socklen_t *optlen); ++int rpc_call_setsockopt(rpc_queue *queue, int fd, int level, int optname, const void *optval, socklen_t optlen); ++ ++int rpc_call_tcp_send(rpc_queue *queue, int fd, size_t len, int flags); ++int rpc_call_udp_send(rpc_queue *queue, int fd, size_t len, int flags); ++ ++int rpc_call_replenish(rpc_queue *queue, void *sock); ++int rpc_call_recvlistcnt(rpc_queue *queue); ++ + void rpc_call_clean_epoll(rpc_queue *queue, void *wakeup); +-int32_t rpc_call_shadow_fd(rpc_queue *queue, int32_t fd, const struct sockaddr *addr, socklen_t addrlen); +-int32_t rpc_call_recvlistcnt(rpc_queue *queue); +-int32_t rpc_call_thread_regphase1(rpc_queue *queue, void *conn); +-int32_t rpc_call_thread_regphase2(rpc_queue *queue, void *conn); +-int32_t rpc_call_conntable(rpc_queue *queue, void *conn_table, uint32_t max_conn); +-int32_t rpc_call_connnum(rpc_queue *queue); +-int32_t rpc_call_arp(rpc_queue *queue, void *mbuf); +-int32_t rpc_call_socket(rpc_queue *queue, int32_t domain, int32_t type, int32_t protocol); +-int32_t rpc_call_close(rpc_queue *queue, int32_t fd); +-int32_t rpc_call_shutdown(rpc_queue *queue, int fd, int how); +-int32_t rpc_call_bind(rpc_queue *queue, int32_t fd, const struct sockaddr *addr, socklen_t addrlen); +-int32_t rpc_call_listen(rpc_queue *queue, int s, int backlog); +-int32_t rpc_call_accept(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen, int flags); +-int32_t rpc_call_connect(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen_t addrlen); +-int32_t rpc_call_tcp_send(rpc_queue *queue, int fd, size_t len, int flags); +-int32_t rpc_call_udp_send(rpc_queue *queue, int fd, size_t len, int flags); +-int32_t rpc_call_getpeername(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen); +-int32_t rpc_call_getsockname(rpc_queue *queue, int fd, struct sockaddr *addr, socklen_t *addrlen); +-int32_t rpc_call_getsockopt(rpc_queue *queue, int fd, int level, int optname, void *optval, socklen_t *optlen); +-int32_t rpc_call_setsockopt(rpc_queue *queue, int fd, int level, int optname, const void *optval, socklen_t optlen); +-int32_t rpc_call_fcntl(rpc_queue *queue, int fd, int cmd, long val); +-int32_t rpc_call_ioctl(rpc_queue *queue, int fd, long cmd, void *argp); +-int32_t rpc_call_replenish(rpc_queue *queue, void *sock); +-int32_t rpc_call_mbufpoolsize(rpc_queue *queue); +-int32_t rpc_call_stack_exit(rpc_queue *queue); +- +-static inline __attribute__((always_inline)) void rpc_call(rpc_queue *queue, struct rpc_msg *msg) +-{ +- lockless_queue_mpsc_push(queue, &msg->queue_node); +-} ++int rpc_call_arp(rpc_queue *queue, void *mbuf); + +-static inline __attribute__((always_inline)) void rpc_msg_free(struct rpc_msg *msg) +-{ +- pthread_spin_destroy(&msg->lock); +- if (msg->rpcpool != NULL && msg->rpcpool->mempool != NULL) { +- rte_mempool_put(msg->rpcpool->mempool, (void *)msg); +- } else { +- free(msg); +- } +-} ++int rpc_call_conntable(rpc_queue *queue, void *conn_table, unsigned max_conn); ++int rpc_call_connnum(rpc_queue *queue); ++int rpc_call_mbufpoolsize(rpc_queue *queue); ++ ++int rpc_call_thread_regphase1(rpc_queue *queue, void *conn); ++int rpc_call_thread_regphase2(rpc_queue *queue, void *conn); + + #endif +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index cf66e15..4f3cbc1 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -43,6 +43,62 @@ + #define MBUF_MAX_LEN 1514 + #define PACKET_READ_SIZE 32 + ++/* any protocol stack thread receives arp packet and sync it to other threads, ++ * so that it can have the arp table */ ++static void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack) ++{ ++ struct protocol_stack_group *stack_group = get_protocol_stack_group(); ++ struct rte_mbuf *mbuf_copy = NULL; ++ struct protocol_stack *stack = NULL; ++ int32_t ret; ++ ++ for (int32_t i = 0; i < stack_group->stack_num; i++) { ++ stack = stack_group->stacks[i]; ++ if (cur_stack == stack) { ++ continue; ++ } ++ ++ /* stack maybe not init in app thread yet */ ++ if (stack == NULL || !(netif_is_up(&stack->netif))) { ++ continue; ++ } ++ ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); ++ if (ret != 0) { ++ stack->stats.rx_allocmbuf_fail++; ++ return; ++ } ++ copy_mbuf(mbuf_copy, mbuf); ++ ++ ret = rpc_call_arp(&stack->rpc_queue, mbuf_copy); ++ if (ret != 0) { ++ rte_pktmbuf_free(mbuf_copy); ++ return; ++ } ++ } ++#if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) ++ if (get_global_cfg_params()->kni_switch) { ++ ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); ++ if (ret != 0) { ++ cur_stack->stats.rx_allocmbuf_fail++; ++ return; ++ } ++ copy_mbuf(mbuf_copy, mbuf); ++ kni_handle_tx(mbuf_copy); ++ } ++#endif ++ if (get_global_cfg_params()->flow_bifurcation) { ++ ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); ++ if (ret != 0) { ++ cur_stack->stats.rx_allocmbuf_fail++; ++ return; ++ } ++ copy_mbuf(mbuf_copy, mbuf); ++ virtio_tap_process_tx(cur_stack->queue_id, mbuf_copy); ++ } ++ return; ++} ++ + void eth_dev_recv(struct rte_mbuf *mbuf, struct protocol_stack *stack) + { + int32_t ret; +-- +2.33.0 + diff --git a/0259-cleancode-add-rpc_async_call-remove-rpc_msg_arg.sock.patch b/0259-cleancode-add-rpc_async_call-remove-rpc_msg_arg.sock.patch new file mode 100644 index 0000000..1d2c323 --- /dev/null +++ b/0259-cleancode-add-rpc_async_call-remove-rpc_msg_arg.sock.patch @@ -0,0 +1,693 @@ +From 710bb34f1b46e0df4d82fe46fc36e729160ea1d7 Mon Sep 17 00:00:00 2001 +From: Lemmy Huang +Date: Sun, 1 Sep 2024 00:21:52 +0800 +Subject: [PATCH] cleancode: add rpc_async_call, remove rpc_msg_arg.socklen, + fix some format + +Signed-off-by: Lemmy Huang +--- + src/lstack/core/lstack_lwip.c | 27 +---- + src/lstack/core/lstack_protocol_stack.c | 25 ++--- + src/lstack/core/lstack_thread_rpc.c | 124 +++++++++++---------- + src/lstack/include/lstack_lwip.h | 27 +++-- + src/lstack/include/lstack_protocol_stack.h | 13 +-- + src/lstack/include/lstack_thread_rpc.h | 25 +++-- + 6 files changed, 117 insertions(+), 124 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 3454961..91f4838 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -588,23 +588,6 @@ bool do_lwip_replenish_sendring(struct protocol_stack *stack, struct lwip_sock * + return replenish_again; + } + +-int do_lwip_send(struct protocol_stack *stack, int32_t fd, struct lwip_sock *sock, +- size_t len, int32_t flags) +-{ +- ssize_t ret; +- /* send all send_ring, so len set lwip send max. */ +- if (NETCONN_IS_UDP(sock)) { +- ret = lwip_send(fd, sock, len, flags); +- } else { +- ret = lwip_send(fd, sock, UINT16_MAX, flags); +- } +- if (ret < 0 && (errno == ENOTCONN || errno == ECONNRESET || errno == ECONNABORTED)) { +- return -1; +- } +- +- return do_lwip_replenish_sendring(stack, sock); +-} +- + static inline void free_recv_ring_readover(struct rte_ring *ring) + { + void *pbufs[SOCK_RECV_RING_SIZE]; +@@ -753,10 +736,10 @@ static inline void notice_stack_tcp_send(struct lwip_sock *sock, int32_t fd, int + + static inline void notice_stack_udp_send(struct lwip_sock *sock, int32_t fd, int32_t len, int32_t flags) + { +- __sync_fetch_and_add(&sock->call_num, 1); +- while (rpc_call_udp_send(&sock->stack->rpc_queue, fd, len, flags) < 0) { +- usleep(1000); // 1000: wait 1ms to exec again +- } ++ __sync_fetch_and_add(&sock->call_num, 1); ++ while (rpc_call_udp_send(&sock->stack->rpc_queue, fd, len, flags) < 0) { ++ usleep(1000); // 1000: wait 1ms to exec again ++ } + } + + static inline void notice_stack_send(struct lwip_sock *sock, int32_t fd, int32_t len, int32_t flags) +@@ -875,7 +858,7 @@ ssize_t do_lwip_send_to_stack(int32_t fd, const void *buf, size_t len, int32_t f + // send = 0 : tcp peer close connection ? + if (send <= 0) { + return send; +- } ++ } + } + + notice_stack_send(sock, fd, send, flags); +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index bcca1a7..f1eeba1 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -88,7 +88,7 @@ struct protocol_stack *get_protocol_stack(void) + return g_stack_p; + } + +-struct protocol_stack *get_protocol_stack_by_fd(int32_t fd) ++struct protocol_stack *get_protocol_stack_by_fd(int fd) + { + struct lwip_sock *sock = lwip_get_socket(fd); + if (POSIX_IS_CLOSED(sock)) { +@@ -468,7 +468,7 @@ END: + return NULL; + } + +-int stack_polling(uint32_t wakeup_tick) ++int stack_polling(unsigned wakeup_tick) + { + int force_quit; + struct cfg_params *cfg = get_global_cfg_params(); +@@ -536,12 +536,11 @@ int stack_polling(uint32_t wakeup_tick) + static void* gazelle_stack_thread(void *arg) + { + struct thread_params *t_params = (struct thread_params*) arg; +- + uint16_t queue_id = t_params->queue_id; +- uint32_t wakeup_tick = 0; +- +- struct protocol_stack *stack = stack_thread_init(arg); ++ struct protocol_stack *stack; ++ unsigned wakeup_tick = 0; + ++ stack = stack_thread_init(arg); + free(arg); + if (stack == NULL) { + LSTACK_LOG(ERR, LSTACK, "stack_thread_init failed queue_id=%hu\n", queue_id); +@@ -607,7 +606,7 @@ static int stack_group_init_mempool(void) + return 0; + } + +-int32_t stack_group_init(void) ++int stack_group_init(void) + { + struct protocol_stack_group *stack_group = get_protocol_stack_group(); + stack_group->stack_num = 0; +@@ -632,7 +631,7 @@ int32_t stack_group_init(void) + return 0; + } + +-int32_t stack_setup_app_thread(void) ++int stack_setup_app_thread(void) + { + static PER_THREAD int first_flags = 1; + static _Atomic uint32_t queue_id = 0; +@@ -660,21 +659,21 @@ int32_t stack_setup_app_thread(void) + return 0; + } + +-int32_t stack_setup_thread(void) ++int stack_setup_thread(void) + { +- int32_t ret; ++ int ret, i; + char name[PATH_MAX]; + int queue_num = get_global_cfg_params()->num_queue; + struct thread_params *t_params[PROTOCOL_STACK_MAX] = {NULL}; + int process_index = get_global_cfg_params()->process_idx; + +- for (uint32_t i = 0; i < queue_num; ++i) { ++ for (i = 0; i < queue_num; ++i) { + t_params[i] = malloc(sizeof(struct thread_params)); + if (t_params[i] == NULL) { + goto OUT1; + } + } +- for (uint32_t i = 0; i < queue_num; i++) { ++ for (i = 0; i < queue_num; i++) { + if (get_global_cfg_params()->seperate_send_recv) { + if (i % 2 == 0) { + ret = sprintf_s(name, sizeof(name), "%s_%d_%d", LSTACK_RECV_THREAD_NAME, process_index, i / 2); +@@ -714,7 +713,7 @@ int32_t stack_setup_thread(void) + return 0; + + OUT1: +- for (int32_t i = 0; i < queue_num; ++i) { ++ for (i = 0; i < queue_num; ++i) { + if (t_params[i] != NULL) { + free(t_params[i]); + } +diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c +index 3e9889a..b4a5953 100644 +--- a/src/lstack/core/lstack_thread_rpc.c ++++ b/src/lstack/core/lstack_thread_rpc.c +@@ -45,20 +45,20 @@ static struct rpc_msg *get_rpc_msg(struct rpc_msg_pool *rpc_pool) + return msg; + } + +-static void rpc_msg_init(struct rpc_msg *msg, rpc_msg_func func, struct rpc_msg_pool *pool) ++__rte_always_inline ++static void rpc_msg_init(struct rpc_msg *msg, rpc_func_t func, struct rpc_msg_pool *pool) + { + msg->func = func; + msg->rpcpool = pool; +- msg->sync_flag = 1; + msg->recall_flag = 0; + pthread_spin_init(&msg->lock, PTHREAD_PROCESS_PRIVATE); + } + +-static struct rpc_msg *rpc_msg_alloc(rpc_msg_func func) ++static struct rpc_msg *rpc_msg_alloc(rpc_func_t func) + { +- struct rpc_msg *msg = NULL; ++ struct rpc_msg *msg; + +- if (g_rpc_pool == NULL) { ++ if (unlikely(g_rpc_pool == NULL)) { + g_rpc_pool = calloc(1, sizeof(struct rpc_msg_pool)); + if (g_rpc_pool == NULL) { + LSTACK_LOG(INFO, LSTACK, "g_rpc_pool calloc failed\n"); +@@ -66,8 +66,8 @@ static struct rpc_msg *rpc_msg_alloc(rpc_msg_func func) + exit(-1); + } + +- g_rpc_pool->mempool = create_mempool("rpc_pool", get_global_cfg_params()->rpc_msg_max, sizeof(struct rpc_msg), +- 0, rte_gettid()); ++ g_rpc_pool->mempool = ++ create_mempool("rpc_pool", get_global_cfg_params()->rpc_msg_max, sizeof(struct rpc_msg), 0, rte_gettid()); + if (g_rpc_pool->mempool == NULL) { + LSTACK_LOG(INFO, LSTACK, "rpc_pool create failed, errno is %d\n", errno); + g_rpc_stats.call_alloc_fail++; +@@ -76,12 +76,12 @@ static struct rpc_msg *rpc_msg_alloc(rpc_msg_func func) + } + + msg = get_rpc_msg(g_rpc_pool); +- if (msg == NULL) { ++ if (unlikely(msg == NULL)) { + g_rpc_stats.call_alloc_fail++; + return NULL; + } +- rpc_msg_init(msg, func, g_rpc_pool); + ++ rpc_msg_init(msg, func, g_rpc_pool); + return msg; + } + +@@ -97,8 +97,9 @@ static void rpc_msg_free(struct rpc_msg *msg) + } + + __rte_always_inline +-static void rpc_call(rpc_queue *queue, struct rpc_msg *msg) ++static void rpc_async_call(rpc_queue *queue, struct rpc_msg *msg) + { ++ msg->sync_flag = 0; + lockless_queue_mpsc_push(queue, &msg->queue_node); + } + +@@ -108,7 +109,9 @@ static int rpc_sync_call(rpc_queue *queue, struct rpc_msg *msg) + int ret; + + pthread_spin_trylock(&msg->lock); +- rpc_call(queue, msg); ++ ++ msg->sync_flag = 1; ++ lockless_queue_mpsc_push(queue, &msg->queue_node); + + // waiting stack unlock + pthread_spin_lock(&msg->lock); +@@ -123,7 +126,7 @@ int rpc_msgcnt(rpc_queue *queue) + return lockless_queue_count(queue); + } + +-static struct rpc_msg *rpc_msg_alloc_except(rpc_msg_func func) ++static struct rpc_msg *rpc_msg_alloc_except(rpc_func_t func) + { + struct rpc_msg *msg = calloc(1, sizeof(struct rpc_msg)); + if (msg == NULL) { +@@ -146,14 +149,14 @@ int rpc_call_stack_exit(rpc_queue *queue) + return -1; + } + +- rpc_call(queue, msg); ++ rpc_async_call(queue, msg); + return 0; + } + + int rpc_poll_msg(rpc_queue *queue, int max_num) + { + int force_quit = 0; +- struct rpc_msg *msg = NULL; ++ struct rpc_msg *msg; + + while (max_num--) { + lockless_queue_node *node = lockless_queue_mpsc_pop(queue); +@@ -163,24 +166,24 @@ int rpc_poll_msg(rpc_queue *queue, int max_num) + + msg = container_of(node, struct rpc_msg, queue_node); + +- if (msg->func) { ++ if (likely(msg->func)) { + msg->func(msg); + } else { + g_rpc_stats.call_null++; + } + +- if (msg->func == stack_exit_by_rpc) { ++ if (unlikely(msg->func == stack_exit_by_rpc)) { + force_quit = 1; + } ++ if (msg->recall_flag) { ++ msg->recall_flag = 0; ++ continue; ++ } + +- if (!msg->recall_flag) { +- if (msg->sync_flag) { +- pthread_spin_unlock(&msg->lock); +- } else { +- rpc_msg_free(msg); +- } ++ if (msg->sync_flag) { ++ pthread_spin_unlock(&msg->lock); + } else { +- msg->recall_flag = 0; ++ rpc_msg_free(msg); + } + } + +@@ -204,7 +207,7 @@ static void callback_close(struct rpc_msg *msg) + + if (sock && __atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) > 0) { + msg->recall_flag = 1; +- rpc_call(&stack->rpc_queue, msg); /* until stack_send recall finish */ ++ rpc_async_call(&stack->rpc_queue, msg); /* until stack_send recall finish */ + return; + } + +@@ -223,7 +226,7 @@ static void callback_shutdown(struct rpc_msg *msg) + + if (sock && __atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) > 0) { + msg->recall_flag = 1; +- rpc_call(&stack->rpc_queue, msg); ++ rpc_async_call(&stack->rpc_queue, msg); + return; + } + +@@ -237,7 +240,7 @@ static void callback_shutdown(struct rpc_msg *msg) + + static void callback_bind(struct rpc_msg *msg) + { +- msg->result = lwip_bind(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].cp, msg->args[MSG_ARG_2].socklen); ++ msg->result = lwip_bind(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].cp, msg->args[MSG_ARG_2].u); + if (msg->result != 0) { + LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d failed %ld\n", get_stack_tid(), msg->args[MSG_ARG_0].i, msg->result); + } +@@ -265,7 +268,7 @@ static void callback_create_shadow_fd(struct rpc_msg *msg) + { + int fd = msg->args[MSG_ARG_0].i; + struct sockaddr *addr = msg->args[MSG_ARG_1].p; +- socklen_t addr_len = msg->args[MSG_ARG_2].socklen; ++ socklen_t addr_len = msg->args[MSG_ARG_2].u; + + int clone_fd = 0; + struct lwip_sock *sock = lwip_get_socket(fd); +@@ -337,7 +340,7 @@ static void callback_accept(struct rpc_msg *msg) + + static void callback_connect(struct rpc_msg *msg) + { +- msg->result = lwip_connect(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].socklen); ++ msg->result = lwip_connect(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].p, msg->args[MSG_ARG_2].u); + if (msg->result < 0) { + msg->result = -errno; + } +@@ -391,7 +394,7 @@ int rpc_call_bind(rpc_queue *queue, int fd, const struct sockaddr *addr, socklen + + msg->args[MSG_ARG_0].i = fd; + msg->args[MSG_ARG_1].cp = addr; +- msg->args[MSG_ARG_2].socklen = addrlen; ++ msg->args[MSG_ARG_2].u = addrlen; + + return rpc_sync_call(queue, msg); + } +@@ -418,7 +421,7 @@ int rpc_call_shadow_fd(rpc_queue *queue, int fd, const struct sockaddr *addr, so + + msg->args[MSG_ARG_0].i = fd; + msg->args[MSG_ARG_1].cp = addr; +- msg->args[MSG_ARG_2].socklen = addrlen; ++ msg->args[MSG_ARG_2].u = addrlen; + + return rpc_sync_call(queue, msg); + } +@@ -447,7 +450,7 @@ int rpc_call_connect(rpc_queue *queue, int fd, const struct sockaddr *addr, sock + + msg->args[MSG_ARG_0].i = fd; + msg->args[MSG_ARG_1].cp = addr; +- msg->args[MSG_ARG_2].socklen = addrlen; ++ msg->args[MSG_ARG_2].u = addrlen; + + int ret = rpc_sync_call(queue, msg); + if (ret < 0) { +@@ -486,7 +489,7 @@ static void callback_getsockopt(struct rpc_msg *msg) + static void callback_setsockopt(struct rpc_msg *msg) + { + msg->result = lwip_setsockopt(msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, +- msg->args[MSG_ARG_3].cp, msg->args[MSG_ARG_4].socklen); ++ msg->args[MSG_ARG_3].cp, msg->args[MSG_ARG_4].u); + if (msg->result != 0) { + LSTACK_LOG(ERR, LSTACK, "tid %ld, fd %d, level %d, optname %d, fail %ld\n", get_stack_tid(), + msg->args[MSG_ARG_0].i, msg->args[MSG_ARG_1].i, msg->args[MSG_ARG_2].i, msg->result); +@@ -548,7 +551,7 @@ int rpc_call_setsockopt(rpc_queue *queue, int fd, int level, int optname, const + msg->args[MSG_ARG_1].i = level; + msg->args[MSG_ARG_2].i = optname; + msg->args[MSG_ARG_3].cp = optval; +- msg->args[MSG_ARG_4].socklen = optlen; ++ msg->args[MSG_ARG_4].u = optlen; + + return rpc_sync_call(queue, msg); + } +@@ -556,13 +559,13 @@ int rpc_call_setsockopt(rpc_queue *queue, int fd, int level, int optname, const + static void callback_tcp_send(struct rpc_msg *msg) + { + int fd = msg->args[MSG_ARG_0].i; +- size_t len = msg->args[MSG_ARG_1].size; ++ size_t len = UINT16_MAX; /* ignore msg->args[MSG_ARG_1].size; */ + struct protocol_stack *stack = get_protocol_stack(); +- int replenish_again; ++ int ret; ++ msg->result = -1; + + struct lwip_sock *sock = lwip_get_socket(fd); +- if (POSIX_IS_CLOSED(sock)) { +- msg->result = -1; ++ if (unlikely(POSIX_IS_CLOSED(sock))) { + return; + } + +@@ -570,16 +573,18 @@ static void callback_tcp_send(struct rpc_msg *msg) + calculate_sock_latency(&stack->latency, sock, GAZELLE_LATENCY_WRITE_RPC_MSG); + } + +- replenish_again = do_lwip_send(stack, sock->conn->callback_arg.socket, sock, len, 0); +- if (replenish_again < 0) { ++ ret = lwip_send(fd, sock, len, 0); ++ if (unlikely(ret < 0) && (errno == ENOTCONN || errno == ECONNRESET || errno == ECONNABORTED)) { + __sync_fetch_and_sub(&sock->call_num, 1); + return; + } ++ msg->result = 0; + +- if (NETCONN_IS_DATAOUT(sock) || replenish_again > 0) { ++ ret = do_lwip_replenish_sendring(stack, sock); ++ if (ret > 0 || NETCONN_IS_DATAOUT(sock)) { + if (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 1) { + msg->recall_flag = 1; +- rpc_call(&stack->rpc_queue, msg); ++ rpc_async_call(&stack->rpc_queue, msg); + return; + } + } +@@ -593,11 +598,11 @@ static void callback_udp_send(struct rpc_msg *msg) + int fd = msg->args[MSG_ARG_0].i; + size_t len = msg->args[MSG_ARG_1].size; + struct protocol_stack *stack = get_protocol_stack(); +- int replenish_again; ++ int ret; ++ msg->result = -1; + + struct lwip_sock *sock = lwip_get_socket(fd); +- if (POSIX_IS_CLOSED(sock)) { +- msg->result = -1; ++ if (unlikely(POSIX_IS_CLOSED(sock))) { + return; + } + +@@ -605,8 +610,15 @@ static void callback_udp_send(struct rpc_msg *msg) + calculate_sock_latency(&stack->latency, sock, GAZELLE_LATENCY_WRITE_RPC_MSG); + } + +- replenish_again = do_lwip_send(stack, sock->conn->callback_arg.socket, sock, len, 0); +- if ((replenish_again > 0) && (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 1)) { ++ ret = lwip_send(fd, sock, len, 0); ++ if (unlikely(ret < 0) && (errno == ENOTCONN || errno == ECONNRESET || errno == ECONNABORTED)) { ++ __sync_fetch_and_sub(&sock->call_num, 1); ++ return; ++ } ++ msg->result = 0; ++ ++ ret = do_lwip_replenish_sendring(stack, sock); ++ if (ret > 0 && (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 1)) { + rpc_call_replenish(&stack->rpc_queue, sock); + return; + } +@@ -629,9 +641,8 @@ int rpc_call_udp_send(rpc_queue *queue, int fd, size_t len, int flags) + msg->args[MSG_ARG_0].i = fd; + msg->args[MSG_ARG_1].size = len; + msg->args[MSG_ARG_2].i = flags; +- msg->sync_flag = 0; + +- rpc_call(queue, msg); ++ rpc_async_call(queue, msg); + return 0; + } + +@@ -649,9 +660,8 @@ int rpc_call_tcp_send(rpc_queue *queue, int fd, size_t len, int flags) + msg->args[MSG_ARG_0].i = fd; + msg->args[MSG_ARG_1].size = len; + msg->args[MSG_ARG_2].i = flags; +- msg->sync_flag = 0; + +- rpc_call(queue, msg); ++ rpc_async_call(queue, msg); + return 0; + } + +@@ -663,7 +673,7 @@ static void callback_replenish_sendring(struct rpc_msg *msg) + msg->result = do_lwip_replenish_sendring(stack, sock); + if (msg->result == true) { + msg->recall_flag = 1; +- rpc_call(&stack->rpc_queue, msg); ++ rpc_async_call(&stack->rpc_queue, msg); + } + } + +@@ -675,9 +685,8 @@ int rpc_call_replenish(rpc_queue *queue, void *sock) + } + + msg->args[MSG_ARG_0].p = sock; +- msg->sync_flag = 0; + +- rpc_call(queue, msg); ++ rpc_async_call(queue, msg); + return 0; + } + +@@ -713,16 +722,17 @@ static void callback_clean_epoll(struct rpc_msg *msg) + list_del_node(&wakeup->wakeup_list[stack->stack_idx]); + } + +-void rpc_call_clean_epoll(rpc_queue *queue, void *wakeup) ++int rpc_call_clean_epoll(rpc_queue *queue, void *wakeup) + { + struct rpc_msg *msg = rpc_msg_alloc(callback_clean_epoll); + if (msg == NULL) { +- return; ++ return -1; + } + + msg->args[MSG_ARG_0].p = wakeup; + + rpc_sync_call(queue, msg); ++ return 0; + } + + static void callback_arp(struct rpc_msg *msg) +@@ -740,11 +750,9 @@ int rpc_call_arp(rpc_queue *queue, void *mbuf) + return -1; + } + +- msg->sync_flag = 0; + msg->args[MSG_ARG_0].p = mbuf; + +- rpc_call(queue, msg); +- ++ rpc_async_call(queue, msg); + return 0; + } + +diff --git a/src/lstack/include/lstack_lwip.h b/src/lstack/include/lstack_lwip.h +index 0c7bb62..dcb7dac 100644 +--- a/src/lstack/include/lstack_lwip.h ++++ b/src/lstack/include/lstack_lwip.h +@@ -29,15 +29,23 @@ unsigned same_node_ring_count(struct lwip_sock *sock); + #define NETCONN_IS_OUTIDLE(sock) gazelle_ring_readable_count((sock)->send_ring) + #define NETCONN_IS_UDP(sock) (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) == NETCONN_UDP) + +-void do_lwip_clone_sockopt(struct lwip_sock *dst_sock, struct lwip_sock *src_sock); +- ++/* lwip api */ + struct pbuf *do_lwip_tcp_get_from_sendring(struct lwip_sock *sock, uint16_t remain_size); + struct pbuf *do_lwip_udp_get_from_sendring(struct lwip_sock *sock, uint16_t remain_size); + void do_lwip_get_from_sendring_over(struct lwip_sock *sock); +-bool do_lwip_replenish_sendring(struct protocol_stack *stack, struct lwip_sock *sock); + ssize_t do_lwip_read_from_lwip(struct lwip_sock *sock, int32_t flags, uint8_t apiflags); + +-/* app write/read ring */ ++/* lwip api */ ++void do_lwip_free_pbuf(struct pbuf *pbuf); ++struct pbuf *do_lwip_alloc_pbuf(pbuf_layer layer, uint16_t length, pbuf_type type); ++ ++/* lwip api */ ++void do_lwip_add_recvlist(int32_t fd); ++/* stack api */ ++void do_lwip_read_recvlist(struct protocol_stack *stack, uint32_t max_num); ++ ++ ++/* app api */ + ssize_t do_lwip_sendmsg_to_stack(struct lwip_sock *sock, int32_t s, + const struct msghdr *message, int32_t flags); + ssize_t do_lwip_recvmsg_from_stack(int32_t s, const struct msghdr *message, int32_t flags); +@@ -47,17 +55,14 @@ ssize_t do_lwip_send_to_stack(int32_t fd, const void *buf, size_t len, int32_t f + ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags, + struct sockaddr *addr, socklen_t *addrlen); + +-void do_lwip_read_recvlist(struct protocol_stack *stack, uint32_t max_num); +-void do_lwip_add_recvlist(int32_t fd); +-int do_lwip_send(struct protocol_stack *stack, int32_t fd, struct lwip_sock *sock, +- size_t len, int32_t flags); ++/* stack api */ ++bool do_lwip_replenish_sendring(struct protocol_stack *stack, struct lwip_sock *sock); ++ ++void do_lwip_clone_sockopt(struct lwip_sock *dst_sock, struct lwip_sock *src_sock); + + uint32_t do_lwip_get_conntable(struct gazelle_stat_lstack_conn_info *conn, uint32_t max_num); + uint32_t do_lwip_get_connnum(void); + +-void do_lwip_free_pbuf(struct pbuf *pbuf); +-struct pbuf *do_lwip_alloc_pbuf(pbuf_layer layer, uint16_t length, pbuf_type type); +- + void read_same_node_recv_list(struct protocol_stack *stack); + + #endif +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index fdd5388..08a3901 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -31,11 +31,8 @@ + #include "lstack_tx_cache.h" + + #define SOCK_RECV_RING_SIZE (get_global_cfg_params()->recv_ring_size) +-#define SOCK_RECV_FREE_THRES (32) + #define SOCK_RECV_RING_SIZE_MAX (2048) + #define SOCK_SEND_RING_SIZE_MAX (2048) +-#define SOCK_SEND_REPLENISH_THRES (16) +-#define WAKEUP_MAX_NUM (32) + + #define MBUFPOOL_RESERVE_NUM (get_global_cfg_params()->nic.rxqueue_size + 1024) + +@@ -113,7 +110,7 @@ struct protocol_stack_group { + long get_stack_tid(void); + + struct protocol_stack *get_protocol_stack(void); +-struct protocol_stack *get_protocol_stack_by_fd(int32_t fd); ++struct protocol_stack *get_protocol_stack_by_fd(int fd); + struct protocol_stack *get_bind_protocol_stack(void); + struct protocol_stack_group *get_protocol_stack_group(void); + +@@ -121,13 +118,13 @@ int get_min_conn_stack(struct protocol_stack_group *stack_group); + void bind_to_stack_numa(struct protocol_stack *stack); + void thread_bind_stack(struct protocol_stack *stack); + +-int32_t stack_group_init(void); ++int stack_group_init(void); + void stack_group_exit(void); + void stack_exit(void); + +-int32_t stack_setup_thread(void); +-int32_t stack_setup_app_thread(void); ++int stack_setup_thread(void); ++int stack_setup_app_thread(void); + +-int stack_polling(uint32_t wakeup_tick); ++int stack_polling(unsigned wakeup_tick); + + #endif +diff --git a/src/lstack/include/lstack_thread_rpc.h b/src/lstack/include/lstack_thread_rpc.h +index c2654bb..6f8e03e 100644 +--- a/src/lstack/include/lstack_thread_rpc.h ++++ b/src/lstack/include/lstack_thread_rpc.h +@@ -32,8 +32,6 @@ struct rpc_stats { + uint64_t call_alloc_fail; + }; + +-struct rpc_msg; +-typedef void (*rpc_msg_func)(struct rpc_msg *msg); + union rpc_msg_arg { + int i; + unsigned int u; +@@ -41,22 +39,25 @@ union rpc_msg_arg { + unsigned long ul; + void *p; + const void *cp; +- socklen_t socklen; + size_t size; + }; +-struct rpc_msg_pool { +- struct rte_mempool *mempool; +-}; ++ ++struct rpc_msg; ++typedef void (*rpc_func_t)(struct rpc_msg *msg); + struct rpc_msg { +- pthread_spinlock_t lock; /* msg handler unlock notice sender msg process done */ + int8_t sync_flag : 1; + int8_t recall_flag : 1; +- int64_t result; /* func return val */ +- lockless_queue_node queue_node; +- struct rpc_msg_pool *rpcpool; + +- rpc_msg_func func; /* msg handle func hook */ ++ long result; /* func return val */ ++ rpc_func_t func; /* msg handle func hook */ + union rpc_msg_arg args[RPM_MSG_ARG_SIZE]; /* resolve by type */ ++ ++ struct rpc_msg_pool { ++ struct rte_mempool *mempool; ++ } *rpcpool; ++ ++ pthread_spinlock_t lock; /* msg handler unlock notice sender msg process done */ ++ lockless_queue_node queue_node; + }; + + static inline void rpc_queue_init(rpc_queue *queue) +@@ -92,7 +93,7 @@ int rpc_call_udp_send(rpc_queue *queue, int fd, size_t len, int flags); + int rpc_call_replenish(rpc_queue *queue, void *sock); + int rpc_call_recvlistcnt(rpc_queue *queue); + +-void rpc_call_clean_epoll(rpc_queue *queue, void *wakeup); ++int rpc_call_clean_epoll(rpc_queue *queue, void *wakeup); + int rpc_call_arp(rpc_queue *queue, void *mbuf); + + int rpc_call_conntable(rpc_queue *queue, void *conn_table, unsigned max_conn); +-- +2.33.0 + diff --git a/0260-cleancode-declare-different-cfg_params-types.patch b/0260-cleancode-declare-different-cfg_params-types.patch new file mode 100644 index 0000000..fb2c1a9 --- /dev/null +++ b/0260-cleancode-declare-different-cfg_params-types.patch @@ -0,0 +1,347 @@ +From 3313619bd53f1bafc5e48eb4642213fd5208c0e2 Mon Sep 17 00:00:00 2001 +From: Lemmy Huang +Date: Sun, 1 Sep 2024 11:33:12 +0800 +Subject: [PATCH] cleancode: declare different cfg_params types + +Signed-off-by: Lemmy Huang +--- + src/lstack/core/lstack_cfg.c | 10 +- + src/lstack/core/lstack_dpdk.c | 8 +- + src/lstack/core/lstack_protocol_stack.c | 2 +- + src/lstack/core/lstack_virtio.c | 4 +- + src/lstack/include/lstack_cfg.h | 161 +++++++++++---------- + src/lstack/include/lstack_protocol_stack.h | 2 +- + src/lstack/netif/lstack_ethdev.c | 4 +- + src/lstack/netif/lstack_vdev.c | 2 +- + 8 files changed, 104 insertions(+), 89 deletions(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 882e60a..659a2a7 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -1300,9 +1300,9 @@ static int32_t parse_use_sockmap(void) + static int32_t parse_nic_rxqueue_size(void) + { + int32_t ret; +- PARSE_ARG(g_config_params.nic.rxqueue_size, "nic_rxqueue_size", 4096, ++ PARSE_ARG(g_config_params.rxqueue_size, "nic_rxqueue_size", 4096, + NIC_QUEUE_SIZE_MIN, NIC_QUEUE_SIZE_MAX, ret); +- if (!rte_is_power_of_2(g_config_params.nic.rxqueue_size)) { ++ if (!rte_is_power_of_2(g_config_params.rxqueue_size)) { + LSTACK_LOG(ERR, LSTACK, "nic queue size only support power of two\n"); + return -1; + } +@@ -1312,9 +1312,9 @@ static int32_t parse_nic_rxqueue_size(void) + static int32_t parse_nic_txqueue_size(void) + { + int32_t ret; +- PARSE_ARG(g_config_params.nic.txqueue_size, "nic_txqueue_size", 2048, ++ PARSE_ARG(g_config_params.txqueue_size, "nic_txqueue_size", 2048, + NIC_QUEUE_SIZE_MIN, NIC_QUEUE_SIZE_MAX, ret); +- if (!rte_is_power_of_2(g_config_params.nic.txqueue_size)) { ++ if (!rte_is_power_of_2(g_config_params.txqueue_size)) { + LSTACK_LOG(ERR, LSTACK, "nic queue size only support power of two\n"); + return -1; + } +@@ -1352,7 +1352,7 @@ static int32_t parse_stack_thread_mode(void) + static int32_t parse_nic_vlan_mode(void) + { + int32_t ret; +- PARSE_ARG(g_config_params.nic.vlan_mode, "nic_vlan_mode", -1, -1, 4094, ret); ++ PARSE_ARG(g_config_params.vlan_mode, "nic_vlan_mode", -1, -1, 4094, ret); + return ret; + } + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index f87e362..1fe0f0a 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -432,8 +432,8 @@ static int eth_params_init(struct eth_params *eth_params, uint16_t port_id, uint + + eth_params->port_id = port_id; + eth_params->nb_queues = nb_queues; +- eth_params->nb_rx_desc = get_global_cfg_params()->nic.rxqueue_size; +- eth_params->nb_tx_desc = get_global_cfg_params()->nic.txqueue_size; ++ eth_params->nb_rx_desc = get_global_cfg_params()->rxqueue_size; ++ eth_params->nb_tx_desc = get_global_cfg_params()->txqueue_size; + eth_params->conf.link_speeds = RTE_ETH_LINK_SPEED_AUTONEG; + eth_params->conf.txmode.mq_mode = RTE_ETH_MQ_TX_NONE; + eth_params->conf.rxmode.mq_mode = RTE_ETH_MQ_RX_NONE; +@@ -571,7 +571,7 @@ int32_t dpdk_ethdev_init(int port_id) + } + + /* after rte_eth_dev_configure */ +- if ((get_global_cfg_params()->nic.vlan_mode != -1) && ++ if ((get_global_cfg_params()->vlan_mode != -1) && + ((stack_group->rx_offload & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) == RTE_ETH_RX_OFFLOAD_VLAN_FILTER)) { + /* + * vlan filter can be configured for switch,nic and software. +@@ -583,7 +583,7 @@ int32_t dpdk_ethdev_init(int port_id) + */ + if ((get_global_cfg_params()->bond_mode != BONDING_MODE_8023AD) && + (get_global_cfg_params()->bond_mode != BONDING_MODE_ALB)) { +- ret = rte_eth_dev_vlan_filter(port_id, get_global_cfg_params()->nic.vlan_mode, 1); ++ ret = rte_eth_dev_vlan_filter(port_id, get_global_cfg_params()->vlan_mode, 1); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk add vlan filter failed ret = %d\n", ret); + return -1; +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index f1eeba1..d03b744 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -571,7 +571,7 @@ static int stack_group_init_mempool(void) + struct cfg_params *cfg_params = get_global_cfg_params(); + uint32_t total_mbufs = 0; + uint32_t total_conn_mbufs = cfg_params->mbuf_count_per_conn * cfg_params->tcp_conn_count; +- uint32_t total_nic_mbufs = cfg_params->nic.rxqueue_size + cfg_params->nic.txqueue_size; ++ uint32_t total_nic_mbufs = cfg_params->rxqueue_size + cfg_params->txqueue_size; + struct rte_mempool *rxtx_mbuf = NULL; + uint32_t cpu_id = 0; + unsigned numa_id = 0; +diff --git a/src/lstack/core/lstack_virtio.c b/src/lstack/core/lstack_virtio.c +index 7a8d947..fefb06d 100644 +--- a/src/lstack/core/lstack_virtio.c ++++ b/src/lstack/core/lstack_virtio.c +@@ -226,10 +226,10 @@ void virtio_tap_process_rx(uint16_t port, uint32_t queue_id) + * so no action will be taken. + * For TSO, tap devices do not support it, so no action will be taken. + */ +- if (get_global_cfg_params()->nic.vlan_mode != -1) { ++ if (get_global_cfg_params()->vlan_mode != -1) { + for (int i = 0; i< pkg_num; i++) { + pkts_burst[i]->ol_flags |= RTE_MBUF_F_TX_VLAN; +- pkts_burst[i]->vlan_tci = (u16_t)get_global_cfg_params()->nic.vlan_mode; ++ pkts_burst[i]->vlan_tci = (u16_t)get_global_cfg_params()->vlan_mode; + } + } + +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index 4fc99f3..5e2d6fc 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -50,93 +50,108 @@ + #define LSTACK_LPM_PKTS_IN_DETECT 1000 + #define LSTACK_LPM_RX_PKTS 20 + +- + #define LSTACK_LPM_PKTS_IN_DETECT_MIN 5 + #define LSTACK_LPM_PKTS_IN_DETECT_MAX 65535 + ++struct dev_addr { + #define DEV_ADDR_TYPE_EMPTY 0 + #define DEV_ADDR_TYPE_MAC 1 + #define DEV_ADDR_TYPE_PCI 2 +- +-struct dev_addr { +- uint8_t addr_type; // 0:empty, 1:mac, 2:pci ++ uint8_t addr_type; + union addr_union { + struct rte_ether_addr mac_addr; + struct rte_pci_addr pci_addr; + } addr; + }; + +-struct secondary_attach_arg { +- uint8_t socket_num; +- uint64_t socket_size; +- uint32_t socket_per_size[GAZELLE_MAX_NUMA_NODES]; +- uintptr_t base_virtaddr; +- char file_prefix[PATH_MAX]; +-}; +- +-struct cfg_nic_params { +- uint32_t rxqueue_size; +- uint32_t txqueue_size; +- int32_t vlan_mode; +-}; +- + struct cfg_params { +- ip4_addr_t host_addr; +- ip6_addr_t host_addr6; +- ip4_addr_t netmask; +- ip4_addr_t gateway_addr; +- uint8_t mac_addr[ETHER_ADDR_LEN]; +- uint16_t num_cpu; +- uint32_t cpus[CFG_MAX_CPUS]; +- uint32_t send_cpus[CFG_MAX_CPUS]; +- uint32_t recv_cpus[CFG_MAX_CPUS]; +- uint16_t app_exclude_num_cpu; +- uint32_t app_exclude_cpus[CFG_MAX_CPUS]; +- uint8_t num_ports; +- uint16_t ports[CFG_MAX_PORTS]; + char log_file[PATH_MAX]; +- uint16_t low_power_mod; +- uint16_t lpm_rx_pkts; +- uint32_t lpm_detect_ms; +- uint32_t lpm_pkts_in_detect; +- uint32_t tcp_conn_count; +- uint32_t mbuf_count_per_conn; +- uint32_t read_connect_number; +- uint32_t rpc_number; +- uint32_t nic_read_number; +- uint8_t use_ltran; // false:lstack read from nic. true:lstack read form ltran process. +- +- uint16_t num_process; +- uint16_t num_listen_port; +- uint16_t is_primary; +- uint16_t num_queue; +- uint16_t tot_queue_num; +- uint8_t process_idx; +- uint32_t process_numa[PROTOCOL_STACK_MAX]; +- +- bool kni_switch; +- bool listen_shadow; // true:listen in all stack thread. false:listen in one stack thread. +- bool app_bind_numa; +- bool main_thread_affinity; +- bool seperate_send_recv; +- int dpdk_argc; +- char **dpdk_argv; +- struct secondary_attach_arg sec_attach_arg; +- char unix_socket_filename[NAME_MAX]; +- uint16_t send_ring_size; +- uint16_t recv_ring_size; +- bool tuple_filter; +- int8_t bond_mode; +- int32_t bond_miimon; +- struct dev_addr bond_slave_addr[GAZELLE_MAX_BOND_NUM]; +- bool use_sockmap; +- bool udp_enable; +- struct cfg_nic_params nic; +- bool stack_mode_rtc; +- bool nonblock_mode; +- uint32_t rpc_msg_max; +- bool send_cache_mode; +- bool flow_bifurcation; ++ ++ struct { // dpdk ++ char **dpdk_argv; ++ uint8_t dpdk_argc; ++ struct secondary_attach_arg { ++ uint8_t socket_num; ++ uint64_t socket_size; ++ uint32_t socket_per_size[GAZELLE_MAX_NUMA_NODES]; ++ uintptr_t base_virtaddr; ++ char file_prefix[PATH_MAX]; ++ } sec_attach_arg; ++ }; ++ ++ struct { // eth ++ ip4_addr_t host_addr; ++ ip6_addr_t host_addr6; ++ ip4_addr_t netmask; ++ ip4_addr_t gateway_addr; ++ uint8_t mac_addr[ETHER_ADDR_LEN]; ++ int8_t bond_mode; ++ int32_t bond_miimon; ++ struct dev_addr bond_slave_addr[GAZELLE_MAX_BOND_NUM]; ++ }; ++ ++ struct { // low_power ++ uint16_t low_power_mod; ++ uint16_t lpm_rx_pkts; ++ uint32_t lpm_detect_ms; ++ uint32_t lpm_pkts_in_detect; ++ }; ++ ++ struct { // eth_rxtx ++ uint32_t rxqueue_size; ++ uint32_t txqueue_size; ++ uint16_t num_queue; ++ uint16_t tot_queue_num; ++ bool send_cache_mode; ++ bool flow_bifurcation; ++ int32_t vlan_mode; ++ }; ++ ++ struct { // stack ++ uint16_t num_cpu; ++ uint32_t cpus[CFG_MAX_CPUS]; ++ ++ bool main_thread_affinity; ++ bool app_bind_numa; ++ uint16_t app_exclude_num_cpu; ++ uint32_t app_exclude_cpus[CFG_MAX_CPUS]; ++ ++ bool stack_mode_rtc; ++ bool listen_shadow; // true:listen in all stack thread. false:listen in one stack thread. ++ ++ uint32_t read_connect_number; ++ uint32_t nic_read_number; ++ uint32_t rpc_number; ++ uint32_t rpc_msg_max; ++ }; ++ ++ struct { // socket ++ uint16_t send_ring_size; ++ uint16_t recv_ring_size; ++ uint32_t tcp_conn_count; ++ uint32_t mbuf_count_per_conn; ++ }; ++ ++ struct { // deprecated ++ char unix_socket_filename[NAME_MAX]; ++ bool use_ltran; // false:lstack read from nic. true:lstack read form ltran process. ++ bool nonblock_mode; ++ bool udp_enable; ++ bool kni_switch; ++ }; ++ ++ struct { // experiment ++ uint16_t num_process; ++ uint16_t is_primary; ++ uint8_t process_idx; ++ uint32_t process_numa[PROTOCOL_STACK_MAX]; ++ bool tuple_filter; ++ bool use_sockmap; ++ ++ bool seperate_send_recv; ++ uint32_t send_cpus[CFG_MAX_CPUS]; ++ uint32_t recv_cpus[CFG_MAX_CPUS]; ++ }; + }; + + struct cfg_params *get_global_cfg_params(void); +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index 08a3901..8cb0020 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -34,7 +34,7 @@ + #define SOCK_RECV_RING_SIZE_MAX (2048) + #define SOCK_SEND_RING_SIZE_MAX (2048) + +-#define MBUFPOOL_RESERVE_NUM (get_global_cfg_params()->nic.rxqueue_size + 1024) ++#define MBUFPOOL_RESERVE_NUM (get_global_cfg_params()->rxqueue_size + 1024) + + struct protocol_stack { + uint32_t tid; +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 4f3cbc1..1a721f6 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -418,8 +418,8 @@ int32_t ethdev_init(struct protocol_stack *stack) + } + + /* 0-4094: The vlaue range for VLAN IDs is 0 to 4094. */ +- if (get_global_cfg_params()->nic.vlan_mode >= 0 && get_global_cfg_params()->nic.vlan_mode <= 4094) { +- netif_set_vlan_tci(&stack->netif, (u16_t)get_global_cfg_params()->nic.vlan_mode); ++ if (get_global_cfg_params()->vlan_mode >= 0 && get_global_cfg_params()->vlan_mode <= 4094) { ++ netif_set_vlan_tci(&stack->netif, (u16_t)get_global_cfg_params()->vlan_mode); + } + + netif_set_link_up(&stack->netif); +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index 9ca77ba..e1a63a7 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -145,7 +145,7 @@ static uint32_t vdev_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pkt + } + + /* skip gro when tcp/ip cksum offloads disable */ +- if (get_protocol_stack_group()->rx_offload == 0 || (get_global_cfg_params()->nic.vlan_mode >= 0 ++ if (get_protocol_stack_group()->rx_offload == 0 || (get_global_cfg_params()->vlan_mode >= 0 + && !(get_protocol_stack_group()->rx_offload & RTE_ETH_RX_OFFLOAD_VLAN_STRIP))) { + return pkt_num; + } +-- +2.33.0 + diff --git a/gazelle.spec b/gazelle.spec index 9a2494b..2d3093c 100644 --- a/gazelle.spec +++ b/gazelle.spec @@ -2,7 +2,7 @@ Name: gazelle Version: 1.0.2 -Release: 63 +Release: 64 Summary: gazelle is a high performance user-mode stack License: MulanPSL-2.0 URL: https://gitee.com/openeuler/gazelle @@ -273,6 +273,10 @@ Patch9253: 0253-example-solve-double-free.patch Patch9254: 0254-WRAP-support-setsockopt-SO_SNDTIMEO-SO_SNBUF.patch Patch9255: 0255-DFX-adapt-log-optimization.patch Patch9256: 0256-LOG-add-log-when-udp-send_ring-is-exhausted.patch +Patch9257: 0257-cleancode-refactor-rtc_api-rtw_api-and-dummy_api.patch +Patch9258: 0258-cleancode-move-some-API-from-stack-to-rpc-and-rtw.patch +Patch9259: 0259-cleancode-add-rpc_async_call-remove-rpc_msg_arg.sock.patch +Patch9260: 0260-cleancode-declare-different-cfg_params-types.patch %description %{name} is a high performance user-mode stack. @@ -314,6 +318,12 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b %config(noreplace) %{conf_path}/ltran.conf %changelog +* Fri Sep 27 2024 yinbin6 - 1.0.2-64 +- cleancode: declare different cfg_params types +- cleancode: add rpc_async_call, remove rpc_msg_arg.socklen, fix some format +- cleancode: move some API from stack to rpc and rtw +- cleancode: refactor rtc_api rtw_api and dummy_api + * Fri Sep 27 2024 yinbin6 - 1.0.2-63 - LOG:add log when udp send_ring is exhausted - DFX: adapt log optimization