From c2057605b8f69b1091af380b98d5f74b471d7431 Mon Sep 17 00:00:00 2001 From: yinbin Date: Wed, 18 Dec 2024 18:21:31 +0800 Subject: [PATCH] sync Connect: execute lwip connect if dst_ip and host_ip are in the same network. (cherry picked from commit 674a95ff9395859b5b14ede0ed1be07a0fa13ea4) --- ...-issue-when-rpc-pools-are-added-to-r.patch | 65 +++++++++ 0307-openGauss-unsupport_tcp_optname.patch | 24 ++++ 0308-kernerl-bind-add-ipv6-add-check.patch | 48 +++++++ ...lwip-connect-if-dst_ip-and-host_ip-a.patch | 132 ++++++++++++++++++ gazelle.spec | 12 +- 5 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 0306-fix-a-contention-issue-when-rpc-pools-are-added-to-r.patch create mode 100644 0307-openGauss-unsupport_tcp_optname.patch create mode 100644 0308-kernerl-bind-add-ipv6-add-check.patch create mode 100644 0309-Connect-execute-lwip-connect-if-dst_ip-and-host_ip-a.patch diff --git a/0306-fix-a-contention-issue-when-rpc-pools-are-added-to-r.patch b/0306-fix-a-contention-issue-when-rpc-pools-are-added-to-r.patch new file mode 100644 index 0000000..9738bcf --- /dev/null +++ b/0306-fix-a-contention-issue-when-rpc-pools-are-added-to-r.patch @@ -0,0 +1,65 @@ +From 6dce1a0ac071e365cb96551b04f555dec3658d85 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Thu, 12 Dec 2024 16:39:48 +0800 +Subject: [PATCH] fix a contention issue when rpc pools are added to + rpc_pool_array + +--- + src/lstack/core/lstack_thread_rpc.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c +index d342af4..050594e 100644 +--- a/src/lstack/core/lstack_thread_rpc.c ++++ b/src/lstack/core/lstack_thread_rpc.c +@@ -31,7 +31,9 @@ struct rpc_pool_array { + int cur_count; + }; + +-static struct rpc_pool_array g_rpc_pool_array; ++static struct rpc_pool_array g_rpc_pool_array = { ++ .lock = PTHREAD_MUTEX_INITIALIZER, ++}; + + static PER_THREAD struct rpc_msg_pool *g_rpc_pool = NULL; + static struct rpc_stats g_rpc_stats; +@@ -41,13 +43,6 @@ struct rpc_stats *rpc_stats_get(void) + return &g_rpc_stats; + } + +-static inline void rpc_pool_array_add(struct rpc_msg_pool *pool) +-{ +- pthread_mutex_lock(&g_rpc_pool_array.lock); +- g_rpc_pool_array.array[g_rpc_pool_array.cur_count++] = pool; +- pthread_mutex_unlock(&g_rpc_pool_array.lock); +-} +- + __rte_always_inline + static struct rpc_msg *get_rpc_msg(struct rpc_msg_pool *rpc_pool) + { +@@ -73,7 +68,9 @@ static void rpc_msg_init(struct rpc_msg *msg, rpc_func_t func, struct rpc_msg_po + static struct rpc_msg_pool *rpc_msg_pool_init(void) + { + struct rpc_msg_pool *rpc_pool; ++ pthread_mutex_lock(&g_rpc_pool_array.lock); + if (g_rpc_pool_array.cur_count >= RPC_POOL_MAX_COUNT) { ++ pthread_mutex_unlock(&g_rpc_pool_array.lock); + return g_rpc_pool_array.array[rte_gettid() % RPC_POOL_MAX_COUNT]; + } + +@@ -90,9 +87,11 @@ static struct rpc_msg_pool *rpc_msg_pool_init(void) + goto END; + } + +- rpc_pool_array_add(rpc_pool); ++ g_rpc_pool_array.array[g_rpc_pool_array.cur_count++] = rpc_pool; ++ pthread_mutex_unlock(&g_rpc_pool_array.lock); + return rpc_pool; + END: ++ pthread_mutex_unlock(&g_rpc_pool_array.lock); + g_rpc_stats.call_alloc_fail++; + return NULL; + } +-- +2.33.0 + diff --git a/0307-openGauss-unsupport_tcp_optname.patch b/0307-openGauss-unsupport_tcp_optname.patch new file mode 100644 index 0000000..de3546f --- /dev/null +++ b/0307-openGauss-unsupport_tcp_optname.patch @@ -0,0 +1,24 @@ +From fd8004b7b7e78d08a7ad59a4561a3b539e806f06 Mon Sep 17 00:00:00 2001 +From: hankangkang +Date: Thu, 12 Dec 2024 09:14:25 +0800 +Subject: [PATCH] openGauss unsupport_tcp_optname + +--- + src/lstack/api/lstack_wrap.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 4416bd8..95e77b6 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -426,6 +426,7 @@ static bool unsupport_tcp_optname(int32_t optname) + if ((optname == TCP_QUICKACK) || + (optname == TCP_INFO) || + (optname == TCP_MAXSEG) || ++ (optname == TCP_USER_TIMEOUT) || + (optname == TCP_CONGESTION)) { + return true; + } +-- +2.33.0 + diff --git a/0308-kernerl-bind-add-ipv6-add-check.patch b/0308-kernerl-bind-add-ipv6-add-check.patch new file mode 100644 index 0000000..29f7a48 --- /dev/null +++ b/0308-kernerl-bind-add-ipv6-add-check.patch @@ -0,0 +1,48 @@ +From bf5bf036eed0f7c15e7441c0c4ddbd5d7e48b3dd Mon Sep 17 00:00:00 2001 +From: hankangkang +Date: Thu, 12 Dec 2024 11:40:09 +0800 +Subject: [PATCH] kernerl bind: add ipv6 add check + +--- + src/lstack/api/lstack_wrap.c | 23 +++++++++++++++++------ + 1 file changed, 17 insertions(+), 6 deletions(-) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 4b57e60..05fa6ef 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -174,14 +174,25 @@ static int kernel_bind_process(int32_t s, const struct sockaddr *name, socklen_t + struct lwip_sock *sock = lwip_get_socket(s); + int times = 10; + int ret = 0; ++ bool share_ip = true; ++ ++ /* lwip and kernel share IP, and exchange mbuf through virtual-NIC. ++ * lstack not sense if ltran enable kni, so only checks use_ltran. */ ++ ++ if (!get_global_cfg_params()->use_ltran && !get_global_cfg_params()->kni_switch && ++ !get_global_cfg_params()->flow_bifurcation) { ++ share_ip = false; ++ } + + ret = posix_api->bind_fn(s, name, namelen); +- /* maybe kni addr, ipv6 addr maybe is tentative,need to wait a few seconds */ +- if (name->sa_family == AF_INET6 && ret < 0 && errno == EADDRNOTAVAIL) { +- LSTACK_LOG(WARNING, LSTACK, "virtio_user addr is tentative, please wait... \n"); +- while (ret != 0 && times-- > 0) { +- sleep(1); +- ret = posix_api->bind_fn(s, name, namelen); ++ if (ret < 0 && errno == EADDRNOTAVAIL) { ++ /* ipv6 addr of virtual-NIC maybe is tentative, need to wait a few seconds */ ++ if (name->sa_family == AF_INET6 && share_ip) { ++ LSTACK_LOG(WARNING, LSTACK, "virtio_user addr is tentative, please wait... \n"); ++ while (ret != 0 && times-- > 0) { ++ sleep(1); ++ ret = posix_api->bind_fn(s, name, namelen); ++ } + } + } + +-- +2.33.0 + diff --git a/0309-Connect-execute-lwip-connect-if-dst_ip-and-host_ip-a.patch b/0309-Connect-execute-lwip-connect-if-dst_ip-and-host_ip-a.patch new file mode 100644 index 0000000..885171b --- /dev/null +++ b/0309-Connect-execute-lwip-connect-if-dst_ip-and-host_ip-a.patch @@ -0,0 +1,132 @@ +From 434a2509c25f265adb5d7b9398cb3bf8e379b387 Mon Sep 17 00:00:00 2001 +From: yinbin +Date: Sat, 14 Dec 2024 16:55:18 +0800 +Subject: [PATCH] Connect: execute lwip connect if dst_ip and host_ip are in + the same network. + +--- + src/lstack/api/lstack_wrap.c | 82 ++++++++++++++++++++++++++---------- + 1 file changed, 59 insertions(+), 23 deletions(-) + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 8077753..97e927a 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -256,7 +256,7 @@ static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen + return g_wrap_api->bind_fn(s, name, namelen); + } + +-static bool kernel_ip_route(const struct sockaddr *addr) ++static bool kernel_ip_match(const struct sockaddr *addr) + { + struct ifaddrs *ifap; + struct ifaddrs *ifa; +@@ -298,7 +298,27 @@ static bool kernel_ip_route(const struct sockaddr *addr) + freeifaddrs(ifap); + return false; + } +-static bool is_relatived_kernel_ip(const struct sockaddr *dst_addr) ++ ++static bool lwip_ip_route(const struct sockaddr *dst_addr) ++{ ++ uint32_t host_ip; ++ uint32_t host_mask; ++ uint32_t dst_ip; ++ ++ host_ip = get_global_cfg_params()->host_addr.addr; ++ host_mask = get_global_cfg_params()->netmask.addr; ++ if (dst_addr->sa_family == AF_INET) { ++ dst_ip = ((struct sockaddr_in *)dst_addr) ->sin_addr.s_addr; ++ /* if dst_addr and host_addr are in the same network, return ture. */ ++ if ((host_ip & host_mask) == (dst_ip & host_mask)) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++static bool kernel_ip_route(const struct sockaddr *dst_addr) + { + struct ifaddrs *ifap; + struct ifaddrs *ifa; +@@ -339,8 +359,34 @@ static bool is_relatived_kernel_ip(const struct sockaddr *dst_addr) + freeifaddrs(ifap); + return ret; + } ++ ++static bool should_enter_kernel_connect(const struct sockaddr *addr) ++{ ++ int32_t remote_port; ++ char listen_ring_name[RING_NAME_LEN]; ++ ++ remote_port = htons(((struct sockaddr_in *)addr)->sin_port); ++ snprintf_s(listen_ring_name, sizeof(listen_ring_name), sizeof(listen_ring_name) - 1, ++ "listen_rx_ring_%d", remote_port); ++ if (kernel_ip_match(addr) && rte_ring_lookup(listen_ring_name) == NULL) { ++ return true; ++ } ++ ++ if (lwip_ip_route(addr)) { ++ return false; ++ } ++ ++ if (kernel_ip_route(addr)) { ++ return true; ++ } ++ ++ return false; ++} ++ + static int32_t do_connect(int32_t s, const struct sockaddr *addr, socklen_t addrlen) + { ++ int32_t ret = 0; ++ + if (addr == NULL) { + GAZELLE_RETURN(EINVAL); + } +@@ -350,30 +396,20 @@ static int32_t do_connect(int32_t s, const struct sockaddr *addr, socklen_t addr + return posix_api->connect_fn(s, addr, addrlen); + } + +- int32_t ret = 0; +- int32_t remote_port; +- bool is_kernel = kernel_ip_route(addr); +- bool is_to_kernel_connect = is_relatived_kernel_ip(addr); +- +- remote_port = htons(((struct sockaddr_in *)addr)->sin_port); +- +- char listen_ring_name[RING_NAME_LEN]; +- snprintf_s(listen_ring_name, sizeof(listen_ring_name), sizeof(listen_ring_name) - 1, +- "listen_rx_ring_%d", remote_port); +- +- if ((is_kernel && rte_ring_lookup(listen_ring_name) == NULL) || is_to_kernel_connect) { ++ if (should_enter_kernel_connect(addr)) { + ret = posix_api->connect_fn(s, addr, addrlen); + POSIX_SET_TYPE(sock, POSIX_KERNEL); ++ return ret; ++ } ++ ++ /* When the socket is POSIX_LWIP_OR_KERNEL, connect to lwip first and then connect to kernel. */ ++ ret = g_wrap_api->connect_fn(s, addr, addrlen); ++ if (ret == 0 || (ret != 0 && errno == EINPROGRESS)) { ++ POSIX_SET_TYPE(sock, POSIX_LWIP); + } else { +- /* When the socket is POSIX_LWIP_OR_KERNEL, connect to lwip first and then connect to kernel. */ +- ret = g_wrap_api->connect_fn(s, addr, addrlen); +- if (ret == 0 || (ret != 0 && errno == EINPROGRESS)) { +- POSIX_SET_TYPE(sock, POSIX_LWIP); +- } else { +- ret = posix_api->connect_fn(s, addr, addrlen); +- if (ret == 0) { +- POSIX_SET_TYPE(sock, POSIX_KERNEL); +- } ++ ret = posix_api->connect_fn(s, addr, addrlen); ++ if (ret == 0) { ++ POSIX_SET_TYPE(sock, POSIX_KERNEL); + } + } + return ret; +-- +2.33.0 + diff --git a/gazelle.spec b/gazelle.spec index 8bfe603..790001d 100644 --- a/gazelle.spec +++ b/gazelle.spec @@ -2,7 +2,7 @@ Name: gazelle Version: 1.0.2 -Release: 79 +Release: 80 Summary: gazelle is a high performance user-mode stack License: MulanPSL-2.0 URL: https://gitee.com/openeuler/gazelle @@ -322,6 +322,10 @@ Patch9302: 0302-fix-rpc-pool-leak-when-thread-exits.patch Patch9303: 0303-fix-epoll-and-recv-threads-blocked-on-the-same-semap.patch Patch9304: 0304-fix-errno-ETIMEFOUT.patch Patch9305: 0305-cfg-notify-that-it-s-unsupported-when-stack_num-1.patch +Patch9306: 0306-fix-a-contention-issue-when-rpc-pools-are-added-to-r.patch +Patch9307: 0307-openGauss-unsupport_tcp_optname.patch +Patch9308: 0308-kernerl-bind-add-ipv6-add-check.patch +Patch9309: 0309-Connect-execute-lwip-connect-if-dst_ip-and-host_ip-a.patch %description %{name} is a high performance user-mode stack. @@ -363,6 +367,12 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b %config(noreplace) %{conf_path}/ltran.conf %changelog +* Wed Dec 18 2024 yinbin6 - 1.0.2-80 +- Connect: execute lwip connect if dst_ip and host_ip are in the same network. +- kernerl bind: add ipv6 add check +- openGauss unsupport_tcp_optname +- fix a contention issue when rpc pools are added to rpc_pool_array + * Wed Dec 11 2024 yinbin6 - 1.0.2-79 - cfg: notify that it's unsupported, when stack_num > 1 - fix errno == ETIMEFOUT