From 81f2e7969135dbcac3f508502afe860661e98b1a Mon Sep 17 00:00:00 2001 From: yinbin6 Date: Fri, 21 Jun 2024 11:39:14 +0800 Subject: [PATCH] sync [virtio]: create and init virtio_port (cherry picked from commit e8314fc36cdb8f34ffe0c46751820c38d6646946) --- 0188-redis-perf-add-tx-driver-cache.patch | 255 ++++++++++++ ...timized-latency-distribution-dotting.patch | 250 +++++++++++ 0190-rtc-adapt-rtc_close.patch | 51 +++ 0191-virtio-flow_bifurcation-switch.patch | 59 +++ 0192-remove-legacy-mem.patch | 30 ++ ...-cfg-bond_slave_mac-support-pci-addr.patch | 246 +++++++++++ 0194-refactor-tx-cache-module.patch | 340 +++++++++++++++ 0195-virtio-create-and-init-virtio_port.patch | 392 ++++++++++++++++++ gazelle.spec | 20 +- 9 files changed, 1642 insertions(+), 1 deletion(-) create mode 100644 0188-redis-perf-add-tx-driver-cache.patch create mode 100644 0189-optimized-latency-distribution-dotting.patch create mode 100644 0190-rtc-adapt-rtc_close.patch create mode 100644 0191-virtio-flow_bifurcation-switch.patch create mode 100644 0192-remove-legacy-mem.patch create mode 100644 0193-cfg-bond_slave_mac-support-pci-addr.patch create mode 100644 0194-refactor-tx-cache-module.patch create mode 100644 0195-virtio-create-and-init-virtio_port.patch diff --git a/0188-redis-perf-add-tx-driver-cache.patch b/0188-redis-perf-add-tx-driver-cache.patch new file mode 100644 index 0000000..af3dfff --- /dev/null +++ b/0188-redis-perf-add-tx-driver-cache.patch @@ -0,0 +1,255 @@ +From 9e6197b3d39a244ed7900bfc2df9d0f2290fcfb2 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Mon, 17 Jun 2024 10:41:54 +0800 +Subject: [PATCH] redis perf: add tx driver cache + +--- + src/lstack/api/dir.mk | 2 +- + src/lstack/api/lstack_tx_cache.c | 47 ++++++++++++++++++++++ + src/lstack/core/lstack_cfg.c | 13 ++++++ + src/lstack/core/lstack_protocol_stack.c | 1 + + src/lstack/include/lstack_cfg.h | 1 + + src/lstack/include/lstack_protocol_stack.h | 2 + + src/lstack/include/lstack_tx_cache.h | 28 +++++++++++++ + src/lstack/netif/lstack_ethdev.c | 30 +++++++++++--- + 8 files changed, 117 insertions(+), 7 deletions(-) + create mode 100644 src/lstack/api/lstack_tx_cache.c + create mode 100644 src/lstack/include/lstack_tx_cache.h + +diff --git a/src/lstack/api/dir.mk b/src/lstack/api/dir.mk +index 729690d..70bc59d 100644 +--- a/src/lstack/api/dir.mk ++++ b/src/lstack/api/dir.mk +@@ -8,7 +8,7 @@ + # PURPOSE. + # See the Mulan PSL v2 for more details. + +-SRC = lstack_epoll.c lstack_signal.c lstack_fork.c lstack_wrap.c lstack_rtw_api.c lstack_rtc_api.c lstack_dummy_api.c ++SRC = lstack_epoll.c lstack_signal.c lstack_fork.c lstack_wrap.c lstack_rtw_api.c lstack_rtc_api.c lstack_dummy_api.c lstack_tx_cache.c + + $(eval $(call register_dir, api, $(SRC))) + +diff --git a/src/lstack/api/lstack_tx_cache.c b/src/lstack/api/lstack_tx_cache.c +new file mode 100644 +index 0000000..42aef57 +--- /dev/null ++++ b/src/lstack/api/lstack_tx_cache.c +@@ -0,0 +1,47 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++ ++#include "lwip/sockets.h" ++#include "lstack_cfg.h" ++#include "lstack_protocol_stack.h" ++#include "lstack_tx_cache.h" ++ ++void stack_send_pkts(struct protocol_stack *stack) ++{ ++ if (!get_global_cfg_params()->send_cache_mode) { ++ return; ++ } ++ ++ uint32_t send_num = stack->tx_cache.send_end - stack->tx_cache.send_start; ++ ++ if (send_num == 0) { ++ return; ++ } ++ ++ uint32_t start = stack->tx_cache.send_start & STACK_SEND_MASK; ++ uint32_t end = stack->tx_cache.send_end & STACK_SEND_MASK; ++ uint32_t sent_pkts = 0; ++ ++ if (start < end) { ++ sent_pkts = stack->dev_ops.tx_xmit(stack, &stack->tx_cache.send_pkts[start], send_num); ++ } else { ++ send_num = STACK_SEND_MAX - start; ++ sent_pkts = stack->dev_ops.tx_xmit(stack, &stack->tx_cache.send_pkts[start], send_num); ++ if (sent_pkts == send_num) { ++ sent_pkts += stack->dev_ops.tx_xmit(stack, stack->tx_cache.send_pkts, end); ++ } ++ } ++ ++ stack->tx_cache.send_start += sent_pkts; ++ stack->stats.tx += sent_pkts; ++} ++ +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 0e5fbf3..56f290e 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -85,6 +85,7 @@ static int32_t parse_stack_thread_mode(void); + static int32_t parse_nic_vlan_mode(void); + static int32_t parse_defaule_nonblock_mode(void); + static int32_t parse_rpc_msg_max(void); ++static int32_t parse_send_cache_mode(void); + + #define PARSE_ARG(_arg, _arg_string, _default_val, _min_val, _max_val, _ret) \ + do { \ +@@ -150,6 +151,7 @@ static struct config_vector_t g_config_tbl[] = { + { "nic_vlan_mode", parse_nic_vlan_mode }, + { "nonblock_mode", parse_defaule_nonblock_mode }, + { "rpc_msg_max", parse_rpc_msg_max }, ++ { "send_cache_mode", parse_send_cache_mode }, + { NULL, NULL } + }; + +@@ -1380,3 +1382,14 @@ static int32_t parse_rpc_msg_max(void) + return ret; + } + ++static int32_t parse_send_cache_mode(void) ++{ ++ int32_t ret; ++ PARSE_ARG(g_config_params.send_cache_mode, "send_cache_mode", 0, 0, 1, ret); ++ if (ret != 0) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid send cache mode value %d. only support 0 or 1\n", ++ g_config_params.send_cache_mode); ++ } ++ return ret; ++} ++ +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index c5a265e..98d6549 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -480,6 +480,7 @@ int stack_polling(uint32_t wakeup_tick) + do_lwip_read_recvlist(stack, read_connect_number); + if ((wakeup_tick & 0xf) == 0) { + wakeup_stack_epoll(stack); ++ stack_send_pkts(stack); + } + + /* run to completion mode currently does not support sockmap */ +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index 94878de..b9721ff 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -121,6 +121,7 @@ struct cfg_params { + bool stack_mode_rtc; + bool nonblock_mode; + uint32_t rpc_msg_max; ++ bool send_cache_mode; + }; + + struct cfg_params *get_global_cfg_params(void); +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index c210ab9..ab27dfa 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -23,6 +23,7 @@ + #include "gazelle_dfx_msg.h" + #include "lstack_thread_rpc.h" + #include "lstack_ethdev.h" ++#include "lstack_tx_cache.h" + #include "gazelle_opt.h" + + #define SOCK_RECV_RING_SIZE (get_global_cfg_params()->recv_ring_size) +@@ -76,6 +77,7 @@ struct protocol_stack { + uint32_t tx_ring_used; + + struct rte_mbuf *pkts[NIC_QUEUE_SIZE_MAX]; ++ struct lstack_tx_cache tx_cache; + struct list_node recv_list; + struct list_node same_node_recv_list; /* used for same node processes communication */ + struct list_node wakeup_list; +diff --git a/src/lstack/include/lstack_tx_cache.h b/src/lstack/include/lstack_tx_cache.h +new file mode 100644 +index 0000000..3991b16 +--- /dev/null ++++ b/src/lstack/include/lstack_tx_cache.h +@@ -0,0 +1,28 @@ ++/* ++* 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_TX_CACHE_H_ ++#define _LSTACK_TX_CACHE_H_ ++ ++#define STACK_SEND_MAX (2048) ++#define STACK_SEND_MASK (STACK_SEND_MAX - 1) ++#define STACK_SEND_INDEX(index) ((index) & STACK_SEND_MASK) ++ ++struct lstack_tx_cache { ++ uint32_t send_start; ++ uint32_t send_end; ++ struct rte_mbuf *send_pkts[STACK_SEND_MAX]; ++}; ++ ++void stack_send_pkts(struct protocol_stack *stack); ++ ++#endif /* _LSTACK_TX_CACHE_H_ */ +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 048ea92..77172f8 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -34,6 +34,7 @@ + #include "lstack_protocol_stack.h" + #include "lstack_thread_rpc.h" + #include "lstack_flow.h" ++#include "lstack_tx_cache.h" + #include "lstack_ethdev.h" + + /* FRAME_MTU + 14byte header */ +@@ -186,6 +187,19 @@ int32_t eth_dev_poll(void) + return nr_pkts; + } + ++static void eth_dev_send_pkt(struct protocol_stack *stack, struct rte_mbuf *mbuf) ++{ ++ do { ++ if (STACK_SEND_INDEX(stack->tx_cache.send_end + 1) != STACK_SEND_INDEX(stack->tx_cache.send_start)) { ++ stack->tx_cache.send_pkts[STACK_SEND_INDEX(stack->tx_cache.send_end)] = mbuf; ++ stack->tx_cache.send_end++; ++ return; ++ } ++ stack_send_pkts(stack); ++ stack->stats.send_pkts_fail++; ++ } while (1); ++} ++ + static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + { + struct protocol_stack *stack = get_protocol_stack(); +@@ -231,12 +245,16 @@ static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + pbuf = pbuf->next; + } + +- uint32_t sent_pkts = stack->dev_ops.tx_xmit(stack, &first_mbuf, 1); +- stack->stats.tx += sent_pkts; +- if (sent_pkts < 1) { +- stack->stats.tx_drop++; +- rte_pktmbuf_free(first_mbuf); +- return ERR_MEM; ++ if (!get_global_cfg_params()->send_cache_mode) { ++ uint32_t sent_pkts = stack->dev_ops.tx_xmit(stack, &first_mbuf, 1); ++ stack->stats.tx += sent_pkts; ++ if (sent_pkts < 1) { ++ stack->stats.tx_drop++; ++ rte_pktmbuf_free(first_mbuf); ++ return ERR_MEM; ++ } ++ } else { ++ eth_dev_send_pkt(stack, first_mbuf); + } + + return ERR_OK; +-- +2.33.0 + diff --git a/0189-optimized-latency-distribution-dotting.patch b/0189-optimized-latency-distribution-dotting.patch new file mode 100644 index 0000000..fee0346 --- /dev/null +++ b/0189-optimized-latency-distribution-dotting.patch @@ -0,0 +1,250 @@ +From 8fd1a2bfacf928d86fe1b76fc1cd80b3a21cb2cc Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Thu, 13 Jun 2024 18:31:42 +0800 +Subject: [PATCH] optimized latency distribution dotting + +--- + src/common/gazelle_dfx_msg.h | 10 ++++--- + src/lstack/core/lstack_lwip.c | 4 +++ + src/lstack/core/lstack_protocol_stack.c | 8 +++--- + src/lstack/core/lstack_stack_stat.c | 36 +++++++++++++++++++++---- + src/lstack/core/lstack_thread_rpc.c | 3 ++- + src/lstack/include/lstack_stack_stat.h | 7 ++++- + src/lstack/include/lstack_thread_rpc.h | 2 -- + src/ltran/ltran_dfx.c | 17 +++++++----- + 8 files changed, 63 insertions(+), 24 deletions(-) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index cad7978..696daf2 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -69,10 +69,11 @@ enum GAZELLE_STAT_MODE { + }; + + enum GAZELLE_LATENCY_TYPE { +- GAZELLE_LATENCY_READ_LWIP, // t0 -> t1 +- GAZELLE_LATENCY_READ_APP_CALL, // t1 -> t2 +- GAZELLE_LATENCY_READ_LSTACK, // t2 -> t3 +- GAZELLE_LATENCY_READ_MAX, // t0 -> t3 ++ GAZELLE_LATENCY_INTO_MBOX, // t0 -> t1 ++ GAZELLE_LATENCY_READ_LWIP, // t1 -> t2 ++ GAZELLE_LATENCY_READ_APP_CALL, // t2 -> t3 ++ GAZELLE_LATENCY_READ_LSTACK, // t3 -> t4 ++ GAZELLE_LATENCY_READ_MAX, // t0 -> t4 + + GAZELLE_LATENCY_WRITE_INTO_RING, // t0 -> t1 + GAZELLE_LATENCY_WRITE_LWIP, // t1 -> t2 +@@ -80,6 +81,7 @@ enum GAZELLE_LATENCY_TYPE { + GAZELLE_LATENCY_WRITE_MAX, // t0 -> t3 + + GAZELLE_LATENCY_WRITE_RPC_MSG, // rpc_call_send ++ GAZELLE_LATENCY_RECVMBOX_READY, // ready to read from recvmbox + + GAZELLE_LATENCY_MAX, + }; +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 628319c..153c5cc 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -1104,6 +1104,10 @@ void do_lwip_read_recvlist(struct protocol_stack *stack, uint32_t max_num) + continue; + } + ++ if (get_protocol_stack_group()->latency_start) { ++ calculate_sock_latency(&sock->stack->latency, sock, GAZELLE_LATENCY_RECVMBOX_READY); ++ } ++ + ssize_t len = 0; + if (NETCONN_IS_UDP(sock)) { + len = lwip_recv(sock->conn->callback_arg.socket, NULL, SSIZE_MAX, 0); +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 98d6549..74e543d 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -882,10 +882,6 @@ void stack_send(struct rpc_msg *msg) + struct protocol_stack *stack = get_protocol_stack(); + int replenish_again; + +- if (get_protocol_stack_group()->latency_start) { +- calculate_rpcmsg_latency(&stack->latency, msg, GAZELLE_LATENCY_WRITE_RPC_MSG); +- } +- + struct lwip_sock *sock = get_socket(fd); + if (sock == NULL) { + msg->result = -1; +@@ -893,6 +889,10 @@ void stack_send(struct rpc_msg *msg) + return; + } + ++ if (get_protocol_stack_group()->latency_start) { ++ calculate_sock_latency(&stack->latency, sock, GAZELLE_LATENCY_WRITE_RPC_MSG); ++ } ++ + replenish_again = do_lwip_send(stack, sock->conn->callback_arg.socket, sock, len, 0); + if (replenish_again < 0) { + __sync_fetch_and_sub(&sock->call_num, 1); +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index e430195..a1bd44d 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include "lstack_cfg.h" + #include "lstack_ethdev.h" +@@ -67,21 +68,46 @@ void time_stamp_transfer_pbuf(struct pbuf *pbuf_old, struct pbuf *pbuf_new) + } + } + +-void time_stamp_into_rpcmsg(struct rpc_msg *msg) ++void time_stamp_into_rpcmsg(struct lwip_sock *sock) + { +- msg->time_stamp = get_current_time(); ++ sock->stamp.rpc_time_stamp = get_current_time(); + } + +-void calculate_rpcmsg_latency(struct gazelle_stack_latency *stack_latency, struct rpc_msg *msg, ++void time_stamp_into_recvmbox(struct lwip_sock *sock) ++{ ++ sock->stamp.mbox_time_stamp = get_current_time(); ++} ++ ++void time_stamp_record(int fd, struct pbuf *pbuf) ++{ ++ struct lwip_sock *sock = get_socket_by_fd(fd); ++ ++ if (get_protocol_stack_group()->latency_start && pbuf != NULL) { ++ calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_INTO_MBOX, 0); ++ time_stamp_into_recvmbox(sock); ++ } ++} ++ ++void calculate_sock_latency(struct gazelle_stack_latency *stack_latency, struct lwip_sock *sock, + enum GAZELLE_LATENCY_TYPE type) + { + uint64_t latency; ++ uint64_t stamp; + struct stack_latency *latency_stat; +- if (msg == NULL || msg->time_stamp < stack_latency->start_time || type >= GAZELLE_LATENCY_MAX) { ++ ++ if (type == GAZELLE_LATENCY_WRITE_RPC_MSG) { ++ stamp = sock->stamp.rpc_time_stamp; ++ } else if (type == GAZELLE_LATENCY_RECVMBOX_READY) { ++ stamp = sock->stamp.mbox_time_stamp; ++ } else { ++ return; ++ } ++ ++ if (stamp < stack_latency->start_time) { + return; + } + +- latency = get_current_time() - msg->time_stamp; ++ latency = get_current_time() - stamp; + latency_stat = &stack_latency->latency[type]; + + latency_stat->latency_total += latency; +diff --git a/src/lstack/core/lstack_thread_rpc.c b/src/lstack/core/lstack_thread_rpc.c +index b98ba84..04bdc3a 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 ++#include + #include + + #include "lstack_log.h" +@@ -471,7 +472,7 @@ int32_t rpc_call_send(rpc_queue *queue, int fd, const void *buf, size_t len, int + } + + if (get_protocol_stack_group()->latency_start) { +- time_stamp_into_rpcmsg(msg); ++ time_stamp_into_rpcmsg(get_socket_by_fd(fd)); + } + + msg->args[MSG_ARG_0].i = fd; +diff --git a/src/lstack/include/lstack_stack_stat.h b/src/lstack/include/lstack_stack_stat.h +index 939189e..f0d3d5d 100644 +--- a/src/lstack/include/lstack_stack_stat.h ++++ b/src/lstack/include/lstack_stack_stat.h +@@ -22,11 +22,14 @@ struct protocol_stack; + enum GAZELLE_LATENCY_TYPE; + enum GAZELLE_STAT_MODE; + struct gazelle_stat_msg_request; ++struct lwip_sock; + + void calculate_lstack_latency(struct gazelle_stack_latency *stack_latency, const struct pbuf *pbuf, + enum GAZELLE_LATENCY_TYPE type, uint64_t time_record); + void calculate_rpcmsg_latency(struct gazelle_stack_latency *stack_latency, struct rpc_msg *msg, + enum GAZELLE_LATENCY_TYPE type); ++void calculate_sock_latency(struct gazelle_stack_latency *stack_latency, struct lwip_sock *sock, ++ enum GAZELLE_LATENCY_TYPE type); + void stack_stat_init(void); + int handle_stack_cmd(int fd, struct gazelle_stat_msg_request *msg); + int handle_dpdk_cmd(int fd, enum GAZELLE_STAT_MODE stat_mode); +@@ -35,6 +38,8 @@ void lstack_get_low_power_info(struct gazelle_stat_low_power_info *low_power_inf + void unregister_wakeup(struct protocol_stack *stack, struct wakeup_poll *wakeup); + void lstack_calculate_aggregate(int type, uint32_t len); + void time_stamp_transfer_pbuf(struct pbuf *pbuf_old, struct pbuf *pbuf_new); +-void time_stamp_into_rpcmsg(struct rpc_msg *msg); ++void time_stamp_into_rpcmsg(struct lwip_sock *sock); ++void time_stamp_into_recvmbox(struct lwip_sock *sock); ++void time_stamp_record(int fd, struct pbuf *pbuf); + + #endif /* GAZELLE_STACK_STAT_H */ +diff --git a/src/lstack/include/lstack_thread_rpc.h b/src/lstack/include/lstack_thread_rpc.h +index 0c51848..276ebb2 100644 +--- a/src/lstack/include/lstack_thread_rpc.h ++++ b/src/lstack/include/lstack_thread_rpc.h +@@ -58,8 +58,6 @@ struct rpc_msg { + + rpc_msg_func func; /* msg handle func hook */ + union rpc_msg_arg args[RPM_MSG_ARG_SIZE]; /* resolve by type */ +- +- uint64_t time_stamp; /* rpc_call_* start time */ + }; + + static inline void rpc_queue_init(rpc_queue *queue) +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 319f7cd..4351891 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -899,11 +899,13 @@ static void gazelle_print_lstack_stat_latency(void *buf, const struct gazelle_st + + printf("Statistics of lstack latency pkts min(us) max(us) average(us)\n"); + printf("Recv:\n"); +- printf("range: t0--->t1\n%s", res[GAZELLE_LATENCY_READ_LWIP].latency_stat_result); +- printf("range: t1--->t2\n%s", res[GAZELLE_LATENCY_READ_APP_CALL].latency_stat_result); +- printf("range: t2--->t3\n%s", res[GAZELLE_LATENCY_READ_LSTACK].latency_stat_result); +- printf("range: t0--->t3\n%s", res[GAZELLE_LATENCY_READ_MAX].latency_stat_result); +- printf("t0: read from nic t1: into recv ring t2: app read start t3: app read end\n"); ++ ++ printf("range: t0--->t1\n%s", res[GAZELLE_LATENCY_INTO_MBOX].latency_stat_result); ++ printf("range: t1--->t2\n%s", res[GAZELLE_LATENCY_READ_LWIP].latency_stat_result); ++ printf("range: t2--->t3\n%s", res[GAZELLE_LATENCY_READ_APP_CALL].latency_stat_result); ++ printf("range: t3--->t4\n%s", res[GAZELLE_LATENCY_READ_LSTACK].latency_stat_result); ++ printf("range: t0--->t4\n%s", res[GAZELLE_LATENCY_READ_MAX].latency_stat_result); ++ printf("t0: read from nic t1: into recvmbox t2: into recvring t3: app read start t4: app read end\n"); + + printf("Send:\n"); + printf("range: t0--->t1\n%s", res[GAZELLE_LATENCY_WRITE_INTO_RING].latency_stat_result); +@@ -912,8 +914,9 @@ static void gazelle_print_lstack_stat_latency(void *buf, const struct gazelle_st + printf("range: t0--->t3\n%s", res[GAZELLE_LATENCY_WRITE_MAX].latency_stat_result); + printf("t0: app send t1: into send ring t2: out of send ring t3: send to nic\n"); + +- printf("Rpc:\n"); +- printf("rpc_call_send \n%s", res[GAZELLE_LATENCY_WRITE_RPC_MSG].latency_stat_result); ++ printf("Others:\n"); ++ printf("rpc_call_send\n%s", res[GAZELLE_LATENCY_WRITE_RPC_MSG].latency_stat_result); ++ printf("ready to read from recvmbox\n%s", res[GAZELLE_LATENCY_RECVMBOX_READY].latency_stat_result); + + free(res); + } +-- +2.33.0 + diff --git a/0190-rtc-adapt-rtc_close.patch b/0190-rtc-adapt-rtc_close.patch new file mode 100644 index 0000000..11f66dd --- /dev/null +++ b/0190-rtc-adapt-rtc_close.patch @@ -0,0 +1,51 @@ +From cba42b0ca25bed62c946a4d902deb82ce0ca74e9 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Sat, 2 Mar 2024 13:44:20 +0800 +Subject: [PATCH] rtc: adapt rtc_close + +--- + src/lstack/api/lstack_epoll.c | 4 +++- + src/lstack/api/lstack_rtc_api.c | 12 +++++++++++- + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c +index 7dbef9d..6ae0eec 100644 +--- a/src/lstack/api/lstack_epoll.c ++++ b/src/lstack/api/lstack_epoll.c +@@ -322,7 +322,9 @@ int32_t lstack_epoll_close(int32_t fd) + + wakeup->type = WAKEUP_CLOSE; + +- stack_broadcast_clean_epoll(wakeup); ++ if (!get_global_cfg_params()->stack_mode_rtc) { ++ stack_broadcast_clean_epoll(wakeup); ++ } + + struct list_node *node, *temp; + pthread_spin_lock(&wakeup->event_list_lock); +diff --git a/src/lstack/api/lstack_rtc_api.c b/src/lstack/api/lstack_rtc_api.c +index 2e10e30..18664ca 100644 +--- a/src/lstack/api/lstack_rtc_api.c ++++ b/src/lstack/api/lstack_rtc_api.c +@@ -63,7 +63,17 @@ int rtc_socket(int domain, int type, int protocol) + + int rtc_close(int s) + { +- return lwip_close(s); ++ struct lwip_sock *sock = get_socket(s); ++ if (sock != NULL && sock->wakeup != NULL && sock->wakeup->epollfd == s) { ++ return lstack_epoll_close(s); ++ } ++ ++ lwip_close(s); ++ if (sock != NULL) { ++ list_del_node_null(&sock->event_list); ++ } ++ ++ return posix_api->close_fn(s); + } + + int rtc_shutdown(int fd, int how) +-- +2.33.0 + diff --git a/0191-virtio-flow_bifurcation-switch.patch b/0191-virtio-flow_bifurcation-switch.patch new file mode 100644 index 0000000..a6c6241 --- /dev/null +++ b/0191-virtio-flow_bifurcation-switch.patch @@ -0,0 +1,59 @@ +From 259092f39041968a07b395c43ed9cd26250215d9 Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Tue, 18 Jun 2024 11:29:58 +0800 +Subject: [PATCH] [virtio]: flow_bifurcation switch + +--- + src/lstack/core/lstack_cfg.c | 12 ++++++++++++ + src/lstack/include/lstack_cfg.h | 1 + + 2 files changed, 13 insertions(+) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 56f290e..f0c5f4f 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -86,6 +86,7 @@ static int32_t parse_nic_vlan_mode(void); + static int32_t parse_defaule_nonblock_mode(void); + static int32_t parse_rpc_msg_max(void); + static int32_t parse_send_cache_mode(void); ++static int32_t parse_flow_bifurcation(void); + + #define PARSE_ARG(_arg, _arg_string, _default_val, _min_val, _max_val, _ret) \ + do { \ +@@ -152,6 +153,7 @@ static struct config_vector_t g_config_tbl[] = { + { "nonblock_mode", parse_defaule_nonblock_mode }, + { "rpc_msg_max", parse_rpc_msg_max }, + { "send_cache_mode", parse_send_cache_mode }, ++ { "flow_bifurcation", parse_flow_bifurcation}, + { NULL, NULL } + }; + +@@ -1393,3 +1395,13 @@ static int32_t parse_send_cache_mode(void) + return ret; + } + ++static int32_t parse_flow_bifurcation(void) ++{ ++ int32_t ret; ++ PARSE_ARG(g_config_params.flow_bifurcation, "flow_bifurcation", 0, 0, 1, ret); ++ if (ret != 0) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid flow_bifurcation value %d. only support 0 or 1\n", ++ g_config_params.flow_bifurcation); ++ } ++ return ret; ++} +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index b9721ff..9649d73 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -122,6 +122,7 @@ struct cfg_params { + bool nonblock_mode; + uint32_t rpc_msg_max; + bool send_cache_mode; ++ bool flow_bifurcation; + }; + + struct cfg_params *get_global_cfg_params(void); +-- +2.33.0 + diff --git a/0192-remove-legacy-mem.patch b/0192-remove-legacy-mem.patch new file mode 100644 index 0000000..411da6a --- /dev/null +++ b/0192-remove-legacy-mem.patch @@ -0,0 +1,30 @@ +From 9fc2f5d7e298c3f549ad7abccc01ee1b971068e2 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Sun, 16 Jun 2024 14:29:43 +0800 +Subject: [PATCH] remove legacy-mem + +--- + src/lstack/lstack.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/lstack/lstack.conf b/src/lstack/lstack.conf +index 9cf967a..c65a25d 100644 +--- a/src/lstack/lstack.conf ++++ b/src/lstack/lstack.conf +@@ -8,11 +8,11 @@ + # PURPOSE. + # See the Mulan PSL v2 for more details. + +-dpdk_args=["--socket-mem", "2048,0,0,0", "--huge-dir", "/mnt/hugepages-lstack", "--proc-type", "primary", "--legacy-mem"] ++dpdk_args=["--socket-mem", "2048,0,0,0", "--huge-dir", "/mnt/hugepages-lstack", "--proc-type", "primary"] + + stack_thread_mode="run-to-wakeup" + +-#ltran mode need add "--map-perfect" in dpdk_args ++#ltran mode need add "--map-perfect" and "--legacy-mem" in dpdk_args + use_ltran=0 + kni_switch=0 + +-- +2.33.0 + diff --git a/0193-cfg-bond_slave_mac-support-pci-addr.patch b/0193-cfg-bond_slave_mac-support-pci-addr.patch new file mode 100644 index 0000000..4721ce6 --- /dev/null +++ b/0193-cfg-bond_slave_mac-support-pci-addr.patch @@ -0,0 +1,246 @@ +From 61366e0a54935684ca3e17477c6367907285a5ff Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Mon, 17 Jun 2024 18:35:12 +0800 +Subject: [PATCH] cfg: bond_slave_mac support pci addr + +--- + src/lstack/core/lstack_cfg.c | 35 +++++++++--------- + src/lstack/core/lstack_dpdk.c | 63 ++++++++++++++++++++++++--------- + src/lstack/include/lstack_cfg.h | 16 ++++++++- + 3 files changed, 80 insertions(+), 34 deletions(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 0e5fbf3..6ce862b 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -39,6 +39,7 @@ + #define LSTACK_CONF_ENV "LSTACK_CONF_PATH" + #define NUMA_CPULIST_PATH "/sys/devices/system/node/node%u/cpulist" + #define DEV_MAC_LEN 17 ++#define DEV_PCI_ADDR_LEN 12 + #define CPUS_MAX_NUM 256 + #define BOND_MIIMON_MIN 1 + #define BOND_MIIMON_MAX INT_MAX +@@ -188,6 +189,21 @@ static int32_t str_to_eth_addr(const char *src, unsigned char *dst) + return 0; + } + ++static int32_t str_to_dev_addr(const char *src, struct dev_addr *dst) ++{ ++ int32_t ret = 0; ++ if (strlen(src) == DEV_PCI_ADDR_LEN) { ++ /* str to pci addr */ ++ ret = rte_pci_addr_parse(src, &dst->addr.pci_addr); ++ dst->addr_type = DEV_ADDR_TYPE_PCI; ++ } else { ++ /* str to mac addr */ ++ ret = str_to_eth_addr(src, dst->addr.mac_addr.addr_bytes); ++ dst->addr_type = DEV_ADDR_TYPE_MAC; ++ } ++ return ret; ++} ++ + static int32_t parse_gateway_addr(void) + { + char *value; +@@ -1227,16 +1243,6 @@ static int32_t parse_bond_miimon(void) + return ret; + } + +-static bool validate_bond_mac(uint8_t *mac_addr, struct rte_ether_addr *bond_slave_mac, int num_slaves) +-{ +- for (int i = 0; i < num_slaves; i++) { +- if (memcmp(mac_addr, bond_slave_mac[i].addr_bytes, ETHER_ADDR_LEN) == 0) { +- return true; +- } +- } +- return false; +-} +- + static int32_t parse_bond_slave_mac(void) + { + if (g_config_params.bond_mode == -1) { +@@ -1269,7 +1275,8 @@ static int32_t parse_bond_slave_mac(void) + free(bond_slave_mac_tmp); + return -EINVAL; + } +- ret = str_to_eth_addr(mac_addr, g_config_params.bond_slave_mac_addr[k].addr_bytes); ++ ++ ret = str_to_dev_addr(mac_addr, &g_config_params.bond_slave_addr[k]); + if (ret != 0) { + LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid device name %s ret=%d.\n", mac_addr, ret); + free(bond_slave_mac_tmp); +@@ -1279,12 +1286,6 @@ static int32_t parse_bond_slave_mac(void) + k = k + 1; + } + free(bond_slave_mac_tmp); +- if (g_config_params.bond_mode == BONDING_MODE_ACTIVE_BACKUP) { +- if (!validate_bond_mac(g_config_params.mac_addr, g_config_params.bond_slave_mac_addr, GAZELLE_MAX_BOND_NUM)) { +- LSTACK_PRE_LOG(LSTACK_ERR, "cfg: devices must be in bond_slave_mac for BONDING_MODE_ACTIVE_BACKUP.\n"); +- return -EINVAL; +- } +- } + return ret; + } + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 07fffe9..785431f 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -372,6 +372,23 @@ static int32_t ethdev_port_id(uint8_t *mac) + return port_id; + } + ++static int32_t pci_to_port_id(struct rte_pci_addr *pci_addr) ++{ ++ uint16_t port_id; ++ char device_name[RTE_DEV_NAME_MAX_LEN] = ""; ++ ++ rte_pci_device_name(pci_addr, device_name, RTE_DEV_NAME_MAX_LEN); ++ ++ int ret = rte_eth_dev_get_port_by_name(device_name, &port_id); ++ if (ret < 0) { ++ LSTACK_LOG(ERR, LSTACK, "match failed: no NIC matches cfg:%04x:%02x:%02x.%x\n", ++ pci_addr->domain, pci_addr->bus, pci_addr->devid, pci_addr->function); ++ return -EINVAL; ++ } ++ ++ return port_id; ++} ++ + static int eth_params_rss(struct rte_eth_conf *conf, struct rte_eth_dev_info *dev_info) + { + int rss_enable = 0; +@@ -491,18 +508,25 @@ static void rss_setup(const int port_id, const uint16_t nb_queues) + free(reta_conf); + } + +-int32_t dpdk_bond_primary_set(int port_id, int slave_port_id) ++int32_t dpdk_bond_primary_set(int port_id, int *slave_port_id) + { + int32_t primary_port_id = ethdev_port_id(get_global_cfg_params()->mac_addr); +- if (slave_port_id == primary_port_id) { +- int32_t ret = rte_eth_bond_primary_set(port_id, primary_port_id); +- if (ret != 0) { +- LSTACK_LOG(ERR, LSTACK, "dpdk set bond primary port failed ret = %d\n", ret); +- return -1; ++ if (primary_port_id < 0) { ++ LSTACK_LOG(ERR, LSTACK, "cannot get the port id of the cfg\n"); ++ return -1; ++ } ++ for (int i = 0; i < GAZELLE_MAX_BOND_NUM; i++) { ++ if (slave_port_id[i] == primary_port_id) { ++ int32_t ret = rte_eth_bond_primary_set(port_id, primary_port_id); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "dpdk set bond primary port failed ret = %d\n", ret); ++ return -1; ++ } ++ return ret; + } +- return ret; + } +- return 0; ++ LSTACK_LOG(ERR, LSTACK, "cfg: devices must be in bond_slave_mac for BONDING_MODE_ACTIVE_BACKUP.\n"); ++ return -1; + } + + int32_t dpdk_ethdev_init(int port_id) +@@ -687,12 +711,17 @@ static int dpdk_bond_create(uint8_t mode, int *slave_port_id, int count) + LSTACK_LOG(ERR, LSTACK, "bond add slave devices failed, ret=%d\n", ret); + return -1; + } +- if (cfg->bond_mode == BONDING_MODE_ACTIVE_BACKUP) { +- dpdk_bond_primary_set(port_id, slave_port_id[i]); ++ } ++ ++ if (cfg->bond_mode == BONDING_MODE_ACTIVE_BACKUP) { ++ ret = dpdk_bond_primary_set(port_id, slave_port_id); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "dpdk set bond primary port failed ret = %d\n", ret); ++ return -1; + } + } + +- if (get_global_cfg_params()->bond_mode == BONDING_MODE_8023AD) { ++ if (cfg->bond_mode == BONDING_MODE_8023AD) { + ret = rte_eth_bond_8023ad_dedicated_queues_enable(port_id); + if (ret < 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk enable 8023 dedicated queues failed ret = %d\n", ret); +@@ -717,8 +746,7 @@ static int dpdk_bond_create(uint8_t mode, int *slave_port_id, int count) + return -1; + } + +- if ((get_global_cfg_params()->bond_mode == BONDING_MODE_8023AD) || +- (get_global_cfg_params()->bond_mode == BONDING_MODE_ALB)) { ++ if ((cfg->bond_mode == BONDING_MODE_8023AD) || (cfg->bond_mode == BONDING_MODE_ALB)) { + for (int i = 0; i < count; i++) { + /* bond port promiscuous only enable primary port */ + /* we enable all ports */ +@@ -742,17 +770,20 @@ static int dpdk_bond_create(uint8_t mode, int *slave_port_id, int count) + int32_t init_dpdk_ethdev(void) + { + int32_t ret; +- int slave_port_id[GAZELLE_MAX_BOND_NUM]; ++ int slave_port_id[GAZELLE_MAX_BOND_NUM] = {-1}; + int port_id; + struct cfg_params *cfg = get_global_cfg_params(); + int i; + + if (cfg->bond_mode >= 0) { + for (i = 0; i < GAZELLE_MAX_BOND_NUM; i++) { +- if (rte_is_zero_ether_addr(&cfg->bond_slave_mac_addr[i])) { ++ if (cfg->bond_slave_addr[i].addr_type == DEV_ADDR_TYPE_EMPTY) { + break; ++ } else if (cfg->bond_slave_addr[i].addr_type == DEV_ADDR_TYPE_MAC) { ++ slave_port_id[i] = ethdev_port_id(cfg->bond_slave_addr[i].addr.mac_addr.addr_bytes); ++ } else { ++ slave_port_id[i] = pci_to_port_id(&cfg->bond_slave_addr[i].addr.pci_addr); + } +- slave_port_id[i] = ethdev_port_id(cfg->bond_slave_mac_addr[i].addr_bytes); + ret = dpdk_ethdev_init(slave_port_id[i]); + if (ret < 0) { + LSTACK_LOG(ERR, LSTACK, "slave port(%d) init failed, ret=%d\n", slave_port_id[i], ret); +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index 94878de..21d9d83 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -16,6 +16,8 @@ + + #include + #include ++#include ++#include + + #include "lstack_protocol_stack.h" + #include "gazelle_opt.h" +@@ -52,6 +54,18 @@ + #define LSTACK_LPM_PKTS_IN_DETECT_MIN 5 + #define LSTACK_LPM_PKTS_IN_DETECT_MAX 65535 + ++#define DEV_ADDR_TYPE_EMPTY 0 ++#define DEV_ADDR_TYPE_MAC 1 ++#define DEV_ADDR_TYPE_PCI 2 ++ ++struct dev_addr { ++ uint8_t addr_type; // 0:empty, 1:mac, 2:pci ++ union addr_union { ++ struct rte_ether_addr mac_addr; ++ struct rte_pci_addr pci_addr; ++ } addr; ++}; ++ + struct secondary_attach_arg { + uint8_t socket_num; + uint64_t socket_size; +@@ -114,7 +128,7 @@ struct cfg_params { + bool tuple_filter; + int8_t bond_mode; + int32_t bond_miimon; +- struct rte_ether_addr bond_slave_mac_addr[GAZELLE_MAX_BOND_NUM]; ++ struct dev_addr bond_slave_addr[GAZELLE_MAX_BOND_NUM]; + bool use_sockmap; + bool udp_enable; + struct cfg_nic_params nic; +-- +2.33.0 + diff --git a/0194-refactor-tx-cache-module.patch b/0194-refactor-tx-cache-module.patch new file mode 100644 index 0000000..3516aaa --- /dev/null +++ b/0194-refactor-tx-cache-module.patch @@ -0,0 +1,340 @@ +From dae1c41eea8dba45344f49c2fc00eeb31a24f925 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 17 Jun 2024 19:09:13 +0800 +Subject: [PATCH] refactor tx cache module + +--- + src/lstack/api/dir.mk | 2 +- + src/lstack/api/lstack_tx_cache.c | 47 --------- + src/lstack/core/lstack_cfg.c | 1 - + src/lstack/core/lstack_protocol_stack.c | 4 +- + src/lstack/include/lstack_protocol_stack.h | 1 - + src/lstack/include/lstack_tx_cache.h | 13 +-- + src/lstack/netif/dir.mk | 2 +- + src/lstack/netif/lstack_ethdev.c | 32 ++---- + src/lstack/netif/lstack_tx_cache.c | 114 +++++++++++++++++++++ + 9 files changed, 130 insertions(+), 86 deletions(-) + delete mode 100644 src/lstack/api/lstack_tx_cache.c + create mode 100644 src/lstack/netif/lstack_tx_cache.c + +diff --git a/src/lstack/api/dir.mk b/src/lstack/api/dir.mk +index 70bc59d..729690d 100644 +--- a/src/lstack/api/dir.mk ++++ b/src/lstack/api/dir.mk +@@ -8,7 +8,7 @@ + # PURPOSE. + # See the Mulan PSL v2 for more details. + +-SRC = lstack_epoll.c lstack_signal.c lstack_fork.c lstack_wrap.c lstack_rtw_api.c lstack_rtc_api.c lstack_dummy_api.c lstack_tx_cache.c ++SRC = lstack_epoll.c lstack_signal.c lstack_fork.c lstack_wrap.c lstack_rtw_api.c lstack_rtc_api.c lstack_dummy_api.c + + $(eval $(call register_dir, api, $(SRC))) + +diff --git a/src/lstack/api/lstack_tx_cache.c b/src/lstack/api/lstack_tx_cache.c +deleted file mode 100644 +index 42aef57..0000000 +--- a/src/lstack/api/lstack_tx_cache.c ++++ /dev/null +@@ -1,47 +0,0 @@ +-/* +-* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. +-* gazelle is licensed under the Mulan PSL v2. +-* You can use this software according to the terms and conditions of the Mulan PSL v2. +-* You may obtain a copy of Mulan PSL v2 at: +-* http://license.coscl.org.cn/MulanPSL2 +-* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +-* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +-* PURPOSE. +-* See the Mulan PSL v2 for more details. +-*/ +- +-#include "lwip/sockets.h" +-#include "lstack_cfg.h" +-#include "lstack_protocol_stack.h" +-#include "lstack_tx_cache.h" +- +-void stack_send_pkts(struct protocol_stack *stack) +-{ +- if (!get_global_cfg_params()->send_cache_mode) { +- return; +- } +- +- uint32_t send_num = stack->tx_cache.send_end - stack->tx_cache.send_start; +- +- if (send_num == 0) { +- return; +- } +- +- uint32_t start = stack->tx_cache.send_start & STACK_SEND_MASK; +- uint32_t end = stack->tx_cache.send_end & STACK_SEND_MASK; +- uint32_t sent_pkts = 0; +- +- if (start < end) { +- sent_pkts = stack->dev_ops.tx_xmit(stack, &stack->tx_cache.send_pkts[start], send_num); +- } else { +- send_num = STACK_SEND_MAX - start; +- sent_pkts = stack->dev_ops.tx_xmit(stack, &stack->tx_cache.send_pkts[start], send_num); +- if (sent_pkts == send_num) { +- sent_pkts += stack->dev_ops.tx_xmit(stack, stack->tx_cache.send_pkts, end); +- } +- } +- +- stack->tx_cache.send_start += sent_pkts; +- stack->stats.tx += sent_pkts; +-} +- +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index f0c5f4f..5521898 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -32,7 +32,6 @@ + #include "gazelle_reg_msg.h" + #include "lstack_log.h" + #include "gazelle_base_func.h" +-#include "lstack_protocol_stack.h" + #include "lstack_cfg.h" + + #define DEFAULT_CONF_FILE "/etc/gazelle/lstack.conf" +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 74e543d..f6d381e 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -480,7 +480,9 @@ int stack_polling(uint32_t wakeup_tick) + do_lwip_read_recvlist(stack, read_connect_number); + if ((wakeup_tick & 0xf) == 0) { + wakeup_stack_epoll(stack); +- stack_send_pkts(stack); ++ if (get_global_cfg_params()->send_cache_mode) { ++ tx_cache_send(stack->queue_id); ++ } + } + + /* run to completion mode currently does not support sockmap */ +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index ab27dfa..6ca4f14 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -77,7 +77,6 @@ struct protocol_stack { + uint32_t tx_ring_used; + + struct rte_mbuf *pkts[NIC_QUEUE_SIZE_MAX]; +- struct lstack_tx_cache tx_cache; + struct list_node recv_list; + struct list_node same_node_recv_list; /* used for same node processes communication */ + struct list_node wakeup_list; +diff --git a/src/lstack/include/lstack_tx_cache.h b/src/lstack/include/lstack_tx_cache.h +index 3991b16..04e9e35 100644 +--- a/src/lstack/include/lstack_tx_cache.h ++++ b/src/lstack/include/lstack_tx_cache.h +@@ -13,16 +13,7 @@ + #ifndef _LSTACK_TX_CACHE_H_ + #define _LSTACK_TX_CACHE_H_ + +-#define STACK_SEND_MAX (2048) +-#define STACK_SEND_MASK (STACK_SEND_MAX - 1) +-#define STACK_SEND_INDEX(index) ((index) & STACK_SEND_MASK) +- +-struct lstack_tx_cache { +- uint32_t send_start; +- uint32_t send_end; +- struct rte_mbuf *send_pkts[STACK_SEND_MAX]; +-}; +- +-void stack_send_pkts(struct protocol_stack *stack); ++int tx_cache_init(uint16_t queue_id, void *priv, struct lstack_dev_ops *dev_ops); ++int tx_cache_send(uint16_t queue_id); + + #endif /* _LSTACK_TX_CACHE_H_ */ +diff --git a/src/lstack/netif/dir.mk b/src/lstack/netif/dir.mk +index 1e67734..b551041 100644 +--- a/src/lstack/netif/dir.mk ++++ b/src/lstack/netif/dir.mk +@@ -8,7 +8,7 @@ + # PURPOSE. + # See the Mulan PSL v2 for more details. + +-SRC = lstack_ethdev.c lstack_vdev.c lstack_flow.c ++SRC = lstack_ethdev.c lstack_vdev.c lstack_flow.c lstack_tx_cache.c + ifeq ($(GAZELLE_FAULT_INJECT_ENABLE), 1) + SRC += lstack_fault_inject.c + endif +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 77172f8..45c5f9e 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -187,19 +187,6 @@ int32_t eth_dev_poll(void) + return nr_pkts; + } + +-static void eth_dev_send_pkt(struct protocol_stack *stack, struct rte_mbuf *mbuf) +-{ +- do { +- if (STACK_SEND_INDEX(stack->tx_cache.send_end + 1) != STACK_SEND_INDEX(stack->tx_cache.send_start)) { +- stack->tx_cache.send_pkts[STACK_SEND_INDEX(stack->tx_cache.send_end)] = mbuf; +- stack->tx_cache.send_end++; +- return; +- } +- stack_send_pkts(stack); +- stack->stats.send_pkts_fail++; +- } while (1); +-} +- + static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + { + struct protocol_stack *stack = get_protocol_stack(); +@@ -245,16 +232,12 @@ static err_t eth_dev_output(struct netif *netif, struct pbuf *pbuf) + pbuf = pbuf->next; + } + +- if (!get_global_cfg_params()->send_cache_mode) { +- uint32_t sent_pkts = stack->dev_ops.tx_xmit(stack, &first_mbuf, 1); +- stack->stats.tx += sent_pkts; +- if (sent_pkts < 1) { +- stack->stats.tx_drop++; +- rte_pktmbuf_free(first_mbuf); +- return ERR_MEM; +- } +- } else { +- eth_dev_send_pkt(stack, first_mbuf); ++ uint32_t sent_pkts = stack->dev_ops.tx_xmit(stack, &first_mbuf, 1); ++ stack->stats.tx += sent_pkts; ++ if (sent_pkts < 1) { ++ stack->stats.tx_drop++; ++ rte_pktmbuf_free(first_mbuf); ++ return ERR_MEM; + } + + return ERR_OK; +@@ -295,6 +278,9 @@ int32_t ethdev_init(struct protocol_stack *stack) + struct cfg_params *cfg = get_global_cfg_params(); + + vdev_dev_ops_init(&stack->dev_ops); ++ if (cfg->send_cache_mode) { ++ tx_cache_init(stack->queue_id, stack, &stack->dev_ops); ++ } + + if (use_ltran()) { + stack->rx_ring_used = 0; +diff --git a/src/lstack/netif/lstack_tx_cache.c b/src/lstack/netif/lstack_tx_cache.c +new file mode 100644 +index 0000000..ac5a9db +--- /dev/null ++++ b/src/lstack/netif/lstack_tx_cache.c +@@ -0,0 +1,114 @@ ++/* ++* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++* gazelle is licensed under the Mulan PSL v2. ++* You can use this software according to the terms and conditions of the Mulan PSL v2. ++* You may obtain a copy of Mulan PSL v2 at: ++* http://license.coscl.org.cn/MulanPSL2 ++* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++* PURPOSE. ++* See the Mulan PSL v2 for more details. ++*/ ++ ++#include ++ ++#include "lwip/sockets.h" ++#include "lstack_ethdev.h" ++#include "lstack_log.h" ++#include "gazelle_opt.h" ++#include "lstack_protocol_stack.h" ++#include "lstack_tx_cache.h" ++ ++#define TX_CACHE_MAX 128 ++#define TX_CACHE_MASK (TX_CACHE_MAX - 1) ++#define TX_CACHE_INDEX(index) ((index) & TX_CACHE_MASK) ++ ++struct tx_cache { ++ uint16_t port_id; ++ uint16_t queue_id; ++ ++ uint32_t send_start; ++ uint32_t send_end; ++ struct rte_mbuf *send_pkts[TX_CACHE_MAX]; ++ ++ uint64_t send_pkts_fail; ++ void *priv; ++}; ++struct lstack_dev_ops g_tx_cache_dev_ops; ++ ++static uint32_t tx_cache_recv(struct protocol_stack *stack, struct rte_mbuf **pkts, uint32_t nr_pkts); ++ ++struct tx_cache *g_tx_cache[PROTOCOL_STACK_MAX]; ++ ++int tx_cache_init(uint16_t queue_id, void *priv, struct lstack_dev_ops *dev_ops) ++{ ++ struct tx_cache *tx_cache = calloc(1, sizeof(struct tx_cache)); ++ if (tx_cache == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "queue(%d) tx cache init failed\n", queue_id); ++ } ++ ++ tx_cache->queue_id = queue_id; ++ tx_cache->priv = priv; ++ g_tx_cache[queue_id] = tx_cache; ++ ++ g_tx_cache_dev_ops.tx_xmit = dev_ops->tx_xmit; ++ dev_ops->tx_xmit = tx_cache_recv; ++ ++ return 0; ++} ++ ++int tx_cache_send(uint16_t queue_id) ++{ ++ struct tx_cache *tx_cache = g_tx_cache[queue_id]; ++ if (tx_cache == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "queue(%d) tx cache get failed\n", queue_id); ++ return 0; ++ } ++ ++ uint32_t send_num = tx_cache->send_end - tx_cache->send_start; ++ if (send_num == 0) { ++ return 0; ++ } ++ ++ uint32_t start = tx_cache->send_start & TX_CACHE_MASK; ++ uint32_t end = tx_cache->send_end & TX_CACHE_MASK; ++ uint32_t sent_pkts = 0; ++ if (start < end) { ++ sent_pkts = g_tx_cache_dev_ops.tx_xmit(tx_cache->priv, &tx_cache->send_pkts[start], send_num); ++ } else { ++ send_num = TX_CACHE_MAX - start; ++ sent_pkts = g_tx_cache_dev_ops.tx_xmit(tx_cache->priv, &tx_cache->send_pkts[start], send_num); ++ if (sent_pkts == send_num) { ++ sent_pkts += g_tx_cache_dev_ops.tx_xmit(tx_cache->priv, tx_cache->send_pkts, end); ++ } ++ } ++ ++ tx_cache->send_start += sent_pkts; ++ return sent_pkts; ++} ++ ++static uint32_t tx_cache_recv(struct protocol_stack *stack, struct rte_mbuf **pkts, uint32_t nr_pkts) ++{ ++ if (nr_pkts != 1) { ++ LSTACK_LOG(ERR, LSTACK, "arg not support, nr_pkts is %d\n", nr_pkts); ++ return 0; ++ } ++ uint16_t queue_id = stack->queue_id; ++ struct tx_cache *tx_cache = g_tx_cache[queue_id]; ++ if (tx_cache == NULL) { ++ LSTACK_LOG(ERR, LSTACK, "queue(%d) tx cache get failed\n", queue_id); ++ return 0; ++ } ++ ++ do { ++ if (TX_CACHE_INDEX(tx_cache->send_end + 1) != TX_CACHE_INDEX(tx_cache->send_start)) { ++ tx_cache->send_pkts[TX_CACHE_INDEX(tx_cache->send_end)] = pkts[0]; ++ tx_cache->send_end++; ++ return nr_pkts; ++ } ++ ++ tx_cache_send(queue_id); ++ } while (1); ++ ++ return 0; ++} +-- +2.33.0 + diff --git a/0195-virtio-create-and-init-virtio_port.patch b/0195-virtio-create-and-init-virtio_port.patch new file mode 100644 index 0000000..0c7706a --- /dev/null +++ b/0195-virtio-create-and-init-virtio_port.patch @@ -0,0 +1,392 @@ +From 696cd69752032e55ef301f3eb4f7ad42693137ab Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Mon, 17 Jun 2024 14:33:50 +0800 +Subject: [PATCH] [virtio]: create and init virtio_port + +--- + src/lstack/core/dir.mk | 2 +- + src/lstack/core/lstack_dpdk.c | 6 +- + src/lstack/core/lstack_port_map.c | 43 ++++++ + src/lstack/core/lstack_virtio.c | 201 +++++++++++++++++++++++++++ + src/lstack/include/lstack_port_map.h | 20 +++ + src/lstack/include/lstack_virtio.h | 36 +++++ + 6 files changed, 306 insertions(+), 2 deletions(-) + create mode 100644 src/lstack/core/lstack_port_map.c + create mode 100644 src/lstack/core/lstack_virtio.c + create mode 100644 src/lstack/include/lstack_port_map.h + create mode 100644 src/lstack/include/lstack_virtio.h + +diff --git a/src/lstack/core/dir.mk b/src/lstack/core/dir.mk +index e2d10a5..21b0d22 100644 +--- a/src/lstack/core/dir.mk ++++ b/src/lstack/core/dir.mk +@@ -8,6 +8,6 @@ + # PURPOSE. + # See the Mulan PSL v2 for more details. + +-SRC = lstack_preload.c lstack_init.c lstack_cfg.c lstack_dpdk.c lstack_control_plane.c lstack_stack_stat.c lstack_lwip.c lstack_protocol_stack.c lstack_thread_rpc.c ++SRC = lstack_preload.c lstack_init.c lstack_cfg.c lstack_dpdk.c lstack_control_plane.c lstack_stack_stat.c lstack_lwip.c lstack_protocol_stack.c lstack_thread_rpc.c lstack_virtio.c lstack_port_map.c + $(eval $(call register_dir, core, $(SRC))) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 785431f..b0d76bf 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -49,6 +49,7 @@ + #include "lstack_thread_rpc.h" + #include "lstack_lwip.h" + #include "lstack_cfg.h" ++#include "lstack_virtio.h" + #include "lstack_dpdk.h" + + struct eth_params { +@@ -771,7 +772,7 @@ int32_t init_dpdk_ethdev(void) + { + int32_t ret; + int slave_port_id[GAZELLE_MAX_BOND_NUM] = {-1}; +- int port_id; ++ int port_id = 0; + struct cfg_params *cfg = get_global_cfg_params(); + int i; + +@@ -813,6 +814,9 @@ int32_t init_dpdk_ethdev(void) + } + } + #endif ++ if (get_global_cfg_params()->flow_bifurcation && virtio_port_create(port_id) != 0) { ++ return -1; ++ } + + return 0; + } +diff --git a/src/lstack/core/lstack_port_map.c b/src/lstack/core/lstack_port_map.c +new file mode 100644 +index 0000000..e5008b3 +--- /dev/null ++++ b/src/lstack/core/lstack_port_map.c +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++ * gazelle is licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#include ++#include ++#include "lstack_port_map.h" ++ ++#define PORT_MAP_UNIX_TCP_PORT_MAX 65535 ++#define PORT_MAP_EIGHT_BIT 8 ++ ++static uint8_t g_rule_port[(PORT_MAP_UNIX_TCP_PORT_MAX + 1) / PORT_MAP_EIGHT_BIT]; // 8k byte ++static pthread_mutex_t g_rule_map_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void port_map_set(uint32_t modBit, int setVal) ++{ ++ pthread_mutex_lock(&g_rule_map_mutex); ++ g_rule_port[modBit / PORT_MAP_EIGHT_BIT] &= ~(1 << (modBit % PORT_MAP_EIGHT_BIT)); ++ g_rule_port[modBit / PORT_MAP_EIGHT_BIT] |= (setVal << (modBit % PORT_MAP_EIGHT_BIT)); ++ pthread_mutex_unlock(&g_rule_map_mutex); ++} ++ ++int port_map_get(int bit_index) ++{ ++ int bit_val = 0; ++ int byte_index = bit_index / PORT_MAP_EIGHT_BIT; ++ int bit_offset = bit_index % PORT_MAP_EIGHT_BIT; ++ uint8_t mask = 1 << bit_offset; ++ pthread_mutex_lock(&g_rule_map_mutex); ++ if ((g_rule_port[byte_index] & mask) != 0) { ++ bit_val = 1; ++ } ++ pthread_mutex_unlock(&g_rule_map_mutex); ++ return bit_val; ++} +\ No newline at end of file +diff --git a/src/lstack/core/lstack_virtio.c b/src/lstack/core/lstack_virtio.c +new file mode 100644 +index 0000000..810e343 +--- /dev/null ++++ b/src/lstack/core/lstack_virtio.c +@@ -0,0 +1,201 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++ * gazelle is licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++#include ++#include "lstack_cfg.h" ++#include "lstack_log.h" ++#include "lstack_port_map.h" ++#include "lstack_virtio.h" ++ ++#define VIRTIO_USER_NAME "virtio_user0" ++#define VIRTIO_DPDK_PARA_LEN 256 ++#define VIRTIO_TX_RX_RING_SIZE 1024 ++ ++static struct virtio_instance g_virtio_instance = {0}; ++ ++struct virtio_instance* virtio_instance_get(void) ++{ ++ return &g_virtio_instance; ++} ++ ++static int virtio_set_ipv6_addr(void) ++{ ++ return 0; ++} ++ ++static int virtio_cfg_ip(void) ++{ ++ // set ipv4 adr() ++ ++ // set ipv6 addr ++ virtio_set_ipv6_addr(); ++ return 0; ++} ++ ++void virtio_tap_process_rx(uint16_t port, uint32_t queue_id) ++{ ++ struct rte_mbuf *pkts_burst[VIRTIO_TX_RX_RING_SIZE]; ++ uint16_t lstack_net_port = port; ++ uint32_t pkg_num; ++ ++ pkg_num = rte_eth_rx_burst(g_virtio_instance.virtio_port_id, queue_id, pkts_burst, VIRTIO_TX_RX_RING_SIZE); ++ if (pkg_num > 0) { ++ g_virtio_instance.rx_pkg[queue_id] += pkg_num; ++ uint16_t nb_rx = rte_eth_tx_burst(lstack_net_port, queue_id, pkts_burst, pkg_num); ++ for (uint16_t i = nb_rx; i < pkg_num; ++i) { ++ rte_pktmbuf_free(pkts_burst[i]); ++ g_virtio_instance.rx_drop[queue_id]++; ++ } ++ } ++} ++ ++void virtio_tap_process_tx(uint16_t queue_id, struct rte_mbuf *mbuf_copy) ++{ ++ int tx_num = rte_eth_tx_burst(g_virtio_instance.virtio_port_id, queue_id, &(mbuf_copy), 1); ++ if (tx_num < 0) { ++ rte_pktmbuf_free(mbuf_copy); ++ g_virtio_instance.tx_drop[queue_id]++; ++ LSTACK_LOG(ERR, LSTACK, "virtio_tap_process_tx failed %d, %d\n", queue_id, tx_num); ++ } ++ g_virtio_instance.tx_pkg[queue_id]++; ++} ++ ++static int virtio_port_init(uint16_t port) ++{ ++ int retval; ++ uint16_t rx_queue_num = g_virtio_instance.rx_queue_num; ++ uint16_t tx_queue_num = g_virtio_instance.tx_queue_num; ++ ++ LSTACK_LOG(INFO, LSTACK, "virtio_port_init port= %u rx_queue_num=%u tx_queue_num=%u \n", ++ port, rx_queue_num, tx_queue_num); ++ ++ struct rte_eth_conf port_conf; ++ memset(&port_conf, 0, sizeof(struct rte_eth_conf)); ++ ++ struct rte_eth_dev_info dev_info; ++ retval = rte_eth_dev_info_get(port, &dev_info); ++ if (retval != 0) { ++ LSTACK_LOG(ERR, LSTACK, "rte_eth_dev_info_get failed(port %u) info: %d\n", port, retval); ++ return retval; ++ } ++ ++ retval = rte_eth_dev_configure(port, rx_queue_num, tx_queue_num, &port_conf); ++ if (retval != 0) { ++ LSTACK_LOG(ERR, LSTACK, "rte_eth_dev_configure failed retval=%d\n", retval); ++ return retval; ++ } ++ ++ for (uint16_t q = 0; q < tx_queue_num; q++) { ++ retval = rte_eth_tx_queue_setup(port, q, VIRTIO_TX_RX_RING_SIZE, rte_eth_dev_socket_id(port), NULL); ++ if (retval < 0) { ++ LSTACK_LOG(ERR, LSTACK, "rte_eth_tx_queue_setup failed (queue %u) retval=%d \n", q, retval); ++ return retval; ++ } ++ } ++ ++ for (uint16_t q = 0; q < rx_queue_num; q++) { ++ struct rte_mempool *rxtx_mbuf_pool = get_protocol_stack_group()->total_rxtx_pktmbuf_pool[q]; ++ retval = rte_eth_rx_queue_setup(port, q, VIRTIO_TX_RX_RING_SIZE, rte_eth_dev_socket_id(port), ++ NULL, rxtx_mbuf_pool); ++ if (retval < 0) { ++ LSTACK_LOG(ERR, LSTACK, "rte_eth_rx_queue_setup failed (queue %u) retval=%d \n", q, retval); ++ return retval; ++ } ++ } ++ return 0; ++} ++ ++static int32_t virtio_port_start(uint16_t virtio_port) ++{ ++ int retval = 0; ++ if (virtio_port_init(virtio_port) < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_port_init failed \n"); ++ return -1; ++ } ++ ++ retval = rte_eth_dev_start(virtio_port); ++ if (retval < 0) { ++ LSTACK_LOG(ERR, LSTACK, "rte_eth_dev_start failed retval=%d\n", retval); ++ return retval; ++ } ++ ++ if (virtio_cfg_ip() != 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_cfg_ip_mac failed\n"); ++ return -1; ++ } ++ LSTACK_LOG(INFO, LSTACK, "virtio_user lstack_net_port=%u virtio_port=%u rx_queue_num = %u tx_queue_num = %u\n", ++ g_virtio_instance.lstack_port_id, g_virtio_instance.virtio_port_id, ++ g_virtio_instance.rx_queue_num, g_virtio_instance.tx_queue_num); ++ return 0; ++} ++int virtio_port_create(int lstack_net_port) ++{ ++ char portargs[VIRTIO_DPDK_PARA_LEN] = {0}; ++ ++ struct rte_ether_addr addr; ++ uint16_t virtio_port_id = 0xffff; // invalid val ++ ++ struct rte_eth_dev_info dev_info; ++ int ret = rte_eth_dev_info_get(lstack_net_port, &dev_info); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "get dev info ret=%d\n", ret); ++ return ret; ++ } ++ ++ g_virtio_instance.rx_queue_num = dev_info.nb_rx_queues; ++ g_virtio_instance.tx_queue_num = dev_info.nb_tx_queues; ++ ++ if (g_virtio_instance.rx_queue_num > VIRTIO_MAX_QUEUE_NUM || ++ g_virtio_instance.tx_queue_num > VIRTIO_MAX_QUEUE_NUM) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_port_create failed queue_num (%u %u) is bigger than %u\n", ++ g_virtio_instance.rx_queue_num, g_virtio_instance.tx_queue_num, VIRTIO_MAX_QUEUE_NUM); ++ return -1; ++ } ++ ++ int retval = rte_eth_macaddr_get(lstack_net_port, &addr); // virtio_user0'mac is same with lstack.conf MAC addr ++ if (retval != 0) { ++ LSTACK_LOG(ERR, LSTACK, " rte_eth_macaddr_get failed ret = %d\n", retval); ++ return retval; ++ } ++ ++ retval = snprintf(portargs, sizeof(portargs), ++ "path=/dev/vhost-net,queues=%u,queue_size=%u,iface=%s,mac=" RTE_ETHER_ADDR_PRT_FMT, ++ VIRTIO_MAX_QUEUE_NUM, VIRTIO_TX_RX_RING_SIZE, VIRTIO_USER_NAME, RTE_ETHER_ADDR_BYTES(&addr)); ++ if (retval < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio portargs snprintf failed ret=%d \n", retval); ++ return retval; ++ } ++ LSTACK_LOG(INFO, LSTACK, "virtio portargs=%s \n", portargs); ++ ++ retval = rte_eal_hotplug_add("vdev", VIRTIO_USER_NAME, portargs); ++ if (retval < 0) { ++ LSTACK_LOG(ERR, LSTACK, "rte_eal_hotplug_add failed retval=%d : %s\n", retval, strerror(-retval)); ++ return retval; ++ } ++ ++ retval = rte_eth_dev_get_port_by_name(VIRTIO_USER_NAME, &virtio_port_id); ++ if (retval != 0) { ++ rte_eal_hotplug_remove("vdev", VIRTIO_USER_NAME); ++ LSTACK_LOG(ERR, LSTACK, "virtio_user0 not found\n"); ++ return -1; ++ } ++ ++ g_virtio_instance.virtio_port_id = virtio_port_id; ++ g_virtio_instance.lstack_port_id = lstack_net_port; ++ ++ retval = virtio_port_start(virtio_port_id); ++ if (retval != 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_port_start failed ret=%d\n", retval); ++ rte_eal_hotplug_remove("vdev", VIRTIO_USER_NAME); ++ return retval; ++ } ++ return 0; ++} +\ No newline at end of file +diff --git a/src/lstack/include/lstack_port_map.h b/src/lstack/include/lstack_port_map.h +new file mode 100644 +index 0000000..24ef53a +--- /dev/null ++++ b/src/lstack/include/lstack_port_map.h +@@ -0,0 +1,20 @@ ++/* ++ * 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_PORT_MAP_H__ ++#define __LSTACK_PORT_MAP_H__ ++ ++#include ++ ++void port_map_set(uint32_t modBit, int setVal); ++int port_map_get(int bit_index); ++ ++#endif +\ No newline at end of file +diff --git a/src/lstack/include/lstack_virtio.h b/src/lstack/include/lstack_virtio.h +new file mode 100644 +index 0000000..5e001ca +--- /dev/null ++++ b/src/lstack/include/lstack_virtio.h +@@ -0,0 +1,36 @@ ++/* ++ * 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_VIRTIO_H__ ++#define __LSTACK_VIRTIO_H__ ++ ++#include ++ ++#define VIRTIO_MAX_QUEUE_NUM 8 ++struct virtio_instance { ++ uint16_t lstack_port_id; ++ uint16_t virtio_port_id; ++ uint16_t rx_queue_num; ++ uint16_t tx_queue_num; ++ ++ uint64_t rx_pkg[VIRTIO_MAX_QUEUE_NUM]; ++ uint64_t rx_drop[VIRTIO_MAX_QUEUE_NUM]; ++ uint64_t tx_pkg[VIRTIO_MAX_QUEUE_NUM]; ++ uint64_t tx_drop[VIRTIO_MAX_QUEUE_NUM]; ++}; ++ ++void virtio_tap_process_rx(uint16_t port, uint32_t queue_id); ++void virtio_tap_process_tx(uint16_t queue_id, struct rte_mbuf *mbuf_copy); ++ ++int virtio_port_create(int lstack_net_port); ++ ++struct virtio_instance* virtio_instance_get(void); ++#endif +\ No newline at end of file +-- +2.33.0 + diff --git a/gazelle.spec b/gazelle.spec index c1684d7..6da2f74 100644 --- a/gazelle.spec +++ b/gazelle.spec @@ -2,7 +2,7 @@ Name: gazelle Version: 1.0.2 -Release: 41 +Release: 42 Summary: gazelle is a high performance user-mode stack License: MulanPSL-2.0 URL: https://gitee.com/openeuler/gazelle @@ -204,6 +204,14 @@ Patch9184: 0184-EPOLL-fix-coredump-while-event-count-exceed-maxevent.patch Patch9185: 0185-fix-fin-pack-free-coredump.patch Patch9186: 0186-fix-MySQL-shutdown-cmd.patch Patch9187: 0187-cfg-remove-map-perfect-flag-in-lstack.conf.patch +Patch9188: 0188-redis-perf-add-tx-driver-cache.patch +Patch9189: 0189-optimized-latency-distribution-dotting.patch +Patch9190: 0190-rtc-adapt-rtc_close.patch +Patch9191: 0191-virtio-flow_bifurcation-switch.patch +Patch9192: 0192-remove-legacy-mem.patch +Patch9193: 0193-cfg-bond_slave_mac-support-pci-addr.patch +Patch9194: 0194-refactor-tx-cache-module.patch +Patch9195: 0195-virtio-create-and-init-virtio_port.patch %description %{name} is a high performance user-mode stack. @@ -244,6 +252,16 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b %config(noreplace) %{conf_path}/ltran.conf %changelog +* Fri Jun 21 2024 yinbin6 - 1.0.2-42 +- [virtio]: create and init virtio_port +- refactor tx cache module +- cfg: bond_slave_mac support pci addr +- remove legacy-mem +- [virtio]: flow_bifurcation switch +- rtc: adapt rtc_close +- optimized latency distribution dotting +- redis perf: add tx driver cache + * Fri Jun 14 2024 yinbin6 - 1.0.2-41 - cfg: remove map-perfect flag in lstack.conf - fix MySQL shutdown cmd