backport upstream patches:

update README
    fix some bugs
    refactor pkt read send to improve performance
    refactor kernle event toimproveperformance

(cherry picked from commit a8c66704608ca83c799adab88be6214bccdcfa44)
This commit is contained in:
jiangheng14 2022-07-07 21:58:03 +08:00 committed by openeuler-sync-bot
parent 58d91474c6
commit 46ab1e1590
17 changed files with 6066 additions and 1 deletions

View File

@ -0,0 +1,35 @@
From 912ac954d0f462418bb09d2ad91e7092d5ad37be Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng12@huawei.com>
Date: Tue, 19 Apr 2022 19:10:10 +0800
Subject: [PATCH 01/18] fix sock invalid address
sockets pointer is allocated memory in gazelle_network_init().
if invoke select_path before sockets pointer be initialized, sock is invalid
---
src/lstack/api/lstack_wrap.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c
index 6ee5639..0164069 100644
--- a/src/lstack/api/lstack_wrap.c
+++ b/src/lstack/api/lstack_wrap.c
@@ -52,10 +52,15 @@ static inline enum KERNEL_LWIP_PATH select_path(int fd)
}
return PATH_KERNEL;
}
+
+ if (unlikely(posix_api->is_chld)) {
+ return PATH_KERNEL;
+ }
+
struct lwip_sock *sock = posix_api->get_socket(fd);
/* AF_UNIX case */
- if (!sock || unlikely(posix_api->is_chld)) {
+ if (!sock) {
return PATH_KERNEL;
}
--
2.23.0

View File

@ -0,0 +1,70 @@
From 336703252c327d82f49d40f79b1d1e4e65a9281e Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng12@huawei.com>
Date: Tue, 19 Apr 2022 19:49:06 +0800
Subject: [PATCH 02/18] exit lstack process after ltran instance logout
close fd is to notify ltran to execute the lstack instance logout.
200ms is an empirical value of instance logout.
---
src/lstack/api/lstack_signal.c | 4 +++-
src/lstack/core/lstack_control_plane.c | 9 +++++++++
src/lstack/include/lstack_control_plane.h | 1 +
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/lstack/api/lstack_signal.c b/src/lstack/api/lstack_signal.c
index f4763e8..87cbdda 100644
--- a/src/lstack/api/lstack_signal.c
+++ b/src/lstack/api/lstack_signal.c
@@ -19,8 +19,9 @@
#include <lwip/posix_api.h>
#include "lstack_log.h"
+#include "lstack_control_plane.h"
-static int g_hijack_signal[] = { SIGTERM, SIGINT, SIGSEGV, SIGBUS, SIGFPE, SIGILL };
+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)
@@ -54,6 +55,7 @@ static inline bool match_hijack_signal(int sig)
static void lstack_sig_default_handler(int sig)
{
LSTACK_LOG(ERR, LSTACK, "lstack dumpedcaught signal%d\n", sig);
+ control_fd_close();
dump_stack();
lwip_exit();
(void)kill(getpid(), sig);
diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c
index c782d51..01b2ff0 100644
--- a/src/lstack/core/lstack_control_plane.c
+++ b/src/lstack/core/lstack_control_plane.c
@@ -446,6 +446,15 @@ int32_t client_reg_thrd_ring(void)
return 0;
}
+void control_fd_close(void)
+{
+ if (g_data_fd != 0) {
+ close(g_data_fd);
+ /* 200ms: wait ltran instance logout */
+ rte_delay_ms(200);
+ }
+}
+
int32_t control_init_client(bool is_reconnect)
{
int32_t ret;
diff --git a/src/lstack/include/lstack_control_plane.h b/src/lstack/include/lstack_control_plane.h
index 0af891a..1fa84e6 100644
--- a/src/lstack/include/lstack_control_plane.h
+++ b/src/lstack/include/lstack_control_plane.h
@@ -32,5 +32,6 @@ void control_server_thread(void *arg);
bool get_register_state(void);
void thread_register_phase1(struct rpc_msg *msg);
void thread_register_phase2(struct rpc_msg *msg);
+void control_fd_close(void);
#endif /* GAZELLE_CONTROL_PLANE_H */
--
2.23.0

View File

@ -0,0 +1,78 @@
From 900685bd99e25f832c4aeac202dfb7d5f5075833 Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng12@huawei.com>
Date: Tue, 19 Apr 2022 20:01:34 +0800
Subject: [PATCH 03/18] use atomic variales to count
name_tick and pool_index are shared by mutiple threads.
atomic variables are required.
---
src/lstack/core/lstack_lwip.c | 9 +++++----
src/lstack/core/lstack_thread_rpc.c | 3 ++-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c
index 887464d..4143f2f 100644
--- a/src/lstack/core/lstack_lwip.c
+++ b/src/lstack/core/lstack_lwip.c
@@ -11,6 +11,7 @@
*/
#include <sys/types.h>
+#include <stdatomic.h>
#include <lwip/sockets.h>
#include <lwip/tcp.h>
#include <lwipsock.h>
@@ -138,25 +139,25 @@ void gazelle_init_sock(int32_t fd)
reset_sock_data(sock);
- sock->recv_ring = create_ring("sock_recv", SOCK_RECV_RING_SIZE, 0, name_tick++);
+ sock->recv_ring = create_ring("sock_recv", SOCK_RECV_RING_SIZE, 0, atomic_fetch_add(&name_tick, 1));
if (sock->recv_ring == NULL) {
LSTACK_LOG(ERR, LSTACK, "sock_recv create failed. errno: %d.\n", rte_errno);
return;
}
- sock->recv_wait_free = create_ring("wait_free", SOCK_RECV_RING_SIZE, 0, name_tick++);
+ sock->recv_wait_free = create_ring("wait_free", SOCK_RECV_RING_SIZE, 0, atomic_fecth_add(&name_tick, 1));
if (sock->recv_wait_free == NULL) {
LSTACK_LOG(ERR, LSTACK, "wait_free create failed. errno: %d.\n", rte_errno);
return;
}
- sock->send_ring = create_ring("sock_send", SOCK_SEND_RING_SIZE, 0, name_tick++);
+ sock->send_ring = create_ring("sock_send", SOCK_SEND_RING_SIZE, 0, atomic_fecth_add(&name_tick, 1));
if (sock->send_ring == NULL) {
LSTACK_LOG(ERR, LSTACK, "sock_send create failed. errno: %d.\n", rte_errno);
return;
}
- sock->send_idle_ring = create_ring("idle_send", SOCK_SEND_RING_SIZE, 0, name_tick++);
+ sock->send_idle_ring = create_ring("idle_send", SOCK_SEND_RING_SIZE, 0, atomic_fetch_add(&name_tick, 1));
if (sock->send_idle_ring == NULL) {
LSTACK_LOG(ERR, LSTACK, "idle_send create failed. errno: %d.\n", rte_errno);
return;
diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c
index 26725f7..312e192 100644
--- a/src/lstack/core/lstack_thread_rpc.c
+++ b/src/lstack/core/lstack_thread_rpc.c
@@ -10,6 +10,7 @@
* See the Mulan PSL v2 for more details.
*/
#include <sys/types.h>
+#include <stdatomic.h>
#include <lwip/sockets.h>
#include <lwipsock.h>
#include <rte_mempool.h>
@@ -36,7 +37,7 @@ struct rpc_msg *rpc_msg_alloc(struct protocol_stack *stack, rpc_msg_func func)
static uint16_t pool_index = 0;
if (rpc_pool == NULL) {
- rpc_pool = create_rpc_mempool("rpc_msg", pool_index++);
+ rpc_pool = create_rpc_mempool("rpc_msg", atomic_fetch_add(&pool_index, 1));
if (rpc_pool == NULL) {
return NULL;
}
--
2.23.0

View File

@ -0,0 +1,45 @@
From 7f4143cd462cba5499cda0434fedd498c0967623 Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng12@huawei.com>
Date: Tue, 19 Apr 2022 21:28:00 +0800
Subject: [PATCH 04/18] re-arrange the program to invoke rte_eth_dev_start
before rss_setup
in rss_setup(), the program invokes rte_eth_dev_rss_reta_update().
this API should be invoked after rte_eth_dev_start().
---
src/lstack/core/lstack_dpdk.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c
index 3f446ea..a5b2ddc 100644
--- a/src/lstack/core/lstack_dpdk.c
+++ b/src/lstack/core/lstack_dpdk.c
@@ -495,6 +495,12 @@ int32_t dpdk_ethdev_init(void)
return ret;
}
+ ret = dpdk_ethdev_start();
+ if (ret < 0) {
+ LSTACK_LOG(ERR, LSTACK, "dpdk_ethdev_start failed\n");
+ return ret;
+ }
+
if (rss_enable) {
rss_setup(port_id, nb_queues);
}
@@ -604,12 +610,6 @@ int32_t init_dpdk_ethdev(void)
return -1;
}
- ret = dpdk_ethdev_start();
- if (ret < 0) {
- LSTACK_LOG(ERR, LSTACK, "dpdk_ethdev_start failed\n");
- return -1;
- }
-
if (get_global_cfg_params()->kni_switch) {
ret = dpdk_init_lstack_kni();
if (ret < 0) {
--
2.23.0

View File

@ -0,0 +1,183 @@
From f3059a5a1e2fcf5b7bfa2ad50865598f79eccf16 Mon Sep 17 00:00:00 2001
From: wuchangsheng <wuchangsheng2@huawei.com>
Date: Thu, 21 Apr 2022 15:24:20 +0800
Subject: [PATCH 05/18] delete redundant file
---
src/lstack/include/lstack_lstack.h | 32 --------
src/lstack/include/lstack_weakup.h | 124 -----------------------------
2 files changed, 156 deletions(-)
delete mode 100644 src/lstack/include/lstack_lstack.h
delete mode 100644 src/lstack/include/lstack_weakup.h
diff --git a/src/lstack/include/lstack_lstack.h b/src/lstack/include/lstack_lstack.h
deleted file mode 100644
index c2e6733..0000000
--- a/src/lstack/include/lstack_lstack.h
+++ /dev/null
@@ -1,32 +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 _LSTACK_H
-#define _LSTACK_H
-
-#if defined __GNUC__
-#define LSTACK_EXPORT_SYMBOL __attribute__((visibility("default")))
-
-#elif defined(_MSC_VER)
-#define LSTACK_EXPORT_SYMBOL extern __declspec(dllexport)
-
-#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
-#define LSTACK_EXPORT_SYMBOL __global
-
-#else
-#define LSTACK_EXPORT_SYMBOL /* unknown compiler */
-#endif
-
-/* Return string describing version of currently running lstack. */
-LSTACK_EXPORT_SYMBOL const char *get_lstack_version(void);
-
-#endif /* lstack.h */
diff --git a/src/lstack/include/lstack_weakup.h b/src/lstack/include/lstack_weakup.h
deleted file mode 100644
index 77f3b9d..0000000
--- a/src/lstack/include/lstack_weakup.h
+++ /dev/null
@@ -1,124 +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_WEAKUP_THREAD_H__
-#define __GAZELLE_WEAKUP_THREAD_H__
-
-#include <rte_ring.h>
-#include "lstack_dpdk.h"
-
-#define EPOLL_MAX_EVENTS 512
-
-struct weakup_poll {
- sem_t event_sem;
- struct lwip_sock *sock_list[EPOLL_MAX_EVENTS];
- struct rte_ring *event_ring;
- struct rte_ring *self_ring;
-};
-
-#define WEAKUP_MAX (32)
-
-static inline void wakeup_list_sock(struct list_node *wakeup_list)
-{
- struct list_node *node, *temp;
-
- list_for_each_safe(node, temp, wakeup_list) {
- struct lwip_sock *sock = container_of(node, struct lwip_sock, wakeup_list);
-
- struct weakup_poll *weakup = sock->weakup;
- struct protocol_stack *stack = sock->stack;
- if (weakup == NULL || stack == NULL) {
- list_del_node_init(&sock->wakeup_list);
- continue;
- }
-
- int32_t ret = rte_ring_mp_enqueue(weakup->event_ring, (void *)sock);
- if (ret == 0) {
- list_del_node_init(&sock->wakeup_list);
- sem_post(&weakup->event_sem);
- stack->stats.lwip_events++;
- } else {
- break;
- }
- }
-}
-
-static inline int32_t weakup_attach_sock(struct list_node *attach_list)
-{
- struct list_node *node, *temp;
- int32_t wakeuped = -1;
-
- list_for_each_safe(node, temp, attach_list) {
- struct lwip_sock *sock = container_of(node, struct lwip_sock, attach_list);
-
- struct weakup_poll *weakup = sock->weakup;
- struct protocol_stack *stack = sock->stack;
- if (weakup == NULL || stack == NULL) {
- continue;
- }
-
- int32_t ret = rte_ring_mp_enqueue(weakup->event_ring, (void *)sock);
- if (ret == 0) {
- sem_post(&weakup->event_sem);
- stack->stats.lwip_events++;
- wakeuped = 0;
- }
- }
-
- return wakeuped;
-}
-
-static inline void weakup_thread(struct rte_ring *weakup_ring, struct list_node *wakeup_list)
-{
- struct lwip_sock *sock;
-
- for (uint32_t i = 0; i < WEAKUP_MAX; ++i) {
- int32_t ret = rte_ring_sc_dequeue(weakup_ring, (void **)&sock);
- if (ret != 0) {
- break;
- }
-
- struct weakup_poll *weakup = sock->weakup;
- struct protocol_stack *stack = sock->stack;
- if (weakup == NULL || stack == NULL) {
- continue;
- }
-
- ret = rte_ring_mp_enqueue(weakup->event_ring, (void *)sock);
- if (ret == 0) {
- sem_post(&weakup->event_sem);
- stack->stats.lwip_events++;
- }
-
- /* listen notice attach sock */
- int32_t wakeuped = -1;
- if (!list_is_empty(&sock->attach_list)) {
- wakeuped = weakup_attach_sock(&sock->attach_list);
- }
-
- /* notice any epoll enough */
- if (ret != 0 && wakeuped != 0) {
- if (list_is_empty(&sock->wakeup_list)) {
- list_add_node(wakeup_list, &sock->wakeup_list);
- }
- break;
- }
- }
-}
-
-static inline __attribute__((always_inline))
-int weakup_enqueue(struct rte_ring *weakup_ring, struct lwip_sock *sock)
-{
- return rte_ring_sp_enqueue(weakup_ring, (void *)sock);
-}
-
-#endif
--
2.23.0

View File

@ -0,0 +1,297 @@
From 625c01d808ffd9a21bcd5705b7237d00acd7ee66 Mon Sep 17 00:00:00 2001
From: wuchangsheng <wuchangsheng2@huawei.com>
Date: Thu, 21 Apr 2022 15:34:36 +0800
Subject: [PATCH 06/18] lstack:all exit move to init
---
src/lstack/core/lstack_control_plane.c | 5 +--
src/lstack/core/lstack_dpdk.c | 23 ++++++++------
src/lstack/core/lstack_init.c | 20 +++++++++++-
src/lstack/core/lstack_lwip.c | 4 +--
src/lstack/core/lstack_protocol_stack.c | 37 ++++++++++++----------
src/lstack/include/lstack_dpdk.h | 2 +-
src/lstack/include/lstack_protocol_stack.h | 4 ++-
7 files changed, 61 insertions(+), 34 deletions(-)
diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c
index 01b2ff0..13a2ed3 100644
--- a/src/lstack/core/lstack_control_plane.c
+++ b/src/lstack/core/lstack_control_plane.c
@@ -699,12 +699,13 @@ void control_server_thread(void *arg)
{
int32_t listenfd = control_init_server();
if (listenfd < 0) {
- LSTACK_EXIT(1, "control_init_server failed\n");
+ LSTACK_LOG(ERR, LSTACK, "control_init_server failed\n");
+ return;
}
int32_t epfd = init_epoll(listenfd);
if (epfd < 0) {
- LSTACK_EXIT(1, "init_epoll failed\n");
+ LSTACK_LOG(ERR, LSTACK, "control_init_server failed\n");
return;
}
diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c
index a5b2ddc..aa91201 100644
--- a/src/lstack/core/lstack_dpdk.c
+++ b/src/lstack/core/lstack_dpdk.c
@@ -86,21 +86,26 @@ int32_t thread_affinity_init(int32_t cpu_id)
return 0;
}
-void dpdk_eal_init(void)
+int32_t dpdk_eal_init(void)
{
int32_t ret;
struct cfg_params *global_params = get_global_cfg_params();
ret = rte_eal_init(global_params->dpdk_argc, global_params->dpdk_argv);
if (ret < 0) {
- if (rte_errno == EALREADY)
+ if (rte_errno == EALREADY) {
LSTACK_PRE_LOG(LSTACK_INFO, "rte_eal_init aleady init\n");
- else
+ /* maybe other program inited, merge init param share init */
+ ret = 0;
+ }
+ else {
LSTACK_PRE_LOG(LSTACK_ERR, "rte_eal_init failed init, rte_errno %d\n", rte_errno);
-
- LSTACK_EXIT(1, "pthread_getaffinity_np failed\n");
+ }
+ } else {
+ LSTACK_PRE_LOG(LSTACK_INFO, "dpdk_eal_init success\n");
}
- LSTACK_PRE_LOG(LSTACK_INFO, "dpdk_eal_init success\n");
+
+ return ret;
}
static struct rte_mempool *create_pktmbuf_mempool(const char *name, uint32_t nb_mbuf,
@@ -116,13 +121,11 @@ static struct rte_mempool *create_pktmbuf_mempool(const char *name, uint32_t nb_
}
/* time stamp before pbuf_custom as priv_data */
- pthread_mutex_lock(get_mem_mutex());
pool = rte_pktmbuf_pool_create(pool_name, nb_mbuf, mbuf_cache_size,
sizeof(struct pbuf_custom) + GAZELLE_MBUFF_PRIV_SIZE, MBUF_SZ, rte_socket_id());
if (pool == NULL) {
LSTACK_LOG(ERR, LSTACK, "cannot create %s pool rte_err=%d\n", pool_name, rte_errno);
}
- pthread_mutex_unlock(get_mem_mutex());
return pool;
}
@@ -136,13 +139,13 @@ struct rte_mempool *create_rpc_mempool(const char *name, uint16_t queue_id)
if (ret < 0) {
return NULL;
}
- pthread_mutex_lock(get_mem_mutex());
+
pool = rte_mempool_create(pool_name, CALL_POOL_SZ, sizeof(struct rpc_msg), 0, 0, NULL, NULL, NULL,
NULL, rte_socket_id(), 0);
if (pool == NULL) {
LSTACK_LOG(ERR, LSTACK, "cannot create %s pool rte_err=%d\n", pool_name, rte_errno);
}
- pthread_mutex_unlock(get_mem_mutex());
+
return pool;
}
diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c
index 774d0f3..335d834 100644
--- a/src/lstack/core/lstack_init.c
+++ b/src/lstack/core/lstack_init.c
@@ -48,6 +48,13 @@
#define LSTACK_PRELOAD_NAME_LEN PATH_MAX
#define LSTACK_PRELOAD_ENV_PROC "GAZELLE_BIND_PROCNAME"
+static volatile int32_t g_init_fail = 0;
+
+void set_init_fail(void)
+{
+ g_init_fail = 1;
+}
+
struct lstack_preload {
int32_t preload_switch;
char env_procname[LSTACK_PRELOAD_NAME_LEN];
@@ -207,7 +214,11 @@ __attribute__((constructor)) void gazelle_network_init(void)
}
ret = pthread_create(&tid, NULL, (void *(*)(void *))control_client_thread, NULL);
} else {
- dpdk_eal_init();
+ ret = dpdk_eal_init();
+ if (ret < 0) {
+ LSTACK_EXIT(1, "dpdk_eal_init failed ret=%d errno=%d\n", ret, errno);
+ }
+
ret = pthread_create(&tid, NULL, (void *(*)(void *))control_server_thread, NULL);
}
if (ret != 0) {
@@ -248,7 +259,14 @@ __attribute__((constructor)) void gazelle_network_init(void)
* Phase 10: register core sig handler func to dumped stack */
lstack_signal_init();
+ /* wait stack thread and kernel_event thread init finish */
+ wait_sem_value(&get_protocol_stack_group()->all_init, get_protocol_stack_group()->stack_num);
+ if (g_init_fail) {
+ LSTACK_EXIT(1, "stack thread or kernel_event thread failed\n");
+ }
+
lstack_prelog_uninit();
posix_api->is_chld = 0;
LSTACK_LOG(INFO, LSTACK, "gazelle_network_init success\n");
+ rte_smp_mb();
}
diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c
index 4143f2f..00a82fb 100644
--- a/src/lstack/core/lstack_lwip.c
+++ b/src/lstack/core/lstack_lwip.c
@@ -145,13 +145,13 @@ void gazelle_init_sock(int32_t fd)
return;
}
- sock->recv_wait_free = create_ring("wait_free", SOCK_RECV_RING_SIZE, 0, atomic_fecth_add(&name_tick, 1));
+ sock->recv_wait_free = create_ring("wait_free", SOCK_RECV_RING_SIZE, 0, atomic_fetch_add(&name_tick, 1));
if (sock->recv_wait_free == NULL) {
LSTACK_LOG(ERR, LSTACK, "wait_free create failed. errno: %d.\n", rte_errno);
return;
}
- sock->send_ring = create_ring("sock_send", SOCK_SEND_RING_SIZE, 0, atomic_fecth_add(&name_tick, 1));
+ sock->send_ring = create_ring("sock_send", SOCK_SEND_RING_SIZE, 0, atomic_fetch_add(&name_tick, 1));
if (sock->send_ring == NULL) {
LSTACK_LOG(ERR, LSTACK, "sock_send create failed. errno: %d.\n", rte_errno);
return;
diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c
index da320e2..8f0b785 100644
--- a/src/lstack/core/lstack_protocol_stack.c
+++ b/src/lstack/core/lstack_protocol_stack.c
@@ -39,19 +39,14 @@
static PER_THREAD uint16_t g_stack_idx = PROTOCOL_STACK_MAX;
static struct protocol_stack_group g_stack_group = {0};
static PER_THREAD long g_stack_tid = 0;
-static pthread_mutex_t g_mem_mutex = PTHREAD_MUTEX_INITIALIZER;
+void set_init_fail(void);
typedef void *(*stack_thread_func)(void *arg);
#ifdef GAZELLE_USE_EPOLL_EVENT_STACK
void update_stack_events(struct protocol_stack *stack);
#endif
-pthread_mutex_t *get_mem_mutex(void)
-{
- return &g_mem_mutex;
-}
-
int32_t bind_to_stack_numa(struct protocol_stack *stack)
{
int32_t ret;
@@ -248,6 +243,14 @@ static void init_stack_value(struct protocol_stack *stack, uint16_t queue_id)
stack_group->stacks[queue_id] = stack;
}
+void wait_sem_value(sem_t *sem, int32_t wait_value)
+{
+ int32_t sem_val;
+ do {
+ sem_getvalue(sem, &sem_val);
+ } while (sem_val < wait_value);
+}
+
static struct protocol_stack * stack_thread_init(uint16_t queue_id)
{
struct protocol_stack_group *stack_group = get_protocol_stack_group();
@@ -304,10 +307,10 @@ static struct protocol_stack * stack_thread_init(uint16_t queue_id)
sem_post(&stack_group->thread_phase1);
- int32_t sem_val;
- do {
- sem_getvalue(&stack_group->ethdev_init, &sem_val);
- } while (!sem_val && !use_ltran());
+ if (!use_ltran()) {
+ wait_sem_value(&stack_group->ethdev_init, 1);
+ }
+
ret = ethdev_init(stack);
if (ret != 0) {
@@ -332,10 +335,13 @@ static void* gazelle_stack_thread(void *arg)
struct protocol_stack *stack = stack_thread_init(queue_id);
if (stack == NULL) {
- pthread_mutex_lock(&g_mem_mutex);
- LSTACK_EXIT(1, "stack_thread_init failed\n");
- pthread_mutex_unlock(&g_mem_mutex);
+ /* exit in main thread, avoid create mempool and exit at the same time */
+ set_init_fail();
+ sem_post(&get_protocol_stack_group()->all_init);
+ LSTACK_LOG(ERR, LSTACK, "stack_thread_init failed queue_id=%d\n", queue_id);
+ return NULL;
}
+ sem_post(&get_protocol_stack_group()->all_init);
LSTACK_LOG(INFO, LSTACK, "stack_%02d init success\n", queue_id);
for (;;) {
@@ -386,10 +392,7 @@ int32_t init_protocol_stack(void)
}
}
- int32_t thread_inited_num;
- do {
- sem_getvalue(&stack_group->thread_phase1, &thread_inited_num);
- } while (thread_inited_num < stack_group->stack_num);
+ wait_sem_value(&stack_group->thread_phase1, stack_group->stack_num);
ret = init_stack_numa_cpuset();
if (ret < 0) {
diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h
index e8080e1..4295f01 100644
--- a/src/lstack/include/lstack_dpdk.h
+++ b/src/lstack/include/lstack_dpdk.h
@@ -58,7 +58,7 @@ int thread_affinity_default(void);
int thread_affinity_init(int cpu_id);
int32_t fill_mbuf_to_ring(struct rte_mempool *mempool, struct rte_ring *ring, uint32_t mbuf_num);
-void dpdk_eal_init(void);
+int32_t dpdk_eal_init(void);
int32_t pktmbuf_pool_init(struct protocol_stack *stack, uint16_t stack_num);
struct rte_ring *create_ring(const char *name, uint32_t count, uint32_t flags, int32_t queue_id);
int32_t create_shared_ring(struct protocol_stack *stack);
diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h
index 9753385..9852878 100644
--- a/src/lstack/include/lstack_protocol_stack.h
+++ b/src/lstack/include/lstack_protocol_stack.h
@@ -64,6 +64,7 @@ struct protocol_stack_group {
uint16_t port_id;
sem_t thread_phase1;
sem_t ethdev_init;
+ sem_t all_init;
struct rte_mempool *kni_pktmbuf_pool;
struct eth_params *eth_params;
struct protocol_stack *stacks[PROTOCOL_STACK_MAX];
@@ -82,7 +83,6 @@ struct wakeup_poll {
};
long get_stack_tid(void);
-pthread_mutex_t *get_mem_mutex(void);
struct protocol_stack *get_protocol_stack(void);
struct protocol_stack *get_protocol_stack_by_fd(int32_t fd);
struct protocol_stack *get_minconn_protocol_stack(void);
@@ -92,6 +92,8 @@ int32_t init_protocol_stack(void);
int32_t 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);
--
2.23.0

View File

@ -0,0 +1,356 @@
From 77a8fb02a7c4352fee106d0aa83500d81c20d315 Mon Sep 17 00:00:00 2001
From: wuchangsheng <wuchangsheng2@huawei.com>
Date: Thu, 21 Apr 2022 16:42:01 +0800
Subject: [PATCH 07/18] clean code:fix huge func
---
src/lstack/core/lstack_control_plane.c | 2 +-
src/lstack/core/lstack_init.c | 101 +++++++++++++-----------
src/lstack/core/lstack_protocol_stack.c | 89 +++++++++++----------
3 files changed, 105 insertions(+), 87 deletions(-)
diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c
index 13a2ed3..26a1b1c 100644
--- a/src/lstack/core/lstack_control_plane.c
+++ b/src/lstack/core/lstack_control_plane.c
@@ -705,7 +705,7 @@ void control_server_thread(void *arg)
int32_t epfd = init_epoll(listenfd);
if (epfd < 0) {
- LSTACK_LOG(ERR, LSTACK, "control_init_server failed\n");
+ LSTACK_LOG(ERR, LSTACK, "init_epoll failed\n");
return;
}
diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c
index 335d834..037b8fd 100644
--- a/src/lstack/core/lstack_init.c
+++ b/src/lstack/core/lstack_init.c
@@ -155,12 +155,52 @@ __attribute__((destructor)) void gazelle_network_exit(void)
}
}
-__attribute__((constructor)) void gazelle_network_init(void)
+static void create_control_thread(void)
{
int32_t ret;
+ pthread_t tid;
+ if (use_ltran()) {
+ dpdk_skip_nic_init();
+ if (control_init_client(false) != 0) {
+ LSTACK_EXIT(1, "control_init_client failed\n");
+ }
+ ret = pthread_create(&tid, NULL, (void *(*)(void *))control_client_thread, NULL);
+ } else {
+ ret = dpdk_eal_init();
+ if (ret < 0) {
+ LSTACK_EXIT(1, "dpdk_eal_init failed ret=%d errno=%d\n", ret, errno);
+ }
+
+ ret = pthread_create(&tid, NULL, (void *(*)(void *))control_server_thread, NULL);
+ }
+ if (ret != 0) {
+ LSTACK_EXIT(1, "pthread_create failed ret=%d errno=%d\n", ret, errno);
+ }
+
+ if (pthread_setname_np(tid, CONTROL_THREAD_NAME) != 0) {
+ LSTACK_LOG(ERR, LSTACK, "pthread_setname_np failed errno=%d\n", errno);
+ }
+ 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();
+}
+
+__attribute__((constructor)) void gazelle_network_init(void)
+{
/*
- * Phase 1: Init POSXI API and prelog */
+ * Init POSXI API and prelog */
lstack_prelog_init("LSTACK");
if (posix_api_init() != 0) {
LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n");
@@ -168,7 +208,7 @@ __attribute__((constructor)) void gazelle_network_init(void)
}
/*
- * Phase 2: Init LD_PRELOAD */
+ * Init LD_PRELOAD */
if (preload_info_init() < 0) {
return;
}
@@ -177,7 +217,7 @@ __attribute__((constructor)) void gazelle_network_init(void)
}
/*
- * Phase 3: Read configure from lstack.cfg */
+ * Read configure from lstack.cfg */
if (cfg_init() != 0) {
LSTACK_PRE_LOG(LSTACK_ERR, "cfg_init failed\n");
LSTACK_EXIT(1, "cfg_init failed\n");
@@ -185,87 +225,56 @@ __attribute__((constructor)) void gazelle_network_init(void)
LSTACK_PRE_LOG(LSTACK_INFO, "cfg_init success\n");
/*
- * Phase 4: check conflict */
+ * check conflict */
if (check_process_conflict() < 0) {
LSTACK_PRE_LOG(LSTACK_INFO, "Have another same primary process. WARNING: Posix API will use kernel mode!\n");
return;
}
/*
- * Phase 5: save initial affinity */
+ * save initial affinity */
if (thread_affinity_default() < 0) {
LSTACK_PRE_LOG(LSTACK_ERR, "pthread_getaffinity_np failed\n");
LSTACK_EXIT(1, "pthread_getaffinity_np failed\n");
}
- /* 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");
- }
+ gazelle_signal_init();
/*
- * Phase 6: Init control plane and dpdk init */
- pthread_t tid;
- if (use_ltran()) {
- dpdk_skip_nic_init();
- if (control_init_client(false) != 0) {
- LSTACK_EXIT(1, "control_init_client failed\n");
- }
- ret = pthread_create(&tid, NULL, (void *(*)(void *))control_client_thread, NULL);
- } else {
- ret = dpdk_eal_init();
- if (ret < 0) {
- LSTACK_EXIT(1, "dpdk_eal_init failed ret=%d errno=%d\n", ret, errno);
- }
-
- ret = pthread_create(&tid, NULL, (void *(*)(void *))control_server_thread, NULL);
- }
- if (ret != 0) {
- LSTACK_EXIT(1, "pthread_create failed errno=%d\n", errno);
- }
- if (pthread_setname_np(tid, CONTROL_THREAD_NAME) != 0) {
- LSTACK_LOG(ERR, LSTACK, "pthread_setname_np failed errno=%d\n", errno);
- }
- LSTACK_LOG(INFO, LSTACK, "create control_easy_thread success\n");
+ * Init control plane and dpdk init */
+ create_control_thread();
/*
- * Phase 7: cancel the core binding from DPDK initialization */
+ * cancel the core binding from DPDK initialization */
if (thread_affinity_default() < 0) {
LSTACK_EXIT(1, "pthread_setaffinity_np failed\n");
}
lstack_log_level_init();
+ lstack_prelog_uninit();
- ret = init_protocol_stack();
- if (ret != 0) {
+ if (init_protocol_stack() != 0) {
LSTACK_EXIT(1, "init_protocol_stack failed\n");
}
/*
- * Phase 8: nic */
+ * nic */
if (!use_ltran()) {
- ret = init_dpdk_ethdev();
- if (ret != 0) {
+ if (init_dpdk_ethdev() != 0) {
LSTACK_EXIT(1, "init_dpdk_ethdev failed\n");
}
}
/*
- * Phase 9: lwip initialization */
+ * lwip initialization */
lwip_sock_init();
- /*
- * Phase 10: register core sig handler func to dumped stack */
- lstack_signal_init();
-
/* wait stack thread and kernel_event thread init finish */
wait_sem_value(&get_protocol_stack_group()->all_init, get_protocol_stack_group()->stack_num);
if (g_init_fail) {
LSTACK_EXIT(1, "stack thread or kernel_event thread failed\n");
}
- lstack_prelog_uninit();
posix_api->is_chld = 0;
LSTACK_LOG(INFO, LSTACK, "gazelle_network_init success\n");
rte_smp_mb();
diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c
index 8f0b785..565d19b 100644
--- a/src/lstack/core/lstack_protocol_stack.c
+++ b/src/lstack/core/lstack_protocol_stack.c
@@ -217,7 +217,7 @@ static void* gazelle_weakup_thread(void *arg)
return NULL;
}
-static void init_stack_value(struct protocol_stack *stack, uint16_t queue_id)
+static int32_t init_stack_value(struct protocol_stack *stack, uint16_t queue_id)
{
struct protocol_stack_group *stack_group = get_protocol_stack_group();
@@ -241,6 +241,31 @@ static void init_stack_value(struct protocol_stack *stack, uint16_t queue_id)
stack_stat_init();
stack_group->stacks[queue_id] = stack;
+
+ cpu_set_t cpuset;
+ CPU_ZERO(&cpuset);
+ CPU_SET(stack->cpu_id, &cpuset);
+ if (rte_thread_set_affinity(&cpuset) != 0) {
+ LSTACK_LOG(ERR, LSTACK, "rte_thread_set_affinity failed\n");
+ return -1;
+ }
+ RTE_PER_LCORE(_lcore_id) = stack->cpu_id;
+
+ stack->socket_id = numa_node_of_cpu(stack->cpu_id);
+ if (stack->socket_id < 0) {
+ LSTACK_LOG(ERR, LSTACK, "numa_node_of_cpu failed\n");
+ return -1;
+ }
+
+ if (pktmbuf_pool_init(stack, stack_group->stack_num) != 0) {
+ return -1;
+ }
+
+ if (create_shared_ring(stack) != 0) {
+ return -1;
+ }
+
+ return 0;
}
void wait_sem_value(sem_t *sem, int32_t wait_value)
@@ -260,33 +285,8 @@ static struct protocol_stack * stack_thread_init(uint16_t queue_id)
LSTACK_LOG(ERR, LSTACK, "malloc stack failed\n");
return NULL;
}
- init_stack_value(stack, queue_id);
-
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- CPU_SET(stack->cpu_id, &cpuset);
- if (rte_thread_set_affinity(&cpuset) != 0) {
- LSTACK_LOG(ERR, LSTACK, "rte_thread_set_affinity failed\n");
- free(stack);
- return NULL;
- }
- RTE_PER_LCORE(_lcore_id) = stack->cpu_id;
-
- stack->socket_id = numa_node_of_cpu(stack->cpu_id);
- if (stack->socket_id < 0) {
- LSTACK_LOG(ERR, LSTACK, "numa_node_of_cpu failed\n");
- free(stack);
- return NULL;
- }
- int32_t ret = pktmbuf_pool_init(stack, stack_group->stack_num);
- if (ret != 0) {
- free(stack);
- return NULL;
- }
-
- ret = create_shared_ring(stack);
- if (ret != 0) {
+ if (init_stack_value(stack, queue_id) != 0) {
free(stack);
return NULL;
}
@@ -298,8 +298,7 @@ static struct protocol_stack * stack_thread_init(uint16_t queue_id)
tcpip_init(NULL, NULL);
if (use_ltran()) {
- ret = client_reg_thrd_ring();
- if (ret != 0) {
+ if (client_reg_thrd_ring() != 0) {
free(stack);
return NULL;
}
@@ -311,15 +310,13 @@ static struct protocol_stack * stack_thread_init(uint16_t queue_id)
wait_sem_value(&stack_group->ethdev_init, 1);
}
-
- ret = ethdev_init(stack);
- if (ret != 0) {
+ if (ethdev_init(stack) != 0) {
free(stack);
return NULL;
}
if (stack_group->wakeup_enable) {
- ret = create_thread(stack->queue_id, "gazelleweakup", gazelle_weakup_thread);
+ int32_t ret = create_thread(stack->queue_id, "gazelleweakup", gazelle_weakup_thread);
if (ret != 0) {
free(stack);
return NULL;
@@ -363,25 +360,37 @@ static void* gazelle_stack_thread(void *arg)
return NULL;
}
-int32_t init_protocol_stack(void)
+static int32_t init_protocol_sem(void)
{
- struct protocol_stack_group *stack_group = get_protocol_stack_group();
int32_t ret;
-
- stack_group->stack_num = get_global_cfg_params()->num_cpu;
- stack_group->wakeup_enable = (get_global_cfg_params()->num_wakeup > 0) ? true : false;
+ struct protocol_stack_group *stack_group = get_protocol_stack_group();
if (!use_ltran()) {
ret = sem_init(&stack_group->ethdev_init, 0, 0);
if (ret < 0) {
- LSTACK_LOG(ERR, PORT, "sem_init failed\n");
+ LSTACK_LOG(ERR, PORT, "sem_init failed ret=%d errno=%d\n", ret, errno);
return -1;
}
}
ret = sem_init(&stack_group->thread_phase1, 0, 0);
if (ret < 0) {
- LSTACK_LOG(ERR, PORT, "sem_init failed\n");
+ LSTACK_LOG(ERR, PORT, "sem_init failed ret=%d errno=%d\n", ret, errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t init_protocol_stack(void)
+{
+ struct protocol_stack_group *stack_group = get_protocol_stack_group();
+ int32_t ret;
+
+ stack_group->stack_num = get_global_cfg_params()->num_cpu;
+ stack_group->wakeup_enable = (get_global_cfg_params()->num_wakeup > 0) ? true : false;
+
+ if (init_protocol_sem() != 0) {
return -1;
}
--
2.23.0

View File

@ -0,0 +1,58 @@
From 17fa541e456acccae61669fcc403b44e4aabb2d5 Mon Sep 17 00:00:00 2001
From: wuchangsheng <wuchangsheng2@huawei.com>
Date: Thu, 21 Apr 2022 16:59:44 +0800
Subject: [PATCH 08/18] add kernel path in epoll funcs
---
src/lstack/api/lstack_wrap.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c
index 0164069..f623da3 100644
--- a/src/lstack/api/lstack_wrap.c
+++ b/src/lstack/api/lstack_wrap.c
@@ -77,6 +77,15 @@ static inline enum KERNEL_LWIP_PATH select_path(int fd)
static inline int32_t do_epoll_create(int32_t size)
{
+ if (posix_api == NULL) {
+ /* link liblstack.so using LD_PRELOAD mode will read liblstack.so,
+ poisx_api need to be initialized here */
+ if (posix_api_init() != 0) {
+ LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n");
+ }
+ return posix_api->epoll_create_fn(size);
+ }
+
if (unlikely(posix_api->is_chld)) {
return posix_api->epoll_create_fn(size);
}
@@ -90,16 +99,22 @@ static inline int32_t do_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct
return posix_api->epoll_ctl_fn(epfd, op, fd, event);
}
+ struct lwip_sock *sock = get_socket_by_fd(epfd);
+ if (sock == NULL || sock->wakeup == NULL) {
+ return posix_api->epoll_ctl_fn(epfd, op, fd, event);
+ }
+
return lstack_epoll_ctl(epfd, op, fd, event);
}
static inline int32_t do_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout)
{
- if (events == NULL || maxevents == 0) {
- GAZELLE_RETURN(EINVAL);
+ if (unlikely(posix_api->is_chld)) {
+ return posix_api->epoll_wait_fn(epfd, events, maxevents, timeout);
}
- if (unlikely(posix_api->is_chld)) {
+ struct lwip_sock *sock = get_socket_by_fd(epfd);
+ if (sock == NULL || sock->wakeup == NULL) {
return posix_api->epoll_wait_fn(epfd, events, maxevents, timeout);
}
--
2.23.0

View File

@ -0,0 +1,836 @@
From a74d5b38b2021397d13b13aaa30f41f69be6f475 Mon Sep 17 00:00:00 2001
From: wuchangsheng <wuchangsheng2@huawei.com>
Date: Thu, 21 Apr 2022 17:21:59 +0800
Subject: [PATCH 09/18] refactor kernel event poll/epoll
---
src/lstack/api/lstack_epoll.c | 343 +++++++++++++++------
src/lstack/api/lstack_wrap.c | 21 +-
src/lstack/core/lstack_dpdk.c | 4 +-
src/lstack/core/lstack_init.c | 2 +-
src/lstack/core/lstack_lwip.c | 1 +
src/lstack/core/lstack_protocol_stack.c | 85 ++++-
src/lstack/include/lstack_cfg.h | 1 -
src/lstack/include/lstack_protocol_stack.h | 8 +-
src/lstack/include/posix/lstack_epoll.h | 24 ++
9 files changed, 350 insertions(+), 139 deletions(-)
diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c
index b8d53f6..cba67ea 100644
--- a/src/lstack/api/lstack_epoll.c
+++ b/src/lstack/api/lstack_epoll.c
@@ -15,6 +15,7 @@
#include <sys/epoll.h>
#include <time.h>
#include <poll.h>
+#include <stdatomic.h>
#include <lwip/lwipsock.h>
#include <lwip/sockets.h>
@@ -32,10 +33,14 @@
#include "gazelle_base_func.h"
#include "lstack_lwip.h"
#include "lstack_protocol_stack.h"
+#include "posix/lstack_epoll.h"
#define EPOLL_KERNEL_INTERVAL 10 /* ms */
-#define EPOLL_NSEC_TO_SEC 1000000000
+#define SEC_TO_NSEC 1000000000
+#define SEC_TO_MSEC 1000
+#define MSEC_TO_NSEC 1000000
#define EPOLL_MAX_EVENTS 512
+#define POLL_KERNEL_EVENTS 32
static PER_THREAD struct wakeup_poll g_wakeup_poll = {0};
static bool g_use_epoll = false; /* FIXME: when no epoll close prepare event for performance testing */
@@ -149,12 +154,12 @@ int32_t lstack_epoll_create(int32_t size)
posix_api->close_fn(fd);
GAZELLE_RETURN(EINVAL);
}
-
memset_s(wakeup, sizeof(struct wakeup_poll), 0, sizeof(struct wakeup_poll));
- sem_init(&wakeup->event_sem, 0, 0);
- sock->wakeup = wakeup;
init_list_node(&wakeup->event_list);
+ wakeup->epollfd = fd;
+ sem_init(&wakeup->event_sem, 0, 0);
+ sock->wakeup = wakeup;
g_use_epoll = true;
return fd;
@@ -162,6 +167,8 @@ int32_t lstack_epoll_create(int32_t size)
int32_t lstack_epoll_close(int32_t fd)
{
+ posix_api->close_fn(fd);
+
struct lwip_sock *sock = get_socket_by_fd(fd);
if (sock == NULL) {
LSTACK_LOG(ERR, LSTACK, "fd=%d sock is NULL errno=%d\n", fd, errno);
@@ -176,6 +183,43 @@ int32_t lstack_epoll_close(int32_t fd)
return 0;
}
+static uint16_t find_max_cnt_stack(int32_t *stack_count, uint16_t stack_num, struct protocol_stack *last_stack)
+{
+ uint16_t max_index = 0;
+ bool all_same_cnt = true;
+
+ for (uint16_t i = 1; i < stack_num; i++) {
+ if (stack_count[i] != stack_count[0]) {
+ all_same_cnt = false;
+ }
+
+ if (stack_count[i] > stack_count[max_index]) {
+ max_index = i;
+ }
+ }
+
+ /* all stack same, don't change */
+ if (all_same_cnt && last_stack) {
+ return last_stack->queue_id;
+ }
+
+ /* first bind and all stack same. choice tick as queue_id, avoid all bind to statck_0.*/
+ static uint16_t tick = 0;
+ if (all_same_cnt && stack_num) {
+ max_index = atomic_fetch_add(&tick, 1) % stack_num;
+ }
+
+ return max_index;
+}
+
+static void update_epoll_max_stack(struct wakeup_poll *wakeup)
+{
+ struct protocol_stack_group *stack_group = get_protocol_stack_group();
+ uint16_t bind_id = find_max_cnt_stack(wakeup->stack_fd_cnt, stack_group->stack_num, wakeup->max_stack);
+
+ wakeup->max_stack = stack_group->stacks[bind_id];
+}
+
int32_t lstack_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event *event)
{
LSTACK_LOG(DEBUG, LSTACK, "op=%d events: fd: %d\n", op, fd);
@@ -185,35 +229,38 @@ int32_t lstack_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_even
GAZELLE_RETURN(EINVAL);
}
+ struct lwip_sock *epoll_sock = get_socket_by_fd(epfd);
+ if (epoll_sock == NULL || epoll_sock->wakeup == NULL) {
+ return posix_api->epoll_ctl_fn(epfd, op, fd, event);
+ }
+
struct lwip_sock *sock = get_socket(fd);
if (sock == NULL) {
+ epoll_sock->wakeup->have_kernel_fd = true;
return posix_api->epoll_ctl_fn(epfd, op, fd, event);
}
if (CONN_TYPE_HAS_HOST(sock->conn)) {
+ epoll_sock->wakeup->have_kernel_fd = true;
int32_t ret = posix_api->epoll_ctl_fn(epfd, op, fd, event);
if (ret < 0) {
return ret;
}
}
- struct lwip_sock *epoll_sock = get_socket_by_fd(epfd);
- if (epoll_sock == NULL || epoll_sock->wakeup == NULL) {
- LSTACK_LOG(ERR, LSTACK, "epfd=%d\n", fd);
- GAZELLE_RETURN(EINVAL);
- }
-
- uint32_t events = event->events | EPOLLERR | EPOLLHUP;
do {
switch (op) {
case EPOLL_CTL_ADD:
sock->wakeup = epoll_sock->wakeup;
+ if (sock->stack) {
+ epoll_sock->wakeup->stack_fd_cnt[sock->stack->queue_id]++;
+ }
if (list_is_empty(&sock->event_list)) {
list_add_node(&sock->wakeup->event_list, &sock->event_list);
}
/* fall through */
case EPOLL_CTL_MOD:
- sock->epoll_events = events;
+ sock->epoll_events = event->events | EPOLLERR | EPOLLHUP;
sock->ep_data = event->data;
if (sock->conn && NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
raise_pending_events(sock);
@@ -222,6 +269,9 @@ int32_t lstack_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_even
case EPOLL_CTL_DEL:
list_del_node_init(&sock->event_list);
sock->epoll_events = 0;
+ if (sock->stack) {
+ epoll_sock->wakeup->stack_fd_cnt[sock->stack->queue_id]--;
+ }
break;
default:
GAZELLE_RETURN(EINVAL);
@@ -230,6 +280,7 @@ int32_t lstack_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_even
sock = get_socket(fd);
} while (fd > 0 && sock != NULL);
+ update_epoll_max_stack(epoll_sock->wakeup);
return 0;
}
@@ -346,129 +397,196 @@ static int32_t poll_lwip_event(struct pollfd *fds, nfds_t nfds)
return event_num;
}
-static inline bool have_kernel_fd(int32_t epfd, struct pollfd *fds, nfds_t nfds)
+static void ms_to_timespec(struct timespec *timespec, int32_t timeout)
{
- /* when epfd > 0 is epoll type */
- for (uint32_t i = 0; i < nfds && epfd < 0; i++) {
- if (get_socket(fds[i].fd) == NULL) {
- return true;
+ clock_gettime(CLOCK_REALTIME, timespec);
+ timespec->tv_sec += timeout / SEC_TO_MSEC;
+ timespec->tv_nsec += (timeout % SEC_TO_MSEC) * MSEC_TO_NSEC;
+ timespec->tv_sec += timespec->tv_nsec / SEC_TO_NSEC;
+ timespec->tv_nsec = timespec->tv_nsec % SEC_TO_NSEC;
+}
+
+static void change_epollfd_kernel_thread(struct wakeup_poll *wakeup, struct protocol_stack *old_stack,
+ struct protocol_stack *new_stack)
+{
+ if (old_stack) {
+ if (posix_api->epoll_ctl_fn(old_stack->epollfd, EPOLL_CTL_DEL, wakeup->epollfd, NULL) != 0) {
+ LSTACK_LOG(ERR, LSTACK, "epoll_ctl_fn errno=%d\n", errno);
}
}
- return false;
+ /* avoid kernel thread post too much, use EPOLLET */
+ struct epoll_event event;
+ event.data.ptr = &wakeup->event_sem;
+ event.events = EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLET;
+ if (posix_api->epoll_ctl_fn(new_stack->epollfd, EPOLL_CTL_ADD, wakeup->epollfd, &event) != 0) {
+ LSTACK_LOG(ERR, LSTACK, "epoll_ctl_fn errno=%d\n", errno);
+ }
}
-static inline int32_t poll_kernel_event(struct pollfd *fds, nfds_t nfds)
+static void epoll_bind_statck(struct wakeup_poll *wakeup)
{
- int32_t event_num = 0;
-
- for (uint32_t i = 0; i < nfds; i++) {
- /* lwip event */
- if (get_socket(fds[i].fd) != NULL || fds[i].fd < 0) {
- continue;
- }
-
- int32_t ret = posix_api->poll_fn(&fds[i], 1, 0);
- if (ret < 0) {
- if (errno != EINTR) {
- return ret;
- }
- } else {
- event_num += ret;
- }
+ /* all fd is kernel, set rand stack */
+ if (wakeup->bind_stack == NULL && wakeup->max_stack== NULL) {
+ update_epoll_max_stack(wakeup);
}
- return event_num;
+ if (wakeup->bind_stack != wakeup->max_stack && wakeup->max_stack) {
+ bind_to_stack_numa(wakeup->max_stack);
+ change_epollfd_kernel_thread(wakeup, wakeup->bind_stack, wakeup->max_stack);
+ wakeup->bind_stack = wakeup->max_stack;
+ }
}
-static int32_t get_event(struct wakeup_poll *wakeup, int32_t epfd, void *out, int32_t maxevents, int32_t timeout)
+int32_t lstack_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout)
{
- struct pollfd *fds = (struct pollfd *)out;
- struct epoll_event *events = (struct epoll_event *)out;
- bool have_kernel = have_kernel_fd(epfd, fds, maxevents);
+ struct lwip_sock *sock = get_socket_by_fd(epfd);
+ if (sock == NULL || sock->wakeup == NULL) {
+ return posix_api->epoll_wait_fn(epfd, events, maxevents, timeout);
+ }
+
int32_t event_num = 0;
- int32_t poll_time = 0;
int32_t ret;
- /* when epfd > 0 is epoll type */
+ struct timespec epoll_time;
+ if (timeout >= 0) {
+ ms_to_timespec(&epoll_time, timeout);
+ }
+
+ epoll_bind_statck(sock->wakeup);
+
do {
- event_num += (epfd > 0) ? epoll_lwip_event(wakeup, &events[event_num], maxevents - event_num) :
- poll_lwip_event(fds, maxevents);
-
- if (have_kernel) {
- int32_t event_kernel_num = (epfd > 0) ?
- posix_api->epoll_wait_fn(epfd, &events[event_num], maxevents - event_num, 0) :
- poll_kernel_event(fds, maxevents);
- if (event_kernel_num < 0) {
- return event_kernel_num;
- }
- event_num += event_kernel_num;
- if (timeout >= 0 && poll_time >= timeout) {
- break;
- }
- poll_time += EPOLL_KERNEL_INTERVAL;
+ event_num += epoll_lwip_event(sock->wakeup, &events[event_num], maxevents - event_num);
+
+ if (sock->wakeup->have_kernel_fd) {
+ event_num += posix_api->epoll_wait_fn(epfd, &events[event_num], maxevents - event_num, 0);
}
if (event_num > 0) {
break;
}
- int32_t interval = (have_kernel) ? EPOLL_KERNEL_INTERVAL : timeout;
- struct timespec epoll_interval;
- clock_gettime(CLOCK_REALTIME, &epoll_interval);
- epoll_interval.tv_sec += interval / 1000;
- epoll_interval.tv_nsec += (interval % 1000) * 1000000;
- epoll_interval.tv_sec += epoll_interval.tv_nsec / 1000000000;
- epoll_interval.tv_nsec = epoll_interval.tv_nsec % 1000000000;
-
- if (timeout < 0 && !have_kernel) {
- ret = sem_wait(&wakeup->event_sem);
+ if (timeout < 0) {
+ ret = sem_wait(&sock->wakeup->event_sem);
} else {
- ret = sem_timedwait(&wakeup->event_sem, &epoll_interval);
+ ret = sem_timedwait(&sock->wakeup->event_sem, &epoll_time);
}
-
- if (!have_kernel && ret < 0) {
- break;
- }
- } while (event_num <= maxevents);
+ } while (ret == 0);
return event_num;
}
-int32_t lstack_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout)
+static void init_poll_wakeup_data(struct wakeup_poll *wakeup)
{
- /* avoid the starvation of epoll events from both netstack */
- maxevents = LWIP_MIN(LWIP_EPOOL_MAX_EVENTS, maxevents);
+ sem_init(&wakeup->event_sem, 0, 0);
- struct lwip_sock *sock = get_socket_by_fd(epfd);
- if (sock == NULL) {
- GAZELLE_RETURN(EINVAL);
+ wakeup->last_fds = calloc(POLL_KERNEL_EVENTS, sizeof(struct pollfd));
+ if (wakeup->last_fds == NULL) {
+ LSTACK_LOG(ERR, LSTACK, "calloc failed errno=%d\n", errno);
}
- if (sock->wakeup == NULL) {
- return posix_api->epoll_wait_fn(epfd, events, maxevents, timeout);
+ wakeup->events = calloc(POLL_KERNEL_EVENTS, sizeof(struct epoll_event));
+ if (wakeup->events == NULL) {
+ LSTACK_LOG(ERR, LSTACK, "calloc failed errno=%d\n", errno);
}
- return get_event(sock->wakeup, epfd, events, maxevents, timeout);
+ wakeup->last_max_nfds = POLL_KERNEL_EVENTS;
+
+ wakeup->epollfd = posix_api->epoll_create_fn(POLL_KERNEL_EVENTS);
+ if (wakeup->epollfd < 0) {
+ LSTACK_LOG(ERR, LSTACK, "epoll_create_fn errno=%d\n", errno);
+ }
}
-static void poll_init(struct pollfd *fds, nfds_t nfds, struct wakeup_poll *wakeup)
+static void resize_kernel_poll(struct wakeup_poll *wakeup, nfds_t nfds)
{
- int32_t stack_count[PROTOCOL_STACK_MAX] = {0};
+ wakeup->last_fds = realloc(wakeup->last_fds, nfds * sizeof(struct pollfd));
+ if (wakeup->last_fds == NULL) {
+ LSTACK_LOG(ERR, LSTACK, "calloc failed errno=%d\n", errno);
+ }
+
+ wakeup->events = realloc(wakeup->events, nfds * sizeof(struct epoll_event));
+ if (wakeup->events == NULL) {
+ LSTACK_LOG(ERR, LSTACK, "calloc failed errno=%d\n", errno);
+ }
+
+ wakeup->last_max_nfds = nfds;
+ memset_s(wakeup->last_fds, nfds * sizeof(struct pollfd), 0, nfds * sizeof(struct pollfd));
+}
+
+static void poll_bind_statck(struct wakeup_poll *wakeup, int32_t *stack_count)
+{
+ struct protocol_stack_group *stack_group = get_protocol_stack_group();
+ uint16_t bind_id = find_max_cnt_stack(stack_count, stack_group->stack_num, wakeup->bind_stack);
+
+ if (wakeup->bind_stack && wakeup->bind_stack->queue_id == bind_id) {
+ return;
+ }
+ change_epollfd_kernel_thread(wakeup, wakeup->bind_stack, stack_group->stacks[bind_id]);
+ bind_to_stack_numa(stack_group->stacks[bind_id]);
+ wakeup->bind_stack = stack_group->stacks[bind_id];
+}
+
+static void update_kernel_poll(struct wakeup_poll *wakeup, uint32_t index, struct pollfd *new_fd)
+{
+ posix_api->epoll_ctl_fn(wakeup->epollfd, EPOLL_CTL_DEL, wakeup->last_fds[index].fd, NULL);
+
+ if (new_fd == NULL) {
+ return;
+ }
+
+ struct epoll_event event;
+ event.data.u32 = index;
+ event.events = new_fd->events;
+ if (posix_api->epoll_ctl_fn(wakeup->epollfd, EPOLL_CTL_ADD, new_fd->fd, &event) != 0) {
+ LSTACK_LOG(ERR, LSTACK, "epoll_ctl_fn errno=%d\n", errno);
+ }
+
+ wakeup->last_fds[index].fd = new_fd->fd;
+ wakeup->last_fds[index].events = new_fd->events;
+
+ wakeup->have_kernel_fd = true;
+}
+
+static void poll_init(struct wakeup_poll *wakeup, struct pollfd *fds, nfds_t nfds)
+{
if (!wakeup->init) {
wakeup->init = true;
- sem_init(&wakeup->event_sem, 0, 0);
+ init_poll_wakeup_data(wakeup);
} else {
while (sem_trywait(&wakeup->event_sem) == 0) {}
}
+ if (nfds > wakeup->last_max_nfds) {
+ resize_kernel_poll(wakeup, nfds);
+ }
+
+ int32_t stack_count[PROTOCOL_STACK_MAX] = {0};
+ int32_t poll_change = 0;
+
+ /* poll fds num less, del old fd */
+ for (uint32_t i = nfds; i < wakeup->last_nfds; i++) {
+ update_kernel_poll(wakeup, i, NULL);
+ poll_change = 1;
+ }
+
for (uint32_t i = 0; i < nfds; i++) {
- int32_t fd = fds[i].fd;
fds[i].revents = 0;
+ if (fds[i].fd == wakeup->last_fds[i].fd && fds[i].events == wakeup->last_fds[i].events) {
+ continue;
+ }
+ poll_change = 1;
+
+ int32_t fd = fds[i].fd;
+ struct lwip_sock *sock = get_socket(fd);
+ if (sock == NULL || CONN_TYPE_HAS_HOST(sock->conn)) {
+ update_kernel_poll(wakeup, i, fds + i);
+ }
+
do {
- struct lwip_sock *sock = get_socket(fd);
+ sock = get_socket(fd);
if (sock == NULL || sock->conn == NULL) {
break;
}
@@ -481,25 +599,50 @@ static void poll_init(struct pollfd *fds, nfds_t nfds, struct wakeup_poll *wakeu
} while (fd > 0);
}
- if (wakeup->bind_stack) {
+ wakeup->last_nfds = nfds;
+ if (poll_change == 0) {
return;
}
- struct protocol_stack_group *stack_group = get_protocol_stack_group();
- uint32_t bind_id = 0;
- for (uint32_t i = 0; i < stack_group->stack_num; i++) {
- if (stack_count[i] > stack_count[bind_id]) {
- bind_id = i;
- }
- }
-
- bind_to_stack_numa(stack_group->stacks[bind_id]);
- wakeup->bind_stack = stack_group->stacks[bind_id];
+ poll_bind_statck(wakeup, stack_count);
}
int32_t lstack_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout)
{
- poll_init(fds, nfds, &g_wakeup_poll);
+ poll_init(&g_wakeup_poll, fds, nfds);
- return get_event(&g_wakeup_poll, -1, fds, nfds, timeout);
+ int32_t event_num = 0;
+ int32_t ret;
+
+ struct timespec poll_time;
+ if (timeout >= 0) {
+ ms_to_timespec(&poll_time, timeout);
+ }
+
+ /* when epfd > 0 is epoll type */
+ do {
+ event_num += poll_lwip_event(fds, nfds);
+
+ /* reduce syscall epoll_wait */
+ if (g_wakeup_poll.have_kernel_fd) {
+ int32_t kernel_num = posix_api->epoll_wait_fn(g_wakeup_poll.epollfd, g_wakeup_poll.events, nfds, 0);
+ for (int32_t i = 0; i < kernel_num; i++) {
+ uint32_t index = g_wakeup_poll.events[i].data.u32;
+ fds[index].revents = g_wakeup_poll.events[i].events;
+ }
+ event_num += kernel_num >= 0 ? kernel_num : 0;
+ }
+
+ if (event_num > 0) {
+ break;
+ }
+
+ if (timeout < 0) {
+ ret = sem_wait(&g_wakeup_poll.event_sem);
+ } else {
+ ret = sem_timedwait(&g_wakeup_poll.event_sem, &poll_time);
+ }
+ } while (ret == 0);
+
+ return event_num;
}
diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c
index f623da3..bf5dcb4 100644
--- a/src/lstack/api/lstack_wrap.c
+++ b/src/lstack/api/lstack_wrap.c
@@ -45,8 +45,7 @@ enum KERNEL_LWIP_PATH {
static inline enum KERNEL_LWIP_PATH select_path(int fd)
{
if (posix_api == NULL) {
- /* link liblstack.so using LD_PRELOAD mode will read liblstack.so,
- poisx_api need to be initialized here */
+ /* posix api maybe call before gazelle init */
if (posix_api_init() != 0) {
LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n");
}
@@ -78,8 +77,7 @@ static inline enum KERNEL_LWIP_PATH select_path(int fd)
static inline int32_t do_epoll_create(int32_t size)
{
if (posix_api == NULL) {
- /* link liblstack.so using LD_PRELOAD mode will read liblstack.so,
- poisx_api need to be initialized here */
+ /* posix api maybe call before gazelle init */
if (posix_api_init() != 0) {
LSTACK_PRE_LOG(LSTACK_ERR, "posix_api_init failed\n");
}
@@ -99,11 +97,6 @@ static inline int32_t do_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct
return posix_api->epoll_ctl_fn(epfd, op, fd, event);
}
- struct lwip_sock *sock = get_socket_by_fd(epfd);
- if (sock == NULL || sock->wakeup == NULL) {
- return posix_api->epoll_ctl_fn(epfd, op, fd, event);
- }
-
return lstack_epoll_ctl(epfd, op, fd, event);
}
@@ -113,11 +106,6 @@ static inline int32_t do_epoll_wait(int32_t epfd, struct epoll_event* events, in
return posix_api->epoll_wait_fn(epfd, events, maxevents, timeout);
}
- struct lwip_sock *sock = get_socket_by_fd(epfd);
- if (sock == NULL || sock->wakeup == NULL) {
- return posix_api->epoll_wait_fn(epfd, events, maxevents, timeout);
- }
-
if (epfd < 0) {
GAZELLE_RETURN(EBADF);
}
@@ -362,6 +350,11 @@ static inline ssize_t do_sendmsg(int32_t s, const struct msghdr *message, int32_
static inline int32_t do_close(int32_t s)
{
+ struct lwip_sock *sock = get_socket_by_fd(s);
+ if (sock && sock->wakeup && sock->wakeup->epollfd == s) {
+ return lstack_epoll_close(s);
+ }
+
if (select_path(s) == PATH_KERNEL) {
return posix_api->close_fn(s);
}
diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c
index aa91201..cdd2c05 100644
--- a/src/lstack/core/lstack_dpdk.c
+++ b/src/lstack/core/lstack_dpdk.c
@@ -95,8 +95,8 @@ int32_t dpdk_eal_init(void)
if (ret < 0) {
if (rte_errno == EALREADY) {
LSTACK_PRE_LOG(LSTACK_INFO, "rte_eal_init aleady init\n");
- /* maybe other program inited, merge init param share init */
- ret = 0;
+ /* maybe other program inited, merge init param share init */
+ ret = 0;
}
else {
LSTACK_PRE_LOG(LSTACK_ERR, "rte_eal_init failed init, rte_errno %d\n", rte_errno);
diff --git a/src/lstack/core/lstack_init.c b/src/lstack/core/lstack_init.c
index 037b8fd..f8e96bf 100644
--- a/src/lstack/core/lstack_init.c
+++ b/src/lstack/core/lstack_init.c
@@ -270,7 +270,7 @@ __attribute__((constructor)) void gazelle_network_init(void)
lwip_sock_init();
/* wait stack thread and kernel_event thread init finish */
- wait_sem_value(&get_protocol_stack_group()->all_init, get_protocol_stack_group()->stack_num);
+ wait_sem_value(&get_protocol_stack_group()->all_init, get_protocol_stack_group()->stack_num * 2);
if (g_init_fail) {
LSTACK_EXIT(1, "stack thread or kernel_event thread failed\n");
}
diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c
index 00a82fb..8544ef7 100644
--- a/src/lstack/core/lstack_lwip.c
+++ b/src/lstack/core/lstack_lwip.c
@@ -29,6 +29,7 @@
#include "lstack_log.h"
#include "lstack_dpdk.h"
#include "lstack_stack_stat.h"
+#include "posix/lstack_epoll.h"
#include "lstack_lwip.h"
#define HALF_DIVISOR (2)
diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c
index 565d19b..eb975c0 100644
--- a/src/lstack/core/lstack_protocol_stack.c
+++ b/src/lstack/core/lstack_protocol_stack.c
@@ -35,6 +35,7 @@
#define READ_LIST_MAX 32
#define SEND_LIST_MAX 32
#define HANDLE_RPC_MSG_MAX 32
+#define KERNEL_EPOLL_MAX 256
static PER_THREAD uint16_t g_stack_idx = PROTOCOL_STACK_MAX;
static struct protocol_stack_group g_stack_group = {0};
@@ -43,9 +44,6 @@ static PER_THREAD long g_stack_tid = 0;
void set_init_fail(void);
typedef void *(*stack_thread_func)(void *arg);
-#ifdef GAZELLE_USE_EPOLL_EVENT_STACK
-void update_stack_events(struct protocol_stack *stack);
-#endif
int32_t bind_to_stack_numa(struct protocol_stack *stack)
{
@@ -206,6 +204,10 @@ static void* gazelle_weakup_thread(void *arg)
LSTACK_LOG(INFO, LSTACK, "weakup_%02d start\n", stack->queue_id);
for (;;) {
+ if (rte_ring_count(stack->wakeup_ring) == 0) {
+ continue;
+ }
+
sem_t *event_sem;
if (rte_ring_sc_dequeue(stack->wakeup_ring, (void **)&event_sem)) {
continue;
@@ -268,6 +270,61 @@ static int32_t init_stack_value(struct protocol_stack *stack, uint16_t queue_id)
return 0;
}
+static void* gazelle_kernel_event(void *arg)
+{
+ uint16_t queue_id = *(uint16_t *)arg;
+
+ int32_t epoll_fd = posix_api->epoll_create_fn(GAZELLE_LSTACK_MAX_CONN);
+ if (epoll_fd < 0) {
+ LSTACK_LOG(ERR, LSTACK, "queue_id=%d epoll_fd=%d errno=%d\n", queue_id, epoll_fd, errno);
+ /* exit in main thread, avoid create mempool and exit at the same time */
+ set_init_fail();
+ sem_post(&get_protocol_stack_group()->all_init);
+ return NULL;
+ }
+
+ struct protocol_stack *stack = get_protocol_stack_group()->stacks[queue_id];
+ stack->epollfd = epoll_fd;
+
+ sem_post(&get_protocol_stack_group()->all_init);
+ LSTACK_LOG(INFO, LSTACK, "kernel_event_%02d start\n", stack->queue_id);
+
+ struct epoll_event events[KERNEL_EPOLL_MAX];
+ for (;;) {
+ int32_t event_num = posix_api->epoll_wait_fn(epoll_fd, events, KERNEL_EPOLL_MAX, -1);
+ if (event_num <= 0) {
+ continue;
+ }
+
+ for (int32_t i = 0; i < event_num; i++) {
+ if (events[i].data.ptr) {
+ sem_post((sem_t *)events[i].data.ptr);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static int32_t create_companion_thread(struct protocol_stack_group *stack_group, struct protocol_stack *stack)
+{
+ int32_t ret;
+
+ if (stack_group->wakeup_enable) {
+ ret = create_thread(stack->queue_id, "gazelleweakup", gazelle_weakup_thread);
+ if (ret != 0) {
+ LSTACK_LOG(ERR, LSTACK, "gazelleweakup ret=%d errno=%d\n", ret, errno);
+ return ret;
+ }
+ }
+
+ ret = create_thread(stack->queue_id, "gazellekernel", gazelle_kernel_event);
+ if (ret != 0) {
+ LSTACK_LOG(ERR, LSTACK, "gazellekernelEvent ret=%d errno=%d\n", ret, errno);
+ }
+ return ret;
+}
+
void wait_sem_value(sem_t *sem, int32_t wait_value)
{
int32_t sem_val;
@@ -315,12 +372,9 @@ static struct protocol_stack * stack_thread_init(uint16_t queue_id)
return NULL;
}
- if (stack_group->wakeup_enable) {
- int32_t ret = create_thread(stack->queue_id, "gazelleweakup", gazelle_weakup_thread);
- if (ret != 0) {
- free(stack);
- return NULL;
- }
+ if (create_companion_thread(stack_group, stack) != 0) {
+ free(stack);
+ return NULL;
}
return stack;
@@ -338,6 +392,7 @@ static void* gazelle_stack_thread(void *arg)
LSTACK_LOG(ERR, LSTACK, "stack_thread_init failed queue_id=%d\n", queue_id);
return NULL;
}
+
sem_post(&get_protocol_stack_group()->all_init);
LSTACK_LOG(INFO, LSTACK, "stack_%02d init success\n", queue_id);
@@ -351,10 +406,6 @@ static void* gazelle_stack_thread(void *arg)
send_stack_list(stack, SEND_LIST_MAX);
sys_timer_run();
-
-#ifdef GAZELLE_USE_EPOLL_EVENT_STACK
- update_stack_events(stack);
-#endif
}
return NULL;
@@ -378,7 +429,13 @@ static int32_t init_protocol_sem(void)
LSTACK_LOG(ERR, PORT, "sem_init failed ret=%d errno=%d\n", ret, errno);
return -1;
}
-
+
+ ret = sem_init(&stack_group->all_init, 0, 0);
+ if (ret < 0) {
+ LSTACK_LOG(ERR, PORT, "sem_init failed ret=%d errno=%d\n", ret, errno);
+ return -1;
+ }
+
return 0;
}
diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h
index 345a373..987828d 100644
--- a/src/lstack/include/lstack_cfg.h
+++ b/src/lstack/include/lstack_cfg.h
@@ -33,7 +33,6 @@
#define LOG_DIR_PATH PATH_MAX
#define LOG_LEVEL_LEN 16
#define GAZELLE_MAX_NUMA_NODES 8
-#define LWIP_EPOOL_MAX_EVENTS 512
/* Default value of low power mode parameters */
#define LSTACK_LPM_DETECT_MS_MIN (5 * 1000)
diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h
index 9852878..bc4e4bd 100644
--- a/src/lstack/include/lstack_protocol_stack.h
+++ b/src/lstack/include/lstack_protocol_stack.h
@@ -51,6 +51,7 @@ struct protocol_stack {
struct list_node send_list;
struct list_node event_list;
pthread_spinlock_t event_lock;
+ int32_t epollfd; /* kernel event thread epoll fd */
struct gazelle_stat_pkts stats;
struct gazelle_stack_latency latency;
@@ -75,13 +76,6 @@ struct protocol_stack_group {
uint64_t call_alloc_fail;
};
-struct wakeup_poll {
- bool init;
- struct protocol_stack *bind_stack;
- struct list_node event_list; /* epoll temp use poll */
- sem_t event_sem;
-};
-
long get_stack_tid(void);
struct protocol_stack *get_protocol_stack(void);
struct protocol_stack *get_protocol_stack_by_fd(int32_t fd);
diff --git a/src/lstack/include/posix/lstack_epoll.h b/src/lstack/include/posix/lstack_epoll.h
index cac640b..a83f41f 100644
--- a/src/lstack/include/posix/lstack_epoll.h
+++ b/src/lstack/include/posix/lstack_epoll.h
@@ -18,6 +18,30 @@ extern "C" {
#endif
#include <poll.h>
+#include <stdbool.h>
+#include <semaphore.h>
+
+#include "lstack_protocol_stack.h"
+
+struct wakeup_poll {
+ bool init;
+ struct protocol_stack *bind_stack;
+ sem_t event_sem;
+
+ int32_t epollfd;
+ bool have_kernel_fd;
+
+ /* poll */
+ struct pollfd *last_fds;
+ nfds_t last_nfds;
+ nfds_t last_max_nfds;
+ struct epoll_event *events;
+
+ /* epoll */
+ int32_t stack_fd_cnt[PROTOCOL_STACK_MAX];
+ struct protocol_stack *max_stack;
+ struct list_node event_list; /* epoll temp use */
+};
int32_t lstack_epoll_create(int32_t size);
int32_t lstack_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event *event);
--
2.23.0

View File

@ -0,0 +1,39 @@
From e0d26480fc3919affe10b55ccbb5837aa88c5c57 Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng14@huawei.com>
Date: Mon, 16 May 2022 18:34:55 +0800
Subject: [PATCH 10/18] post thread_phase1 sem to avoid block main thread when
stack error
---
src/lstack/core/lstack_protocol_stack.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c
index eb975c0..88513ba 100644
--- a/src/lstack/core/lstack_protocol_stack.c
+++ b/src/lstack/core/lstack_protocol_stack.c
@@ -339,11 +339,13 @@ static struct protocol_stack * stack_thread_init(uint16_t queue_id)
struct protocol_stack *stack = malloc(sizeof(*stack));
if (stack == NULL) {
+ sem_post(&stack_group->thread_phase1);
LSTACK_LOG(ERR, LSTACK, "malloc stack failed\n");
return NULL;
}
if (init_stack_value(stack, queue_id) != 0) {
+ sem_post(&stack_group->thread_phase1);
free(stack);
return NULL;
}
@@ -356,6 +358,7 @@ static struct protocol_stack * stack_thread_init(uint16_t queue_id)
if (use_ltran()) {
if (client_reg_thrd_ring() != 0) {
+ sem_post(&stack_group->thread_phase1);
free(stack);
return NULL;
}
--
2.23.0

View File

@ -0,0 +1,46 @@
From 98f76a2d2d512338d40cd435b4a75f6989aa13bf Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng14@huawei.com>
Date: Mon, 16 May 2022 18:49:18 +0800
Subject: [PATCH 11/18] adjust the number of RX/TX mbufs of each stack thread
---
src/lstack/core/lstack_dpdk.c | 4 ++--
src/lstack/include/lstack_dpdk.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c
index cdd2c05..df0332b 100644
--- a/src/lstack/core/lstack_dpdk.c
+++ b/src/lstack/core/lstack_dpdk.c
@@ -175,13 +175,13 @@ int32_t pktmbuf_pool_init(struct protocol_stack *stack, uint16_t stack_num)
return -1;
}
- stack->rx_pktmbuf_pool = create_pktmbuf_mempool("rx_mbuf", RX_NB_MBUF / stack_num, RX_MBUF_CACHE_SZ,
+ stack->rx_pktmbuf_pool = create_pktmbuf_mempool("rx_mbuf", RX_NB_MBUF, RX_MBUF_CACHE_SZ,
stack->queue_id);
if (stack->rx_pktmbuf_pool == NULL) {
return -1;
}
- stack->tx_pktmbuf_pool = create_pktmbuf_mempool("tx_mbuf", TX_NB_MBUF / stack_num, TX_MBUF_CACHE_SZ,
+ stack->tx_pktmbuf_pool = create_pktmbuf_mempool("tx_mbuf", TX_NB_MBUF, TX_MBUF_CACHE_SZ,
stack->queue_id);
if (stack->tx_pktmbuf_pool == NULL) {
return -1;
diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h
index 4295f01..bb9be21 100644
--- a/src/lstack/include/lstack_dpdk.h
+++ b/src/lstack/include/lstack_dpdk.h
@@ -23,7 +23,7 @@
#include "dpdk_common.h"
struct protocol_stack;
-#define RX_NB_MBUF ((5 * MAX_CLIENTS) + (VDEV_RX_QUEUE_SZ * DEFAULT_BACKUP_RING_SIZE_FACTOR))
+#define RX_NB_MBUF ((5 * (MAX_CLIENTS / 4)) + (VDEV_RX_QUEUE_SZ * DEFAULT_BACKUP_RING_SIZE_FACTOR))
#define RX_MBUF_CACHE_SZ (VDEV_RX_QUEUE_SZ)
#define TX_NB_MBUF (128 * DEFAULT_RING_SIZE)
#define TX_MBUF_CACHE_SZ (DEFAULT_RING_SIZE)
--
2.23.0

365
0051-modify-README.patch Normal file
View File

@ -0,0 +1,365 @@
From 981a5ddaa7708b7e2c34fc52dae592b703fd64f2 Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng14@huawei.com>
Date: Fri, 20 May 2022 17:14:07 +0800
Subject: [PATCH 2/6] modify readme
---
README.md | 262 ++++++++++++++++++++++++----------------------------
2 files changed, 121 insertions(+), 404 deletions(-)
delete mode 100644 Gazelle.md
diff --git a/README.md b/README.md
index 5a99633..61f298c 100644
--- a/README.md
+++ b/README.md
@@ -1,90 +1,75 @@
-<img src="doc/logo.png" alt="gazelle" style="zoom:20%;" />
+# 用户态协议栈Gazelle用户指南
-# gazelle
+## 简介
-## Introduction
-gazelle是高性能的用户态协议栈通过dpdk在用户态直接读写网卡报文共享大页内存传递报文并使用轻量级lwip协议栈。能够大幅提高应用的网络IO吞吐能力.
+Gazelle是一款高性能用户态协议栈。它基于DPDK在用户态直接读写网卡报文共享大页内存传递报文使用轻量级LwIP协议栈。能够大幅提高应用的网络I/O吞吐能力。专注于数据库网络性能加速如MySQL、redis等。
+- 高性能
+报文零拷贝无锁灵活scale-out自适应调度。
+- 通用性
+完全兼容POSIX零修改适用不同类型的应用。
-## Compile
-- 编译依赖软件包
-cmake gcc-c++ lwip dpdk-devel(>=21.11-2)
-numactl-devel libpcap-devel libconfig-devel libboundscheck rpm-build
-- 编译
-``` sh
-#创建目录
-mkdir -p ~/rpmbuild/SPECS
-mkdir -p ~/rpmbuild/SOURCES
-
-#创建压缩包
-mkdir gazelle-1.0.0
-mv build gazelle-1.0.0
-mv src gazelle-1.0.0
-tar zcvf gazelle-1.0.0.tar.gz gazelle-1.0.0/
-
-#编包
-mv gazelle-1.0.0.tar.gz ~/rpmbuild/SPECS
-cp gazelle.spec ~/rpmbuild/SPECS
-cd ~/rpmbuild/SPECS
-rpmbuild -bb gazelle.spec
-
-#编出的包
-ls ~/rpmbuild/RPMS
-```
+单进程且网卡支持多队列时只需使用liblstack.so有更短的报文路径。其余场景使用ltran进程分发报文到各个线程。
-## Install
-``` sh
+## 安装
+配置openEuler的yum源直接使用yum命令安装
+```sh
#dpdk >= 21.11-2
yum install dpdk
yum install libconfig
-yum install numacttl
+yum install numactl
yum install libboundscheck
yum install libpcap
yum install gazelle
-
```
-## Use
-### 1. 安装ko模块
+## 使用方法
+配置运行环境使用Gazelle加速应用程序步骤如下
+### 1. 使用root权限安装ko
+根据实际情况选择使用ko提供虚拟网口、绑定网卡到用户态功能。
+若使用虚拟网口功能则使用rte_kni.ko
``` sh
-modprobe uio
-insmod /usr/lib/modules/5.10.0-54.0.0.27.oe1.x86_64/extra/dpdk/igb_uio.ko
-insmod /usr/lib/modules/5.10.0-54.0.0.27.oe1.x86_64/extra/dpdk/rte_kni.ko carrier="on"
+modprobe rte_kni carrier="on"
+```
+网卡从内核驱动绑为用户态驱动的ko根据实际情况选择一种
+``` sh
+#若IOMMU能使用
+modprobe vfio-pci
+
+#若IOMMU不能使用且VFIO支持noiommu
+modprobe vfio enable_unsafe_noiommu_mode=1
+modprobe vfio-pci
+
+#其它情况
+modprobe igb_uio
```
+
### 2. dpdk绑定网卡
-- 对于虚拟网卡或一般物理网卡绑定到驱动igb_uio
+将网卡绑定到步骤1选择的驱动。为用户态网卡驱动提供网卡资源访问接口。
``` sh
+#使用vfio-pci
+dpdk-devbind -b vfio-pci enp3s0
+
+#使用igb_uio
dpdk-devbind -b igb_uio enp3s0
```
-- 1822网卡绑定到驱动vfio-pci由kernel提供
+
+### 3. 大页内存配置
+Gazelle使用大页内存提高效率。使用root权限配置系统预留大页内存可选用任意页大小。因每页内存都需要一个fd使用内存较大时建议使用1G的大页避免占用过多fd。
+根据实际情况,选择一种页大小,配置足够的大页内存即可。配置大页操作如下:
``` sh
-modprobe vfio-pci
-dpdk-devbind -b vfio-pci enp3s0
-```
+#配置2M大页内存在node0上配置 2M * 1024 = 2G
+echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
-### 3. 大页内存配置
-dpdk提供了高效的大页内存管理和共享机制gazelle的报文数据、无锁队列等都使用了大页内存。大页内存需要root用户配置。2M或1G大页按实际需要配置推荐使用2M大页内存该内存是本机上ltran和所有lstack可以使用的总内存具体方法如下
-- 2M大页配置
- - 配置系统大页数量
- ``` sh
- #示例在node0上配置2M * 2000 = 4000M
- echo 2000 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
- echo 0 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
- echo 0 > /sys/devices/system/node/node2/hugepages/hugepages-2048kB/nr_hugepages
- echo 0 > /sys/devices/system/node/node3/hugepages/hugepages-2048kB/nr_hugepages
- # 查看配置结果
- grep Huge /proc/meminfo
- ```
-- 1G大页配置
-1G大页配置方法与2M类似
- - 配置系统大页数量
- ``` sh
- #示例在node0上配置1G * 5 = 5G
- echo 5 > /sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages
- ```
+#配置1G大页内存在node0上配置1G * 5 = 5G
+echo 5 > /sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages
+
+#查看配置结果
+grep Huge /proc/meminfo
+```
### 4. 挂载大页内存
-创建两个目录分别给lstack的进程、ltran进程使用。操作步骤如下
+创建两个目录分别给lstack的进程、ltran进程访问大页内存使用。操作步骤如下
``` sh
mkdir -p /mnt/hugepages
mkdir -p /mnt/hugepages-2M
@@ -94,34 +79,35 @@ mount -t hugetlbfs nodev /mnt/hugepages
mount -t hugetlbfs nodev /mnt/hugepages-2M
```
-### 5. 应用程序从内核协议栈切换至用户态协议栈
-+ 一种方式:重新编译程序
-修改应用的makefile文件使其链接liblstack.so。示例如下
-``` makefile
-#在makefile中添加
-ifdef USE_GAZELLE
- -include /etc/gazelle/lstack.Makefile
-endif
-gcc test.c -o test $(LSTACK_LIBS)
+### 5. 应用程序使用Gazelle
+有两种使能Gazelle方法根据需要选择其一
+- 重新编译应用程序链接Gazelle的库
+修改应用makefile文件链接liblstack.so示例如下
```
+#makefile中添加Gazelle的Makefile
+-include /etc/gazelle/lstack.Makefile
-+ 另一个方式使用LD_PRELOAD
+#编译添加LSTACK_LIBS变量
+gcc test.c -o test ${LSTACK_LIBS}
```
-GAZELLE_BIND_PROCNAME=test(具体进程名) LD_PRELOAD=/usr/lib64/liblstack.so ./test
+
+- 使用LD_PRELOAD加载Gazelle的库
+GAZELLE_BIND_PROCNAME环境变量指定进程名LD_PRELOAD指定Gazelle库路径
+```
+GAZELLE_BIND_PROCNAME=test LD_PRELOAD=/usr/lib64/liblstack.so ./test
```
### 6. 配置文件
-- lstack.conf用于指定lstack的启动参数Gazelle发布件会包括ltran.conf供用户参考路径为/etc/gazelle/lstack.conf, 配置文件参数如下
+- lstack.conf用于指定lstack的启动参数默认路径为/etc/gazelle/lstack.conf, 配置文件参数如下
|选项|参数格式|说明|
|:---|:---|:---|
|dpdk_args|--socket-mem必需<br>--huge-dir必需<br>--proc-type必需<br>--legacy-mem<br>--map-perfect<br>等|dpdk初始化参数参考dpdk说明|
|use_ltran| 0/1 | 是否使用ltran |
-|num_cpus|"0,2,4 ..."|lstack线程绑定的cpu编号编号的数量为lstack线程个数(小于等于网卡多队列数量),仅在use_ltran=0时生效,如果机器不支持网卡多队列lstack线程数量应该为1|
-|num_weakup|"1,3,5 ..."|weakup线程绑定的cpu编号编号的数量为weakup线程个数与lstack线程的数量保持一致|
-|numa_bind|0/1|是否支持将用户线程绑定到与某lstack线程相同numa内|
+|num_cpus|"0,2,4 ..."|lstack线程绑定的cpu编号编号的数量为lstack线程个数(小于等于网卡多队列数量)。可按NUMA选择cpu|
+|num_wakeup|"1,3,5 ..."|wakeup线程绑定的cpu编号编号的数量为wakeup线程个数与lstack线程的数量保持一致。与numcpus选择对应NUMA的cpu。不配置则为不使用唤醒线程|
|low_power_mode|0/1|是否开启低功耗模式,暂不支持|
-|kni_swith|0/1|rte_kni开关默认为0|
+|kni_swith|0/1|rte_kni开关默认为0。只有不使用ltran时才能开启|
|host_addr|"192.168.xx.xx"|协议栈的IP地址必须和redis-server配置<br>文件里的“bind”字段保存一致。|
|mask_addr|"255.255.xx.xx"|掩码地址|
|gateway_addr|"192.168.xx.1"|网关地址|
@@ -137,10 +123,8 @@ kni_switch=0
low_power_mode=0
-num_cpus="2"
-num_weakup="3"
-
-numa_bind=1
+num_cpus="2,22"
+num_wakeup="3,23"
host_addr="192.168.1.10"
mask_addr="255.255.255.0"
@@ -148,7 +132,7 @@ gateway_addr="192.168.1.1"
devices="aa:bb:cc:dd:ee:ff"
```
-- ltran.conf用于指定ltran启动的参数Gazelle发布件会包括ltran.conf供用户参考路径为/etc/gazelle/ltran.conf仅在lstack.conf内配置use_ltran=1时生效,配置文件格式如下
+- ltran.conf用于指定ltran启动的参数默认路径为/etc/gazelle/ltran.conf。使用ltran时lstack.conf内配置use_ltran=1,配置参数如下:
|功能分类|选项|参数格式|说明|
|:---|:---|:---|:---|
@@ -182,24 +166,26 @@ bond_macs="aa:bb:cc:dd:ee:ff"
bond_ports="0x1"
tcp_conn_scan_interval=10
-```
-### 7. 启动
-- 不使用ltran模式(use_ltran=0)时不需要启动ltran
-- 启动ltran如果不指定--config-file则使用默认路径/etc/gazelle/ltran.conf
+```
+### 7. 启动应用程序
+- 启动ltran进程
+单进程且网卡支持多队列则直接使用网卡多队列分发报文到各线程不启动ltran进程lstack.conf的use_ltran配置为0.
+启动ltran时不使用-config-file指定配置文件则使用默认路径/etc/gazelle/ltran.conf
``` sh
ltran --config-file ./ltran.conf
```
-- 启动redis如果不指定环境变量LSTACK_CONF_PATH则使用默认路径/etc/gazelle/lstack.conf
+- 启动应用程序
+启动应用程序前不使用环境变量LSTACK_CONF_PATH指定配置文件则使用默认路径/etc/gazelle/lstack.conf
``` sh
export LSTACK_CONF_PATH=./lstack.conf
-redis-server redis.conf
+LD_PRELOAD=/usr/lib64/liblstack.so GAZELLE_BIND_PROCNAME=redis-server redis-server redis.conf
```
### 8. API
-liblstack.so编译进应用程序后wrap网络编程标准接口应用程序无需修改代码。
+Gazelle wrap应用程序POSIX接口应用程序无需修改代码。
-### 9. gazellectl
-- 不使用ltran模式时不支持gazellectl ltran xxx命令以及-r, rate命令
+### 9. 调测命令
+- 不使用ltran模式时不支持gazellectl ltran xxx命令以及lstack -r命令
```
Usage: gazellectl [-h | help]
or: gazellectl ltran {quit | show} [LTRAN_OPTIONS] [time]
@@ -228,56 +214,50 @@ Usage: gazellectl [-h | help]
#### 1. dpdk配置文件的位置
如果是root用户dpdk启动后的配置文件将会放到/var/run/dpdk目录下;
如果是非root用户dpdk配置文件的路径将由环境变量XDG_RUNTIME_DIR决定
-+ 如果XDG_RUNTIME_DIR为空dpdk配置文件放到/tmp/dpdk目录下
-+ 如果XDG_RUNTIME_DIR不为空dpdk配置文件放到变量XDG_RUNTIME_DIR下
-+ 注意有些机器会默认设置XDG_RUNTIME_DIR
+- 如果XDG_RUNTIME_DIR为空dpdk配置文件放到/tmp/dpdk目录下
+- 如果XDG_RUNTIME_DIR不为空dpdk配置文件放到变量XDG_RUNTIME_DIR下
+- 注意有些机器会默认设置XDG_RUNTIME_DIR
+
+## 约束限制
-## Constraints
-- 提供的命令行、配置文件以及配置大页内存需要root权限执行或修改。非root用户使用需先提权以及修改文件权限。
-- 若要把用户态网卡绑回内核驱动必须先将Gazelle退出。
+使用 Gazelle 存在一些约束限制:
+#### 功能约束
- 不支持accept阻塞模式或者connect阻塞模式。
-- 最多只支持1500个连接。
-- 协议栈当前只支持tcp、icmp、arp、ipv4。
-- 大页内存不支持在挂载点里创建子目录重新挂载。
-- 在对端ping时要求指定报文长度小于等于14000。
+- 最多支持1500个TCP连接。
+- 当前仅支持TCP、ICMP、ARP、IPv4 协议。
+- 在对端ping Gazelle时要求指定报文长度小于等于14000B。
- 不支持使用透明大页。
-- 需要保证ltran的可用大页内存 >=1G
-- 需要保证应用实例协议栈线程的可用大页内存 >=800M
-- 不支持32位系统使用。
- ltran不支持使用多种类型的网卡混合组bond。
- ltran的bond1主备模式只支持链路层故障主备切换例如网线断开不支持物理层故障主备切换例如网卡下电、拔网卡
-- 构建X86版本使用-march=native选项基于构建环境的CPUIntel® Xeon® Gold 5118 CPU @ 2.30GHz指令集进行优化。要求运行环境CPU支持SSE4.2、AVX、AVX2、AVX-512指令集。
-- 最大IP分片数为10ping最大包长14790TCP协议不使用IP分片。
-- sysctl配置网卡rp_filter参数为1否则可能使用内核协议栈
-- 虚拟机网卡不支持多队列。
-- 不使用ltran模式kni网口只支持本地通讯使用且需要启动前配置NetworkManager不管理kni网卡
-- 虚拟kni网口的ip及mac地址需要与lstack配置文件保持一致
-- gazelle运行过程中不允许删除运行文件如果删除需要重启gazelle
-- lstack配置的ip需要与应用程序的ip保持一致
-
-## Security risk note
-gazelle有如下安全风险用户需要评估使用场景风险
-1. 共享内存
+- 虚拟机网卡不支持多队列。
+#### 操作约束
+- 提供的命令行、配置文件默认root权限。非root用户使用需先提权以及修改文件所有者。
+- 将用户态网卡绑回到内核驱动必须先退出Gazelle。
+- 大页内存不支持在挂载点里创建子目录重新挂载。
+- ltran需要最低大页内存为1GB。
+- 每个应用实例协议栈线程最低大页内存为800MB 。
+- 仅支持64位系统。
+- 构建x86版本的Gazelle使用了-march=native选项基于构建环境的CPUIntel® Xeon® Gold 5118 CPU @ 2.30GHz指令集进行优化。要求运行环境CPU支持 SSE4.2、AVX、AVX2、AVX-512 指令集。
+- 最大IP分片数为10ping 最大包长14790BTCP协议不使用IP分片。
+- sysctl配置网卡rp_filter参数为1否则可能不按预期使用Gazelle协议栈而是依然使用内核协议栈。
+- 不使用ltran模式KNI网口不可配置只支持本地通讯使用且需要启动前配置NetworkManager不管理KNI网卡。
+- 虚拟KNI网口的IP及mac地址需要与lstack.conf配置文件保持一致 。
+
+## 风险提示
+Gazelle可能存在如下安全风险用户需要根据使用场景评估风险。
+
+**共享内存**
- 现状
-大页内存mount至/mnt/hugepages-2M目录链接liblstack.so的进程初始化时在/mnt/hugepages-2M目录下创建文件每个文件对应2M大页内存并mmap这些文件。ltran在收到lstask的注册信息后根据大页内存配置信息也mmap目录下文件实现大页内存共享。
-ltran在/mnt/hugepages目录的大页内存同理。
-- 当前消减措施
-大页文件权限600只有OWNER用户才能访问文件默认root用户支持配置成其它用户
-大页文件有dpdk文件锁不能直接写或者mmap。
-- 风险点
-属于同一用户的恶意进程模仿DPDK实现逻辑通过大页文件共享大页内存写破坏大页内存导致gazelle程序crash。建议用户下的进程属于同一信任域。
-2. 流量限制
-- 风险点
-gazelle没有做流量限制用户有能力发送最大网卡线速流量的报文到网络。
-3. 进程仿冒
-- 风险点
-合法注册到ltran的两个lstack进程进程A可仿冒进程B发送仿冒消息给ltran修改ltran的转发控制信息造成进程B通讯异常进程B报文转发给进程A等问题。建议lstack进程都为可信任进程。
-
-## How to Contribute
-We are happy to provide guidance for the new contributors.
-Please sign the CLA before contributing.
-
-## Licensing
-gazelle is licensed under the Mulan PSL v2.
-
-
+ 大页内存 mount 至 /mnt/hugepages-2M 目录,链接 liblstack.so 的进程初始化时在 /mnt/hugepages-2M 目录下创建文件,每个文件对应 2M 大页内存,并 mmap 这些文件。ltran 在收到 lstask 的注册信息后,根据大页内存配置信息也 mmap 目录下文件,实现大页内存共享。
+ ltran 在 /mnt/hugepages 目录的大页内存同理。
+- 当前消减措施
+ 大页文件权限 600只有 OWNER 用户才能访问文件,默认 root 用户,支持配置成其它用户;
+ 大页文件有 DPDK 文件锁,不能直接写或者映射。
+- 风险点
+ 属于同一用户的恶意进程模仿DPDK实现逻辑通过大页文件共享大页内存写破坏大页内存导致Gazelle程序crash。建议用户下的进程属于同一信任域。
+
+**流量限制**
+Gazelle没有做流量限制用户有能力发送最大网卡线速流量的报文到网络可能导致网络流量拥塞。
+
+**进程仿冒**
+合法注册到ltran的两个lstack进程进程A可仿冒进程B发送仿冒消息给ltran修改ltran的转发控制信息造成进程B通讯异常进程B报文转发给进程A信息泄露等问题。建议lstack进程都为可信任进程。
--
2.23.0

View File

@ -0,0 +1,40 @@
From 94a5043e03d3d83b661af64c3723d5f775c10706 Mon Sep 17 00:00:00 2001
From: zhangqiang <zhangqiang@kylinos.cn>
Date: Fri, 1 Jul 2022 01:26:09 +0800
Subject: [PATCH 3/6] =?UTF-8?q?<bugfix><https://gitee.com/src-openeuler/ga?=
=?UTF-8?q?zelle/issues/I5643C>=20=E6=8C=89=E7=85=A7POSIX=E6=A0=87?=
=?UTF-8?q?=E5=87=86,sigaction=E5=87=BD=E6=95=B0act=3D=3DNULL,=E8=B0=83?=
=?UTF-8?q?=E7=94=A8=E8=80=85=E5=8F=AF=E4=BB=A5=E9=80=9A=E8=BF=87oldact?=
=?UTF-8?q?=E8=8E=B7=E5=8F=96=E4=B9=8B=E5=89=8D=E7=9A=84=E4=BF=A1=E5=8F=B7?=
=?UTF-8?q?action=20=E6=8C=89=E7=85=A7lstack=E7=9A=84=E7=90=86=E8=A7=A3,?=
=?UTF-8?q?=E5=AE=83HOOK=20sigaction=E5=87=BD=E6=95=B0,=E6=98=AF=E5=BD=93?=
=?UTF-8?q?=E8=B0=83=E7=94=A8=E8=80=85=E8=AE=BE=E7=BD=AE=E6=96=B0=E7=9A=84?=
=?UTF-8?q?=E4=BF=A1=E5=8F=B7=E5=87=BD=E6=95=B0=E4=B8=BA=E7=BC=BA=E7=9C=81?=
=?UTF-8?q?=E5=A4=84=E7=BD=AE=E8=A1=8C=E4=B8=BA=E6=97=B6,=E5=AF=B9?=
=?UTF-8?q?=E6=8C=87=E5=AE=9A=E4=BF=A1=E5=8F=B7=E8=BF=9B=E8=A1=8C=E6=8B=A6?=
=?UTF-8?q?=E6=88=AA,=E8=AF=A5=E6=94=B9=E5=8A=A8=E4=B8=8D=E5=BD=B1?=
=?UTF-8?q?=E5=93=8D=E5=8E=9F=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/lstack/api/lstack_signal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lstack/api/lstack_signal.c b/src/lstack/api/lstack_signal.c
index 87cbdda..4dba472 100644
--- a/src/lstack/api/lstack_signal.c
+++ b/src/lstack/api/lstack_signal.c
@@ -78,7 +78,7 @@ int lstack_sigaction(int sig_num, const struct sigaction *action, struct sigacti
{
struct sigaction new_action;
- if ((match_hijack_signal(sig_num) != 0) && (action->sa_handler == SIG_DFL)) {
+ if ((match_hijack_signal(sig_num) != 0) && (action && action->sa_handler == SIG_DFL)) {
new_action = *action;
new_action.sa_flags |= SA_RESETHAND;
new_action.sa_handler = lstack_sig_default_handler;
--
2.23.0

332
0053-update-README.md.patch Normal file
View File

@ -0,0 +1,332 @@
From 5249ab9e033d2f02ca78eca1b96db540f9990641 Mon Sep 17 00:00:00 2001
From: xiusailong <xiusailong@huawei.com>
Date: Wed, 29 Jun 2022 11:28:10 +0800
Subject: [PATCH 4/6] update README.md
---
README.md | 10 +-
...50\346\210\267\346\214\207\345\215\227.md" | 159 +++++++-----------
2 files changed, 62 insertions(+), 107 deletions(-)
diff --git a/README.md b/README.md
index 61f298c..3c1487c 100644
--- a/README.md
+++ b/README.md
@@ -75,12 +75,12 @@ mkdir -p /mnt/hugepages
mkdir -p /mnt/hugepages-2M
chmod -R 700 /mnt/hugepages
chmod -R 700 /mnt/hugepages-2M
-mount -t hugetlbfs nodev /mnt/hugepages
-mount -t hugetlbfs nodev /mnt/hugepages-2M
+mount -t hugetlbfs nodev /mnt/hugepages -o pagesize=2M
+mount -t hugetlbfs nodev /mnt/hugepages-2M -o pagesize=2M
```
### 5. 应用程序使用Gazelle
-有两种使能Gazelle方法根据需要选择其一
+有两种使用Gazelle方法根据需要选择其一
- 重新编译应用程序链接Gazelle的库
修改应用makefile文件链接liblstack.so示例如下
```
@@ -256,8 +256,8 @@ Gazelle可能存在如下安全风险用户需要根据使用场景评估风
- 风险点
属于同一用户的恶意进程模仿DPDK实现逻辑通过大页文件共享大页内存写破坏大页内存导致Gazelle程序crash。建议用户下的进程属于同一信任域。
-**流量限制**
+**流量限制**
Gazelle没有做流量限制用户有能力发送最大网卡线速流量的报文到网络可能导致网络流量拥塞。
-**进程仿冒**
+**进程仿冒**
合法注册到ltran的两个lstack进程进程A可仿冒进程B发送仿冒消息给ltran修改ltran的转发控制信息造成进程B通讯异常进程B报文转发给进程A信息泄露等问题。建议lstack进程都为可信任进程。
diff --git "a/doc/gazelle-\347\224\250\346\210\267\346\214\207\345\215\227.md" "b/doc/gazelle-\347\224\250\346\210\267\346\214\207\345\215\227.md"
index bfe0f7c..3f40bf1 100644
--- "a/doc/gazelle-\347\224\250\346\210\267\346\214\207\345\215\227.md"
+++ "b/doc/gazelle-\347\224\250\346\210\267\346\214\207\345\215\227.md"
@@ -1,54 +1,52 @@
-[toc]
+# gazelle-用户指南
-# 1 简介
+## 1 简介
EulerOS提供了利用Gazelle runtime优化数据库服务性能的完整解决方案Gazelle
runtime基于bypass内核的架构设计能够提供更高性能运行环境优化服务软件性
能,可以很好地满足产品的性能需求。
本文主要介绍Gazelle软件如何安装使用。
-# 2 安装软件包编译应用程序以redis 为例)
+## 2 安装软件包编译应用程序以redis 为例)
-1. 在使用之前需要安装Gazelle软件包。
+在使用之前需要安装Gazelle软件包。
-#### 操作步骤
+### 操作步骤
- Gazelle是高性能用户态协议栈软件包使用如下命令安装Gazelle软件包
+Gazelle是高性能用户态协议栈软件包使用如下命令安装Gazelle软件包
```
- yum install gazelle
+yum install gazelle
```
-#### 安装正确性验证
+### 安装正确性验证
- 1. 安装完成后使用“rpm -qa | grep -E gazelle”命令确认是否已经正确安装。示例如下
+1. 安装完成后使用“rpm -qa | grep -E gazelle”命令确认是否已经正确安装。示例如下
- 如果已正确安装则结果显示如下:
+如果已正确安装则结果显示如下:
```
- gazelle-1.0.0-h1.eulerosv2r10.aarch64
+gazelle-1.0.0-h1.eulerosv2r10.aarch64
```
2. 确认以下dpdk组件是否存在
```
-
- /lib/modules/4.19.90-vhulk2007.2.0.h188.eulerosv2r10.aarch64/extra/dpdk/igb_uio.ko
- /usr/share/dpdk
- /usr/share/dpdk/usertools/dpdk-devbind.py
+rpm -ql dpdk | grep igb_uio
+/usr/share/dpdk
+/usr/share/dpdk/usertools/dpdk-devbind.py
```
3. 确认以下Gazelle组件是否存在
-
-```
- /usr/bin/gazellectl
- /usr/bin/ltran
- /usr/lib64/liblstack.so
- /etc/gazelle/ltran.conf
- /etc/gazelle/lstack.conf
- /etc/gazelle/lstack.Makefile
+```
+/usr/bin/gazellectl
+/usr/bin/ltran
+/usr/lib64/liblstack.so
+/etc/gazelle/ltran.conf
+/etc/gazelle/lstack.conf
+/etc/gazelle/lstack.Makefile
```
-#### 链接Gazelle编译redis-server
+### 链接Gazelle编译redis-server
1. 获取开源redis代码更改redis/src/Makefile文件使其链接lstack示例如下
@@ -78,10 +76,10 @@ index 4b2a31c..92fa17d 100644
2. 编译redis
- ```
- localhost:/euler/zyk/serverless/lredis/src # make distclean
- localhost:/euler/zyk/serverless/lredis/src # make USE_GAZELLE=1 -j32
- ```
+ ```
+ localhost:/euler/zyk/serverless/lredis/src # make distclean
+ localhost:/euler/zyk/serverless/lredis/src # make USE_GAZELLE=1 -j32
+ ```
#### 注意
@@ -89,7 +87,7 @@ index 4b2a31c..92fa17d 100644
支持LD_PRELOAD方式免编译使用gazelle可跳过编译应用程序步骤。
-#3 设置配置文件以redis为例
+## 3 设置配置文件以redis为例
安装完软件包后运行Gazelle服务需要设置必要的配置文件。
@@ -168,13 +166,13 @@ tcp_conn_scan_interval=10
redis.conf为redis服务的配置文件可以参考开源的配置文件需要注意的是redis.conf侦听的ip必须和其使用的lstack.conf里面的host_addr值保持一致。
-# 4 环境初始化
+## 4 环境初始化
配置文件完成后需要配置大页、插入igb_uio.ko、绑定dpdk网卡等环境初始化工作才可以运行Gazelle服务。
**说明igb_uio.ko依赖于uio.ko需要用户先确保已安装uio.ko模块。**
-#### 操作步骤
+### 操作步骤
1. **配置大页内存**
@@ -203,68 +201,24 @@ tcp_conn_scan_interval=10
将需要通信的网卡绑定到dpdk示例如下
```
- [root@ARM159server usertools]# ./dpdk-devbind.py --bind=igb_uio eth4
+[root@ARM159server usertools]# dpdk-devbind.py --bind=igb_uio eth4
```
如果是1822网卡必须绑定vfio-pci驱动
-```
- [root@ARM159server usertools]# ./dpdk-devbind.py --bind=vfio-pci eth4
-```
-
-4. **一键部署脚本使用**
-
- 提供gazelle_setup脚本用于快速自动化部署gazelle运行环境。
-
- 一键部署脚本执行示例:
-
-```
- gazelle_setup.sh i/--nic eth0 n/--numa 1024,1024 d/--daemon 1/0 k/--kni 1/0 l/--lowpower 1/0 --ltrancore 0,1 --lstackcore 2-3
-```
-
- 参数描述:
-
- -i/--nic设置待绑定网卡此参数必须配置且网卡需要有ip、路由和网关等必须参数否则会读取配置失败必选。
-
- -n/--numalstack大页内存不包括ltran的ltran默认为1024Msetup脚本不对其做修改根据numa节点配置并用","(英文的逗号)分离这里需要根据系统环境内存配置对应的大小默认为1024 可选。
-
- -d/--daemon是否开启deamon模式开启为1关闭为0默认为1可选。
-
- -k/--kni是否开启kni开启为1关闭为0默认为0可选。
-
- -l/--lowpower是否开启低功耗模式开启为1关闭为0默认为0可选。
-
- --ltrancoreltran的绑核参数参考dpdk的参数配置此处不做参数校验默认为0,1可选。
-
- --lstackcorelstack的绑核参数同--ltrancore默认为2可选。
-
- **说明**
-
- 1. gazelle_setup.sh支持非root用户启动即执行脚本对应的用户及用户组
- 2. 默认配置文件的目录为:/etc/gazelle。
- 3. gazelle_setup.sh会按照启动参数生成lstack.conf对于lstack多进程场景若多进程要使用不同配置文件则需要自己拷贝修改每个进程的lstack.conf。
- 4. 部署脚本会启动ltran进程。
-
- 一键退出脚本执行实例:
```
- gazelle_exit.sh
+[root@ARM159server usertools]# dpdk-devbind.py --bind=vfio-pci eth4
```
- **说明**
-
- 若启动了ltran的守护任务gazelle_setup.sh指定了 -d/--daemon 1那么在杀死ltran之后守护任务仍会将ltran拉起所以此时若要完全退出ltran需要执行gazelle_exit.sh。
-
-
+## 5 运行Gazelle
-# 5 运行Gazelle
-
-#### 前提条件
+### 前提条件
- 已完成软件包的安装。
- 已设置完配置文件。
- 已初始化环境。
-#### 操作步骤
+### 操作步骤
1. **启动ltran**
@@ -275,21 +229,22 @@ tcp_conn_scan_interval=10
**说明一键部署脚本已启动ltran若使用一键部署脚本无需此步骤。**
```
- [root@localhost deploy_open_source]# ltran --config-file /usr/share/gazelle/ltran.confEAL: Detected 96 lcore(s)
- EAL: Detected 4 NUMA nodes
- EAL: Multi-process socket /var/run/dpdk/(null)/mp_socket
- EAL: Selected IOVA mode 'PA'
- EAL: No free hugepages reported in hugepages-2048kB
- EAL: No free hugepages reported in hugepages-2048kB
- EAL: No free hugepages reported in hugepages-2048kB
- EAL: No available hugepages reported in hugepages-1048576kB
- EAL: Probing VFIO support...
- EAL: VFIO support initialized
- EAL: PCI device 0000:03:00.0 on NUMA socket 0......
- EAL: Finished Process ltran_core_init.
- EAL: Finished Process ctrl_thread_fn.
- EAL: Finished Process client_rx_buf_init.
- EAL: Runing Process forward.
+[root@localhost deploy_open_source]# ltran --config-file /usr/share/gazelle/ltran.conf
+EAL: Detected 96 lcore(s)
+EAL: Detected 4 NUMA nodes
+EAL: Multi-process socket /var/run/dpdk/(null)/mp_socket
+EAL: Selected IOVA mode 'PA'
+EAL: No free hugepages reported in hugepages-2048kB
+EAL: No free hugepages reported in hugepages-2048kB
+EAL: No free hugepages reported in hugepages-2048kB
+EAL: No available hugepages reported in hugepages-1048576kB
+EAL: Probing VFIO support...
+EAL: VFIO support initialized
+EAL: PCI device 0000:03:00.0 on NUMA socket 0......
+EAL: Finished Process ltran_core_init.
+EAL: Finished Process ctrl_thread_fn.
+EAL: Finished Process client_rx_buf_init.
+EAL: Runing Process forward.
```
2. **启动redis**
@@ -367,7 +322,7 @@ GAZELLE_BIND_PROCNAME=benchmark_ker GAZELLE_BIND_THREADNAME=disp LD_PRELOAD=/lib
1. 不支持使用export方式单独声明LD_PRELOAD环境变量。
2. GAZELLE_BIND_PROCNAME指定lstack绑定的进程名称GAZELLE_BIND_THREADNAME指定lstack绑定的进程中的具体线程名且支持字串匹配如设置disp表示进程中所有线程名包含disp 字串的线程都会绑定lstack。
-# 6 最佳性能配置
+## 6 最佳性能配置
为获得最佳的性能Gazelle在启动时对cpu和内存配置有一定要求。最佳性能配置如下
@@ -377,7 +332,7 @@ GAZELLE_BIND_PROCNAME=benchmark_ker GAZELLE_BIND_THREADNAME=disp LD_PRELOAD=/lib
4. 应用进程绑核可提高性能与网卡同一个numa节点对应的核如果有空闲应当优先绑定。
5. Gazelle的网络高性能只有在远程访问的时候才有保证本机的tcp连接功能也支持但如果本机有频繁的数据访问会导致实例整体性能下降不建议这么部署。
-# 7 使用约束
+## 7 使用约束
1. Gazelle提供的命令行及配置文件仅root权限开源执行或修改。配置大页内存需要root用户执行操作。
2. 在将网卡绑定到igb_uio后禁止将网卡绑回ixgbe。
@@ -408,7 +363,7 @@ GAZELLE_BIND_PROCNAME=benchmark_ker GAZELLE_BIND_THREADNAME=disp LD_PRELOAD=/lib
-# 8 升级说明
+## 8 升级说明
后续升级需要变更的组件包括ltran、liblstack.so、gazellectl、lstack.Makefile、lstack.conf、ltran.conf、gazelle_setup.sh、gazelle_exit.sh、gazelle_crontab.sh、gazelle_common.sh。
@@ -436,9 +391,9 @@ GAZELLE_BIND_PROCNAME=benchmark_ker GAZELLE_BIND_THREADNAME=disp LD_PRELOAD=/lib
-#9 调测工具
+## 9 调测工具
-##9.1 获取ltran统计数据说明
+### 9.1 获取ltran统计数据说明
#### 概述
@@ -501,7 +456,7 @@ GAZELLE_BIND_PROCNAME=benchmark_ker GAZELLE_BIND_THREADNAME=disp LD_PRELOAD=/lib
-## 9.2 获取Lstack统计数据说明
+### 9.2 获取Lstack统计数据说明
#### 概述
@@ -553,4 +508,4 @@ lstack作为网络协议栈底座使用时必须指定需要获取的lstack
```
gazellectl lstack set {client_ip} lowpower {0 | 1}1:enable lowpower mode
-```
\ No newline at end of file
+```
--
2.23.0

View File

@ -0,0 +1,28 @@
From 0f37499d7922d59fa46b7961bde36ab0b20eac62 Mon Sep 17 00:00:00 2001
From: Honggang LI <honggangli@163.com>
Date: Thu, 23 Jun 2022 13:56:31 +0800
Subject: [PATCH 5/6] ltran: fix use-after-free issue
Signed-off-by: Honggang LI <honggangli@163.com>
---
src/ltran/ltran_timer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ltran/ltran_timer.c b/src/ltran/ltran_timer.c
index 29b307c..1327203 100644
--- a/src/ltran/ltran_timer.c
+++ b/src/ltran/ltran_timer.c
@@ -63,9 +63,9 @@ void gazelle_detect_sock_logout(struct gazelle_tcp_sock_htable *tcp_sock_htable)
hlist_del_init(&tcp_sock->tcp_sock_node);
tcp_sock_htable->cur_tcp_sock_num--;
tcp_sock_htable->array[i].chain_size--;
- free(tcp_sock);
LTRAN_DEBUG("delete the tcp sock htable: tid %u ip %u port %u\n",
tcp_sock->tid, tcp_sock->ip, (uint32_t)ntohs(tcp_sock->port));
+ free(tcp_sock);
}
}
}
--
2.23.0

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
Name: gazelle
Version: 1.0.1
Release: 9
Release: 10
Summary: gazelle is a high performance user-mode stack
License: Mulan PSL v2
URL: https://gitee.com/openeuler/gazelle
@ -54,6 +54,22 @@ Patch9036: 0036-the-sending-of-sock-last-data-is-triggered-by-lstack.patch
Patch9037: 0037-add-gazellectl-lstack-constraint.patch
Patch9038: 0038-refactor-event.patch
Patch9039: 0039-update-license-lockless-queue.patch
Patch9040: 0040-fix-sock-invalid-address.patch
Patch9041: 0041-exit-lstack-process-after-ltran-instance-logout.patch
Patch9042: 0042-use-atomic-variales-to-count.patch
Patch9043: 0043-re-arrange-the-program-to-invoke-rte_eth_dev_start-b.patch
Patch9044: 0044-delete-redundant-file.patch
Patch9045: 0045-lstack-all-exit-move-to-init.patch
Patch9046: 0046-clean-code-fix-huge-func.patch
Patch9047: 0047-add-kernel-path-in-epoll-funcs.patch
Patch9048: 0048-refactor-kernel-event-poll-epoll.patch
Patch9049: 0049-post-thread_phase1-sem-to-avoid-block-main-thread-wh.patch
Patch9050: 0050-adjust-the-number-of-RX-TX-mbufs-of-each-stack-threa.patch
Patch9051: 0051-modify-README.patch
Patch9052: 0052-bugfix-https-gitee.com-src-openeuler-gazelle-issues-.patch
Patch9053: 0053-update-README.md.patch
Patch9054: 0054-ltran-fix-use-after-free-issue.patch
Patch9055: 0055-refactor-pkt-read-send-performance.patch
%description
%{name} is a high performance user-mode stack.
@ -94,6 +110,15 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b
%config(noreplace) %{conf_path}/ltran.conf
%changelog
* Thu Jul 7 2022 jiangheng <jiangheng14@huawei.com> - 1.0.1-10
- Type:bugfix
- CVE:
- SUG:NA
- DESC:update readme
fix some bugs
refactor pkt read send to improve performance
refactoe kernle event to improve performanc
* Fri May 27 2022 xiusailong <xiusailong@huawei.com> - 1.0.1-9
- update license lockless queue