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:
parent
58d91474c6
commit
46ab1e1590
35
0040-fix-sock-invalid-address.patch
Normal file
35
0040-fix-sock-invalid-address.patch
Normal 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
|
||||
|
||||
70
0041-exit-lstack-process-after-ltran-instance-logout.patch
Normal file
70
0041-exit-lstack-process-after-ltran-instance-logout.patch
Normal 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 dumped,caught 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
|
||||
|
||||
78
0042-use-atomic-variales-to-count.patch
Normal file
78
0042-use-atomic-variales-to-count.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
183
0044-delete-redundant-file.patch
Normal file
183
0044-delete-redundant-file.patch
Normal 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
|
||||
|
||||
297
0045-lstack-all-exit-move-to-init.patch
Normal file
297
0045-lstack-all-exit-move-to-init.patch
Normal 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
|
||||
|
||||
356
0046-clean-code-fix-huge-func.patch
Normal file
356
0046-clean-code-fix-huge-func.patch
Normal 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
|
||||
|
||||
58
0047-add-kernel-path-in-epoll-funcs.patch
Normal file
58
0047-add-kernel-path-in-epoll-funcs.patch
Normal 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
|
||||
|
||||
836
0048-refactor-kernel-event-poll-epoll.patch
Normal file
836
0048-refactor-kernel-event-poll-epoll.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
365
0051-modify-README.patch
Normal 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选项,基于构建环境的CPU(Intel® Xeon® Gold 5118 CPU @ 2.30GHz)指令集进行优化。要求运行环境CPU支持SSE4.2、AVX、AVX2、AVX-512指令集。
|
||||
-- 最大IP分片数为10(ping最大包长14790),TCP协议不使用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选项,基于构建环境的CPU(Intel® Xeon® Gold 5118 CPU @ 2.30GHz指令集进行优化。要求运行环境CPU支持 SSE4.2、AVX、AVX2、AVX-512 指令集。
|
||||
+- 最大IP分片数为10(ping 最大包长14790B),TCP协议不使用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
|
||||
|
||||
@ -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
332
0053-update-README.md.patch
Normal 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/--numa:lstack大页内存(不包括ltran的,ltran默认为1024M,setup脚本不对其做修改),根据numa节点配置,并用","(英文的逗号)分离,这里需要根据系统环境内存配置对应的大小,默认为1024, 可选。
|
||||
-
|
||||
- -d/--daemon:是否开启deamon模式,开启为1,关闭为0;默认为1,可选。
|
||||
-
|
||||
- -k/--kni:是否开启kni,开启为1,关闭为0;默认为0,可选。
|
||||
-
|
||||
- -l/--lowpower:是否开启低功耗模式,开启为1,关闭为0;默认为0,可选。
|
||||
-
|
||||
- --ltrancore:ltran的绑核参数,参考dpdk的参数配置,此处不做参数校验;默认为0,1,可选。
|
||||
-
|
||||
- --lstackcore:lstack的绑核参数,同--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
|
||||
|
||||
28
0054-ltran-fix-use-after-free-issue.patch
Normal file
28
0054-ltran-fix-use-after-free-issue.patch
Normal 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
|
||||
|
||||
3232
0055-refactor-pkt-read-send-performance.patch
Normal file
3232
0055-refactor-pkt-read-send-performance.patch
Normal file
File diff suppressed because it is too large
Load Diff
27
gazelle.spec
27
gazelle.spec
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user