diff --git a/0199-perftool-add-latency-tool.patch b/0199-perftool-add-latency-tool.patch new file mode 100644 index 0000000..7bf1e21 --- /dev/null +++ b/0199-perftool-add-latency-tool.patch @@ -0,0 +1,57 @@ +From a037f2d9d92ea4a5e659297c5c9839557040f1ce Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Fri, 21 Jun 2024 16:48:20 +0800 +Subject: [PATCH] perftool: add latency tool + +--- + tools/perf/latency.bt | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + create mode 100755 tools/perf/latency.bt + +diff --git a/tools/perf/latency.bt b/tools/perf/latency.bt +new file mode 100755 +index 0000000..bfe18ae +--- /dev/null ++++ b/tools/perf/latency.bt +@@ -0,0 +1,38 @@ ++#!/usr/bin/env bpftrace ++/* ++reference: https://github.com/bpftrace/bpftrace/blob/master/man/adoc/bpftrace.adoc ++prepare: yum install bpftrace ++example: ./latency.bt xxx.so func1 func2 ++supported functions: bpftrace -l 'uprobe:xxx.so' ++*/ ++ ++BEGIN ++{ ++} ++ ++uprobe:$1:$2 ++{ ++ @t_start[tid] = nsecs; ++} ++ ++uretprobe:$1:$3 ++/@t_start[tid]/ ++{ ++ $t_dur = nsecs - @t_start[tid]; ++ @t_avg = avg($t_dur); ++ ++ //@t_hist = lhist($t_dur, 0, 4000, 100); ++ @t_hist = hist($t_dur); ++ ++ delete(@t_start[tid]); ++} ++ ++END ++{ ++ printf("\n\n%s -> %s \n", str($2), str($3)); ++ printf("average time(nsec):"); ++ print(@t_avg); ++ ++ clear(@t_avg); ++ clear(@t_start); ++} +-- +2.33.0 + diff --git a/0200-cfg-del-unnecessary-logs.patch b/0200-cfg-del-unnecessary-logs.patch new file mode 100644 index 0000000..b1f8f23 --- /dev/null +++ b/0200-cfg-del-unnecessary-logs.patch @@ -0,0 +1,88 @@ +From b83a8ba5bb2f7f689cbdb404d3352bd039def160 Mon Sep 17 00:00:00 2001 +From: yangchen +Date: Thu, 20 Jun 2024 16:58:38 +0800 +Subject: [PATCH] cfg: del unnecessary logs + +--- + src/lstack/core/lstack_cfg.c | 24 ++---------------------- + 1 file changed, 2 insertions(+), 22 deletions(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index a1afe70..a5918f1 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -100,7 +100,7 @@ static int32_t parse_flow_bifurcation(void); + } \ + int32_t _val = config_setting_get_int(_config_arg); \ + if (_val < (_min_val) || _val > (_max_val)) { \ +- LSTACK_PRE_LOG(LSTACK_ERR, "cfg %s %d invaild, range is [%d, %d].\n", \ ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg %s %d invalid, range is [%d, %d].\n", \ + (_arg_string), _val, (_min_val), (_max_val)); \ + (_ret) = -EINVAL; \ + break; \ +@@ -1196,7 +1196,7 @@ static int parse_tuple_filter(void) + return 0; + } + if (g_config_params.use_ltran || g_config_params.listen_shadow) { +- LSTACK_LOG(ERR, LSTACK, "tuple filter and (ltran or listen_shadow) cannot be enabled at the same time\n"); ++ LSTACK_LOG(ERR, LSTACK, "tuple filter and (ltran or listen_shadow) cannot be enabled at the same time\n"); + return -EINVAL; + } + +@@ -1356,10 +1356,6 @@ static int32_t parse_nic_vlan_mode(void) + { + int32_t ret; + PARSE_ARG(g_config_params.nic.vlan_mode, "nic_vlan_mode", -1, -1, 4094, ret); +- if (ret != 0) { +- LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid vlan mode value %d ret=%d. only support -1~4094\n", \ +- g_config_params.nic.vlan_mode, ret); +- } + return ret; + } + +@@ -1367,10 +1363,6 @@ static int32_t parse_defaule_nonblock_mode(void) + { + int32_t ret; + PARSE_ARG(g_config_params.nonblock_mode, "nonblock_mode", 1, 0, 1, ret); +- if (ret != 0) { +- LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid nonblock mode value %d. only support 0 or 1\n", \ +- g_config_params.nonblock_mode); +- } + return ret; + } + +@@ -1378,10 +1370,6 @@ static int32_t parse_rpc_msg_max(void) + { + int32_t ret; + PARSE_ARG(g_config_params.rpc_msg_max, "rpc_msg_max", 4096, 1, 8192, ret); +- if (ret != 0) { +- LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid rpc msg max value %d ret=%d. only support 1~8192\n", +- g_config_params.rpc_msg_max, ret); +- } + return ret; + } + +@@ -1389,10 +1377,6 @@ 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; + } + +@@ -1400,9 +1384,5 @@ 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; + } +-- +2.33.0 + diff --git a/0201-fix-dpdk_bond_primary_set-bug.patch b/0201-fix-dpdk_bond_primary_set-bug.patch new file mode 100644 index 0000000..9a7f813 --- /dev/null +++ b/0201-fix-dpdk_bond_primary_set-bug.patch @@ -0,0 +1,72 @@ +From c65b58b68bf51cc09d1c2438e55d1dcb92ffd4ca Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Mon, 24 Jun 2024 10:43:50 +0800 +Subject: [PATCH] fix dpdk_bond_primary_set bug + +--- + src/lstack/core/lstack_dpdk.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index b0d76bf..6e52187 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -509,14 +509,14 @@ 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, int count) + { + int32_t primary_port_id = ethdev_port_id(get_global_cfg_params()->mac_addr); + 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++) { ++ for (int i = 0; i < count; 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) { +@@ -715,7 +715,7 @@ static int dpdk_bond_create(uint8_t mode, int *slave_port_id, int count) + } + + if (cfg->bond_mode == BONDING_MODE_ACTIVE_BACKUP) { +- ret = dpdk_bond_primary_set(port_id, slave_port_id); ++ ret = dpdk_bond_primary_set(port_id, slave_port_id, count); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk set bond primary port failed ret = %d\n", ret); + return -1; +@@ -771,7 +771,7 @@ 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] = {-1}; ++ int slave_port_id[GAZELLE_MAX_BOND_NUM]; + int port_id = 0; + struct cfg_params *cfg = get_global_cfg_params(); + int i; +@@ -785,6 +785,10 @@ int32_t init_dpdk_ethdev(void) + } else { + slave_port_id[i] = pci_to_port_id(&cfg->bond_slave_addr[i].addr.pci_addr); + } ++ if (slave_port_id[i] < 0) { ++ LSTACK_LOG(ERR, LSTACK, "cfg->bond_slave_addr[%d] parsing failed, ret=%d\n", i, ret); ++ return -1; ++ } + 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); +@@ -799,6 +803,9 @@ int32_t init_dpdk_ethdev(void) + } + } else { + port_id = ethdev_port_id(cfg->mac_addr); ++ if (port_id < 0) { ++ return -1; ++ } + ret = dpdk_ethdev_init(port_id); + if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk_ethdev_init failed, port id=%d\n", port_id); +-- +2.33.0 + diff --git a/0202-fix-build-failed-in-2003sp4.patch b/0202-fix-build-failed-in-2003sp4.patch new file mode 100644 index 0000000..d0e38cf --- /dev/null +++ b/0202-fix-build-failed-in-2003sp4.patch @@ -0,0 +1,25 @@ +From a287036099c050f91bceaeb7bd1a3b5c1b0b6af6 Mon Sep 17 00:00:00 2001 +From: yinbin6 +Date: Mon, 24 Jun 2024 20:01:58 +0800 +Subject: [PATCH] fix build failed in 2003sp4 + +--- + src/lstack/core/lstack_dpdk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 6e52187..2de41e3 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -786,7 +786,7 @@ int32_t init_dpdk_ethdev(void) + slave_port_id[i] = pci_to_port_id(&cfg->bond_slave_addr[i].addr.pci_addr); + } + if (slave_port_id[i] < 0) { +- LSTACK_LOG(ERR, LSTACK, "cfg->bond_slave_addr[%d] parsing failed, ret=%d\n", i, ret); ++ LSTACK_LOG(ERR, LSTACK, "cfg->bond_slave_addr[%d] parsing failed.\n", i); + return -1; + } + ret = dpdk_ethdev_init(slave_port_id[i]); +-- +2.33.0 + diff --git a/0203-virtio-cfg-ipv4-and-ipv6-addr.patch b/0203-virtio-cfg-ipv4-and-ipv6-addr.patch new file mode 100644 index 0000000..a2df27c --- /dev/null +++ b/0203-virtio-cfg-ipv4-and-ipv6-addr.patch @@ -0,0 +1,190 @@ +From e2bdddb748e891312aa6e2c67a44ba265ca16edf Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Fri, 21 Jun 2024 09:20:03 +0800 +Subject: [PATCH] [virtio]: cfg ipv4 and ipv6 addr + +--- + src/lstack/core/lstack_virtio.c | 140 +++++++++++++++++++++++++++++++- + 1 file changed, 136 insertions(+), 4 deletions(-) + +diff --git a/src/lstack/core/lstack_virtio.c b/src/lstack/core/lstack_virtio.c +index 810e343..c3b3511 100644 +--- a/src/lstack/core/lstack_virtio.c ++++ b/src/lstack/core/lstack_virtio.c +@@ -10,15 +10,23 @@ + * See the Mulan PSL v2 for more details. + */ + #include ++#include ++#include ++#include ++#include ++#include + #include "lstack_cfg.h" + #include "lstack_log.h" + #include "lstack_port_map.h" + #include "lstack_virtio.h" ++#include "securec.h" + + #define VIRTIO_USER_NAME "virtio_user0" + #define VIRTIO_DPDK_PARA_LEN 256 + #define VIRTIO_TX_RX_RING_SIZE 1024 + ++#define VIRTIO_MASK_BITS(mask) (32 - __builtin_clz(mask)) ++ + static struct virtio_instance g_virtio_instance = {0}; + + struct virtio_instance* virtio_instance_get(void) +@@ -28,15 +36,139 @@ struct virtio_instance* virtio_instance_get(void) + + static int virtio_set_ipv6_addr(void) + { ++ struct cfg_params *cfg = get_global_cfg_params(); ++ struct ifreq ifr; ++ memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)); ++ ++ int sockfd = posix_api->socket_fn(AF_INET6, SOCK_DGRAM, 0); ++ if (sockfd < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_set_ipv6_addr failed ret =%d errno=%d \n", sockfd, errno); ++ return -1; ++ } ++ ++ int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), VIRTIO_USER_NAME, sizeof(VIRTIO_USER_NAME)); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_set_ipv6_addr strncpy failed ret =%d errno=%d \n", ret, errno); ++ posix_api->close_fn(sockfd); ++ return -1; ++ } ++ ++ ret = posix_api->ioctl_fn(sockfd, SIOGIFINDEX, &ifr); ++ if (ret < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_set_ipv6_addr failed ret =%d errno=%d \n", ret, errno); ++ posix_api->close_fn(sockfd); ++ return -1; ++ } ++ ++ struct in6_ifreq ifr6; ++ memset_s(&ifr6, sizeof(ifr6), 0, sizeof(ifr6)); ++ ret = memcpy_s(&ifr6.ifr6_addr, sizeof(ifr6.ifr6_addr), &(cfg->host_addr6), sizeof((cfg->host_addr6.addr))); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_set_ipv6_addr memcpy_s failed ret =%d errno=%d \n", ret, errno); ++ posix_api->close_fn(sockfd); ++ return -1; ++ } ++ ++ ifr6.ifr6_ifindex = ifr.ifr_ifindex; ++ ifr6.ifr6_prefixlen = VIRTIO_MASK_BITS(cfg->netmask.addr); ++ ++ ret = posix_api->ioctl_fn(sockfd, SIOCSIFADDR, &ifr6); ++ if (ret < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_set_ipv6_addr failed err= %d errno %d \n", ret, errno); ++ posix_api->close_fn(sockfd); ++ return -1; ++ } ++ posix_api->close_fn(sockfd); ++ return 0; ++} ++ ++static int virtio_set_ipv4_addr(void) ++{ ++ int ret = 0; ++ int sockfd = posix_api->socket_fn(AF_INET, SOCK_DGRAM, 0); ++ if (sockfd < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_set_ipv6_addr failed ret= %d errno %d \n", sockfd, errno); ++ return -1; ++ } ++ ++ struct cfg_params *cfg = get_global_cfg_params(); ++ struct ifreq ifr; ++ memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)); ++ ++ ret = strcpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), VIRTIO_USER_NAME); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_set_ipv4_addr strcpy_s failed ret=%d errno %d \n", ret, errno); ++ posix_api->close_fn(sockfd); ++ return -1; ++ } ++ ++ struct sockaddr_in *addr = (struct sockaddr_in *)&ifr.ifr_addr; ++ addr->sin_family = AF_INET; ++ addr->sin_addr.s_addr = cfg->host_addr.addr; ++ ++ if (posix_api->ioctl_fn(sockfd, SIOCSIFADDR, &ifr) < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_cfg_ip failed errno %d \n", errno); ++ posix_api->close_fn(sockfd); ++ return -1; ++ } ++ ++ addr->sin_addr.s_addr = cfg->netmask.addr; ++ if (posix_api->ioctl_fn(sockfd, SIOCSIFNETMASK, &ifr) < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_cfg_ip netmask=%u fail\n", cfg->netmask.addr); ++ posix_api->close_fn(sockfd); ++ return -1; ++ } ++ posix_api->close_fn(sockfd); ++ return 0; ++} ++ ++static int virtio_netif_up(void) ++{ ++ int sockfd = posix_api->socket_fn(AF_INET, SOCK_DGRAM, 0); ++ if (sockfd < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_netif_up socket_fn failed ret= %d errno %d \n", sockfd, errno); ++ return -1; ++ } ++ ++ struct ifreq ifr; ++ memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)); ++ int ret = strcpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), VIRTIO_USER_NAME); ++ if (ret != 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_netif_up strcpy_s failed ret=%d errno %d \n", ret, errno); ++ posix_api->close_fn(sockfd); ++ return -1; ++ } ++ ++ ifr.ifr_flags |= IFF_UP; ++ if (posix_api->ioctl_fn(sockfd, SIOCSIFFLAGS, &ifr) < 0) { ++ posix_api->close_fn(sockfd); ++ LSTACK_LOG(ERR, LSTACK, " virtio_netif_up ioctl_fn failed errno= %d \n", errno); ++ return -1; ++ } ++ ++ posix_api->close_fn(sockfd); + return 0; + } + + static int virtio_cfg_ip(void) + { +- // set ipv4 adr() ++ struct cfg_params *cfg = get_global_cfg_params(); + +- // set ipv6 addr +- virtio_set_ipv6_addr(); ++ if (virtio_set_ipv4_addr() < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_set_ipv4_addr failed \n"); ++ return -1; ++ } ++ ++ if (!ip6_addr_isany(&cfg->host_addr6) && virtio_set_ipv6_addr() < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_set_ipv6_addr failed \n"); ++ return -1; ++ } ++ ++ // start virtio_user ++ if (virtio_netif_up() < 0) { ++ LSTACK_LOG(ERR, LSTACK, "virtio_netif_up failed \n"); ++ return -1; ++ } + return 0; + } + +@@ -198,4 +330,4 @@ int virtio_port_create(int lstack_net_port) + return retval; + } + return 0; +-} +\ No newline at end of file ++} +-- +2.33.0 + diff --git a/0204-parse-packages-type-in-rx_poll.patch b/0204-parse-packages-type-in-rx_poll.patch new file mode 100644 index 0000000..35a7d0f --- /dev/null +++ b/0204-parse-packages-type-in-rx_poll.patch @@ -0,0 +1,168 @@ +From c7fff9e6eb2ba6f9d71389dc43c606b55f9379ce Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Tue, 18 Jun 2024 15:33:14 +0800 +Subject: [PATCH] parse packages type in rx_poll + +--- + src/lstack/netif/lstack_ethdev.c | 28 ++++++++--- + src/lstack/netif/lstack_vdev.c | 84 ++++++++++++++++++++------------ + 2 files changed, 73 insertions(+), 39 deletions(-) + +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 45c5f9e..3bfa8af 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -130,6 +130,25 @@ void kni_handle_tx(struct rte_mbuf *mbuf) + } + #endif + ++#define IS_ARP_PKT(ptype) ((ptype & RTE_PTYPE_L2_ETHER_ARP) == RTE_PTYPE_L2_ETHER_ARP) ++#define IS_IPV4_TCP_PKT(ptype) (RTE_ETH_IS_IPV4_HDR(ptype) && \ ++ ((ptype & RTE_PTYPE_L4_TCP) == RTE_PTYPE_L4_TCP) && \ ++ ((ptype & RTE_PTYPE_L4_FRAG) != RTE_PTYPE_L4_FRAG) && \ ++ (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) ++ ++#define IS_IPV6_TCP_PKT(ptype) (RTE_ETH_IS_IPV6_HDR(ptype) && \ ++ ((ptype & RTE_PTYPE_L4_TCP) == RTE_PTYPE_L4_TCP) && \ ++ ((ptype & RTE_PTYPE_L4_FRAG) != RTE_PTYPE_L4_FRAG) && \ ++ (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) ++ ++#define IS_IPV4_UDP_PKT(ptype) (RTE_ETH_IS_IPV4_HDR(ptype) && \ ++ ((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \ ++ (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) ++ ++#define IS_IPV6_UDP_PKT(ptype) (RTE_ETH_IS_IPV6_HDR(ptype) && \ ++ ((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \ ++ (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) ++ + int32_t eth_dev_poll(void) + { + uint32_t nr_pkts; +@@ -151,14 +170,7 @@ int32_t eth_dev_poll(void) + int transfer_type = TRANSFER_CURRENT_THREAD; + /* copy arp into other stack */ + if (!use_ltran()) { +- struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(stack->pkts[i], struct rte_ether_hdr *); +- u16_t type; +- type = ethh->ether_type; +- if (type == PP_HTONS(ETHTYPE_VLAN)) { +- struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr *)(((char *)ethh) + SIZEOF_ETH_HDR); +- type = vlan->tpid; +- } +- if (unlikely(RTE_BE16(RTE_ETHER_TYPE_ARP) == type)) { ++ if (unlikely(IS_ARP_PKT(stack->pkts[i]->packet_type))) { + stack_broadcast_arp(stack->pkts[i], stack); + /* copy arp into other process */ + transfer_arp_to_other_process(stack->pkts[i]); +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index 107ee8c..5ce69a9 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -72,6 +72,58 @@ static uint32_t ltran_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pk + return rcvd_pkts; + } + ++static inline void vdev_pkts_parse(struct rte_mbuf **pkts, int pkt_num) ++{ ++ for (int i = 0; i < pkt_num; i++) { ++ struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(pkts[i], struct rte_ether_hdr *); ++ u16_t type = ethh->ether_type; ++ if (type == RTE_BE16(RTE_ETHER_TYPE_VLAN)) { ++ struct rte_vlan_hdr *vlan = (struct rte_vlan_hdr *)(ethh + 1); ++ type = vlan->eth_proto; ++ pkts[i]->l2_len = sizeof(struct rte_ether_hdr) + sizeof(struct rte_vlan_hdr); ++ } else { ++ pkts[i]->l2_len = sizeof(struct rte_ether_hdr); ++ } ++ ++ if (type == RTE_BE16(RTE_ETHER_TYPE_IPV4)) { ++ struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(pkts[i], struct rte_ipv4_hdr *, ++ pkts[i]->l2_len); ++ if (unlikely((iph->version_ihl & IPV4_MASK) != IPV4_VERION)) { ++ continue; ++ } ++ pkts[i]->l3_len = sizeof(struct rte_ipv4_hdr); ++ if (iph->next_proto_id == IPPROTO_TCP) { ++ struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *, ++ pkts[i]->l2_len + pkts[i]->l3_len); ++ pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr); ++ ++ pkts[i]->packet_type = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP; ++ } else if (iph->next_proto_id == IPPROTO_UDP) { ++ pkts[i]->l4_len = sizeof(struct rte_udp_hdr); ++ pkts[i]->packet_type = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP; ++ } ++ ++ } else if (type == RTE_BE16(RTE_ETHER_TYPE_IPV6)) { ++ struct rte_ipv6_hdr *iph6 = rte_pktmbuf_mtod_offset(pkts[i], struct rte_ipv6_hdr *, ++ pkts[i]->l2_len); ++ pkts[i]->l3_len = sizeof(struct rte_ipv6_hdr); ++ if (iph6->proto == IPPROTO_TCP) { ++ struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *, ++ pkts[i]->l2_len + pkts[i]->l3_len); ++ pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr); ++ pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP; ++ } else if (iph6->proto == IPPROTO_UDP) { ++ pkts[i]->l4_len = sizeof(struct rte_udp_hdr); ++ pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP; ++ } ++ } else if (type == RTE_BE16(RTE_ETHER_TYPE_ARP)) { ++ pkts[i]->packet_type = RTE_PTYPE_L2_ETHER_ARP; ++ } else { ++ continue; ++ } ++ } ++} ++ + static uint32_t vdev_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pkts, uint32_t max_mbuf) + { + struct rte_gro_param gro_param = { +@@ -82,6 +134,7 @@ static uint32_t vdev_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pkt + }; + + uint32_t pkt_num = rte_eth_rx_burst(stack->port_id, stack->queue_id, pkts, max_mbuf); ++ vdev_pkts_parse(pkts, pkt_num); + if (pkt_num <= 1) { + return pkt_num; + } +@@ -92,37 +145,6 @@ static uint32_t vdev_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pkt + return pkt_num; + } + +- for (uint32_t i = 0; i < pkt_num; i++) { +- struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(pkts[i], struct rte_ether_hdr *); +- u16_t type = ethh->ether_type; +- +- pkts[i]->l2_len = sizeof(struct rte_ether_hdr); +- +- if (type == RTE_BE16(RTE_ETHER_TYPE_IPV4)) { +- struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(pkts[i], struct rte_ipv4_hdr *, +- sizeof(struct rte_ether_hdr)); +- if (unlikely((iph->version_ihl & IPV4_MASK) != IPV4_VERION)) { +- continue; +- } +- pkts[i]->l3_len = sizeof(struct rte_ipv4_hdr); +- +- struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *, +- sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)); +- pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr); +- +- pkts[i]->packet_type = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP; +- } else if (type == RTE_BE16(RTE_ETHER_TYPE_IPV6)) { +- pkts[i]->l3_len = sizeof(struct rte_ipv6_hdr); +- +- struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *, +- sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv6_hdr)); +- pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr); +- +- pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP; +- } else { +- continue; +- } +- } + pkt_num = rte_gro_reassemble_burst(pkts, pkt_num, &gro_param); + + return pkt_num; +-- +2.33.0 + diff --git a/0205-virtio-distribute-pkg-by-dst_port.patch b/0205-virtio-distribute-pkg-by-dst_port.patch new file mode 100644 index 0000000..77e8204 --- /dev/null +++ b/0205-virtio-distribute-pkg-by-dst_port.patch @@ -0,0 +1,198 @@ +From a86ef865f47b99b41e426e621cb3b5e3416a70ff Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Thu, 27 Jun 2024 19:53:07 +0800 +Subject: [PATCH] [virtio]: distribute pkg by dst_port + +--- + src/lstack/core/lstack_protocol_stack.c | 27 ++++++++++++++---- + src/lstack/core/lstack_virtio.c | 9 ++++++ + src/lstack/include/lstack_virtio.h | 2 ++ + src/lstack/netif/lstack_ethdev.c | 37 +++++++++++++++++++++++-- + src/lstack/netif/lstack_vdev.c | 2 ++ + 5 files changed, 68 insertions(+), 9 deletions(-) + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index d6e3c86..e272a04 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -34,6 +34,7 @@ + #include "lstack_control_plane.h" + #include "posix/lstack_epoll.h" + #include "lstack_stack_stat.h" ++#include "lstack_virtio.h" + #include "lstack_protocol_stack.h" + + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) +@@ -509,6 +510,9 @@ int stack_polling(uint32_t wakeup_tick) + } + } + #endif ++ if (get_global_cfg_params()->flow_bifurcation) { ++ virtio_tap_process_rx(stack->port_id, stack->queue_id); ++ } + return force_quit; + } + +@@ -979,14 +983,25 @@ void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack + } + } + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) +- ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); +- if (ret != 0) { +- cur_stack->stats.rx_allocmbuf_fail++; +- return; ++ if (get_global_cfg_params()->kni_switch) { ++ ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); ++ if (ret != 0) { ++ cur_stack->stats.rx_allocmbuf_fail++; ++ return; ++ } ++ copy_mbuf(mbuf_copy, mbuf); ++ kni_handle_tx(mbuf_copy); + } +- copy_mbuf(mbuf_copy, mbuf); +- kni_handle_tx(mbuf_copy); + #endif ++ if (get_global_cfg_params()->flow_bifurcation) { ++ ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); ++ if (ret != 0) { ++ cur_stack->stats.rx_allocmbuf_fail++; ++ return; ++ } ++ copy_mbuf(mbuf_copy, mbuf); ++ virtio_tap_process_tx(stack->queue_id, mbuf_copy); ++ } + return; + } + +diff --git a/src/lstack/core/lstack_virtio.c b/src/lstack/core/lstack_virtio.c +index c3b3511..ad3088d 100644 +--- a/src/lstack/core/lstack_virtio.c ++++ b/src/lstack/core/lstack_virtio.c +@@ -331,3 +331,12 @@ int virtio_port_create(int lstack_net_port) + } + return 0; + } ++ ++bool virtio_distribute_pkg_to_kernel(uint16_t dst_port) ++{ ++ if (dst_port == VIRTIO_PORT_INVALID) { ++ return false; ++ } ++ ++ return (port_map_get(dst_port) == 0); ++} +\ No newline at end of file +diff --git a/src/lstack/include/lstack_virtio.h b/src/lstack/include/lstack_virtio.h +index d40c754..615d9c9 100644 +--- a/src/lstack/include/lstack_virtio.h ++++ b/src/lstack/include/lstack_virtio.h +@@ -14,6 +14,7 @@ + + #include + ++#define VIRTIO_PORT_INVALID 0xffff + #define VIRTIO_MAX_QUEUE_NUM 8 + + // RTE_ETHER_ADDR_PRT_FMT RTE_ETHER_ADDR_BYTES are defined in dpdk 21.11 +@@ -48,4 +49,5 @@ 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); ++bool virtio_distribute_pkg_to_kernel(uint16_t dst_port); + #endif +\ No newline at end of file +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 3bfa8af..933c3e8 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -35,6 +35,7 @@ + #include "lstack_thread_rpc.h" + #include "lstack_flow.h" + #include "lstack_tx_cache.h" ++#include "lstack_virtio.h" + #include "lstack_ethdev.h" + + /* FRAME_MTU + 14byte header */ +@@ -149,6 +150,25 @@ void kni_handle_tx(struct rte_mbuf *mbuf) + ((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \ + (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) + ++#define IS_ICMPV6_PKT(ptype) (RTE_ETH_IS_IPV6_HDR(ptype) && \ ++ ((ptype & RTE_PTYPE_L4_ICMP) == RTE_PTYPE_L4_ICMP) && \ ++ (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) ++ ++static uint16_t eth_dev_get_dst_port(struct rte_mbuf *pkt) ++{ ++ uint16_t dst_port = VIRTIO_PORT_INVALID; ++ uint32_t packet_type = pkt->packet_type; ++ ++ void *l4_hdr = rte_pktmbuf_mtod_offset(pkt, void *, pkt->l2_len + pkt->l3_len); ++ ++ if (IS_IPV4_TCP_PKT(packet_type) || IS_IPV6_TCP_PKT(packet_type)) { ++ dst_port = rte_be_to_cpu_16(((struct rte_tcp_hdr *)l4_hdr)->dst_port); ++ } else if (IS_IPV4_UDP_PKT(packet_type) || IS_IPV6_UDP_PKT(packet_type)) { ++ dst_port = rte_be_to_cpu_16(((struct rte_udp_hdr *)l4_hdr)->dst_port); ++ } ++ return dst_port; ++} ++ + int32_t eth_dev_poll(void) + { + uint32_t nr_pkts; +@@ -170,7 +190,8 @@ int32_t eth_dev_poll(void) + int transfer_type = TRANSFER_CURRENT_THREAD; + /* copy arp into other stack */ + if (!use_ltran()) { +- if (unlikely(IS_ARP_PKT(stack->pkts[i]->packet_type))) { ++ if (unlikely(IS_ARP_PKT(stack->pkts[i]->packet_type)) || ++ unlikely(IS_ICMPV6_PKT(stack->pkts[i]->packet_type))) { + stack_broadcast_arp(stack->pkts[i], stack); + /* copy arp into other process */ + transfer_arp_to_other_process(stack->pkts[i]); +@@ -178,17 +199,27 @@ int32_t eth_dev_poll(void) + if (get_global_cfg_params()->tuple_filter && stack->queue_id == 0) { + transfer_type = distribute_pakages(stack->pkts[i]); + } ++ if (get_global_cfg_params()->flow_bifurcation) { ++ uint16_t dst_port = eth_dev_get_dst_port(stack->pkts[i]); ++ if (virtio_distribute_pkg_to_kernel(dst_port)) { ++ transfer_type = TRANSFER_KERNEL; ++ } ++ } + } + } + + if (likely(transfer_type == TRANSFER_CURRENT_THREAD)) { + eth_dev_recv(stack->pkts[i], stack); + } else if (transfer_type == TRANSFER_KERNEL) { ++ if (get_global_cfg_params()->flow_bifurcation) { ++ virtio_tap_process_tx(stack->queue_id, stack->pkts[i]); ++ } else { + #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) +- kni_handle_tx(stack->pkts[i]); ++ kni_handle_tx(stack->pkts[i]); + #else +- rte_pktmbuf_free(stack->pkts[i]); ++ rte_pktmbuf_free(stack->pkts[i]); + #endif ++ } + } else { + /* transfer to other thread */ + } +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index 5ce69a9..cb3953e 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -115,6 +115,8 @@ static inline void vdev_pkts_parse(struct rte_mbuf **pkts, int pkt_num) + } else if (iph6->proto == IPPROTO_UDP) { + pkts[i]->l4_len = sizeof(struct rte_udp_hdr); + pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP; ++ } else if (iph6->proto == IPPROTO_ICMPV6) { ++ pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_ICMP; + } + } else if (type == RTE_BE16(RTE_ETHER_TYPE_ARP)) { + pkts[i]->packet_type = RTE_PTYPE_L2_ETHER_ARP; +-- +2.33.0 + diff --git a/0206-fix-coredump-when-get-empty-from-udp-sendring.patch b/0206-fix-coredump-when-get-empty-from-udp-sendring.patch new file mode 100644 index 0000000..c4bb923 --- /dev/null +++ b/0206-fix-coredump-when-get-empty-from-udp-sendring.patch @@ -0,0 +1,40 @@ +From 8cd5427107511b6daed9905590c2812346a3a57d Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Thu, 27 Jun 2024 19:52:02 +0800 +Subject: [PATCH] fix coredump when get empty from udp sendring + +--- + src/lstack/core/lstack_lwip.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index db948b0..3728100 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -255,17 +255,16 @@ struct pbuf *do_lwip_udp_get_from_sendring(struct lwip_sock *sock, uint16_t rema + struct pbuf *pbufs[count]; + + int actual_count = gazelle_ring_sc_dequeue(sock->send_ring, (void **)&pbufs, count); +- if (unlikely(actual_count != count)) { ++ /* it's impossible to enter this branch theoretically */ ++ if (unlikely((actual_count != count) || ++ ((actual_count != 0) && pbufs[0]->tot_len != remain_size))) { + LSTACK_LOG(ERR, LSTACK, "udp get pbuf from sendring error, expected: %d, actual: %d\n", + count, actual_count); ++ LSTACK_LOG(ERR, LSTACK, "udp get pbuf size error, expected: %d, actual: %d\n", ++ remain_size, actual_count == 0 ? 0 : pbufs[0]->tot_len); + } + +- if (unlikely(pbufs[0]->tot_len != remain_size)) { +- LSTACK_LOG(ERR, LSTACK, "udp get pbuf size error, expected: %d, actual: %d\n", +- remain_size, pbufs[0]->tot_len); +- } +- +- for (int i = 0; get_protocol_stack_group()->latency_start && i < count; i++) { ++ for (int i = 0; get_protocol_stack_group()->latency_start && i < actual_count; i++) { + calculate_lstack_latency(&sock->stack->latency, pbufs[i], GAZELLE_LATENCY_WRITE_LWIP, 0); + } + +-- +2.33.0 + diff --git a/0207-fix-poll-init-not-clear-old-fd.patch b/0207-fix-poll-init-not-clear-old-fd.patch new file mode 100644 index 0000000..f2b4d3f --- /dev/null +++ b/0207-fix-poll-init-not-clear-old-fd.patch @@ -0,0 +1,35 @@ +From 5dbdb572406e168205cb9e54b2c247e97a57c22c Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Sat, 29 Jun 2024 07:17:27 +0000 +Subject: [PATCH] fix poll init not clear old fd + +--- + src/lstack/api/lstack_epoll.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c +index 2791dd7..2ac7150 100644 +--- a/src/lstack/api/lstack_epoll.c ++++ b/src/lstack/api/lstack_epoll.c +@@ -837,14 +837,15 @@ static void poll_init(struct wakeup_poll *wakeup, struct pollfd *fds, nfds_t nfd + continue; + } + } +- wakeup->last_fds[i].fd = fd; +- wakeup->last_fds[i].events = fds[i].events; +- poll_change = 1; + + if (sock == NULL || sock->conn == NULL || CONN_TYPE_HAS_HOST(sock->conn)) { + update_kernel_poll(wakeup, i, fds + i); + } + ++ wakeup->last_fds[i].fd = fd; ++ wakeup->last_fds[i].events = fds[i].events; ++ poll_change = 1; ++ + while (sock && sock->conn) { + sock->epoll_events = fds[i].events | POLLERR; + sock->wakeup = wakeup; +-- +2.33.0 + diff --git a/0208-virtio-mode-actual_queue_num.patch b/0208-virtio-mode-actual_queue_num.patch new file mode 100644 index 0000000..fd53200 --- /dev/null +++ b/0208-virtio-mode-actual_queue_num.patch @@ -0,0 +1,29 @@ +From 0613a7275ed2ed0aefc2f8419adeaadd8fd87de9 Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Sat, 29 Jun 2024 17:35:37 +0800 +Subject: [PATCH] virtio: mode actual_queue_num + +--- + src/lstack/core/lstack_virtio.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/lstack/core/lstack_virtio.c b/src/lstack/core/lstack_virtio.c +index ad3088d..bc42bb9 100644 +--- a/src/lstack/core/lstack_virtio.c ++++ b/src/lstack/core/lstack_virtio.c +@@ -298,9 +298,11 @@ int virtio_port_create(int lstack_net_port) + return retval; + } + ++ uint16_t actual_queue_num = (g_virtio_instance.rx_queue_num < g_virtio_instance.tx_queue_num) ? ++ g_virtio_instance.rx_queue_num : g_virtio_instance.tx_queue_num; + 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)); ++ actual_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; +-- +2.33.0 + diff --git a/0209-virtio-update-g_rule_port-by-reg_ring_type-enum.patch b/0209-virtio-update-g_rule_port-by-reg_ring_type-enum.patch new file mode 100644 index 0000000..9833f1e --- /dev/null +++ b/0209-virtio-update-g_rule_port-by-reg_ring_type-enum.patch @@ -0,0 +1,109 @@ +From cb0c86801bc4c221ae79a284619879dc98a5464d Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Sat, 29 Jun 2024 14:46:32 +0800 +Subject: [PATCH] virtio: update g_rule_port by reg_ring_type enum + +--- + src/lstack/core/lstack_port_map.c | 25 ++++++++++++------------- + src/lstack/include/lstack_port_map.h | 4 ++-- + src/lstack/netif/lstack_vdev.c | 15 +++++++++++++++ + 3 files changed, 29 insertions(+), 15 deletions(-) + +diff --git a/src/lstack/core/lstack_port_map.c b/src/lstack/core/lstack_port_map.c +index e5008b3..5439394 100644 +--- a/src/lstack/core/lstack_port_map.c ++++ b/src/lstack/core/lstack_port_map.c +@@ -15,29 +15,28 @@ + #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 uint32_t g_rule_port[PORT_MAP_UNIX_TCP_PORT_MAX] = {0}; + static pthread_mutex_t g_rule_map_mutex = PTHREAD_MUTEX_INITIALIZER; + +-void port_map_set(uint32_t modBit, int setVal) ++void port_map_mod(uint16_t port, uint16_t flag) + { + 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)); ++ if (flag == 0) { ++ g_rule_port[port]--; ++ } else { ++ g_rule_port[port]++; ++ } + pthread_mutex_unlock(&g_rule_map_mutex); + } + +-int port_map_get(int bit_index) ++uint16_t port_map_get(uint16_t port) + { +- 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; ++ uint16_t val = 0; + pthread_mutex_lock(&g_rule_map_mutex); +- if ((g_rule_port[byte_index] & mask) != 0) { +- bit_val = 1; ++ if (g_rule_port[port] > 0) { ++ val = 1; + } + pthread_mutex_unlock(&g_rule_map_mutex); +- return bit_val; ++ return val; + } +\ No newline at end of file +diff --git a/src/lstack/include/lstack_port_map.h b/src/lstack/include/lstack_port_map.h +index 24ef53a..80955dc 100644 +--- a/src/lstack/include/lstack_port_map.h ++++ b/src/lstack/include/lstack_port_map.h +@@ -14,7 +14,7 @@ + + #include + +-void port_map_set(uint32_t modBit, int setVal); +-int port_map_get(int bit_index); ++void port_map_mod(uint16_t port, uint16_t flag); ++uint16_t port_map_get(uint16_t port); + + #endif +\ No newline at end of file +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index cb3953e..75e4acc 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -35,6 +35,8 @@ + #include "lstack_lwip.h" + #include "lstack_flow.h" + #include "lstack_vdev.h" ++#include "lstack_port_map.h" ++#include "lstack_virtio.h" + + /* INUSE_TX_PKTS_WATERMARK < VDEV_RX_QUEUE_SZ; + * USE_RX_PKTS_WATERMARK < FREE_RX_QUEUE_SZ. +@@ -197,6 +199,19 @@ int32_t vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple) + return -1; + } + ++ uint16_t local_port = ntohs(qtuple->src_port); ++ if (get_global_cfg_params()->flow_bifurcation && get_global_cfg_params()->is_primary) { ++ if (type == REG_RING_TCP_LISTEN_CLOSE || type == REG_RING_UDP_BIND_CLOSE) { // add enum type in reg_sock.h ++ port_map_mod(local_port, 0); ++ } else if (type == REG_RING_TCP_LISTEN || type == REG_RING_UDP_BIND) { ++ port_map_mod(local_port, 1); ++ } else if (type == REG_RING_TCP_CONNECT_CLOSE) { ++ port_map_mod(local_port, 0); ++ } else if (type == REG_RING_TCP_CONNECT) { ++ port_map_mod(local_port, 1); ++ } ++ } ++ + if (!use_ltran() && get_global_cfg_params()->tuple_filter) { + if (type == REG_RING_TCP_LISTEN_CLOSE) { + if (get_global_cfg_params()->is_primary) { +-- +2.33.0 + diff --git a/0210-virtio-dfx-data-of-virtio.patch b/0210-virtio-dfx-data-of-virtio.patch new file mode 100644 index 0000000..2769715 --- /dev/null +++ b/0210-virtio-dfx-data-of-virtio.patch @@ -0,0 +1,157 @@ +From 0c6cf045fb0eea38cc7e53ee1984459ae90792bf Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Sat, 29 Jun 2024 15:16:54 +0800 +Subject: [PATCH] virtio: dfx data of virtio + +--- + src/common/gazelle_dfx_msg.h | 16 ++++++++++++++++ + src/lstack/core/lstack_stack_stat.c | 8 ++++++++ + src/lstack/include/lstack_virtio.h | 2 +- + src/ltran/ltran_dfx.c | 23 +++++++++++++++++++++++ + 4 files changed, 48 insertions(+), 1 deletion(-) + +diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h +index 696daf2..57bf631 100644 +--- a/src/common/gazelle_dfx_msg.h ++++ b/src/common/gazelle_dfx_msg.h +@@ -53,6 +53,7 @@ enum GAZELLE_STAT_MODE { + GAZELLE_STAT_LSTACK_LOG_LEVEL_SET, + GAZELLE_STAT_LSTACK_SHOW_RATE, + GAZELLE_STAT_LSTACK_SHOW_SNMP, ++ GAZELLE_STAT_LSTACK_SHOW_VIRTIO, + GAZELLE_STAT_LSTACK_SHOW_CONN, + GAZELLE_STAT_LSTACK_SHOW_LATENCY, + GAZELLE_STAT_LSTACK_LOW_POWER_MDF, +@@ -137,6 +138,20 @@ struct gazelle_stat_pkts { + struct gazelle_stack_aggregate_stats aggregate_stats; + }; + ++// same with lstack_virtio.h struct virtio_instance ++struct gazelle_stat_lstack_virtio { ++#define VIRTIO_MAX_QUEUE_NUM 8 ++ 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]; ++}; ++ + /* same as define in lwip/stats.h - struct stats_mib2 */ + struct gazelle_stat_lstack_snmp { + /* IP */ +@@ -328,6 +343,7 @@ struct gazelle_stack_dfx_data { + struct gazelle_stack_latency latency; + struct gazelle_stat_lstack_conn conn; + struct gazelle_stat_lstack_snmp snmp; ++ struct gazelle_stat_lstack_virtio virtio; + struct nic_eth_xstats nic_xstats; + struct nic_eth_features nic_features; + struct gazelle_stat_lstack_proto proto_data; +diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c +index 0f1f693..1e32c45 100644 +--- a/src/lstack/core/lstack_stack_stat.c ++++ b/src/lstack/core/lstack_stack_stat.c +@@ -29,6 +29,7 @@ + #include "posix/lstack_epoll.h" + #include "lstack_dpdk.h" + #include "lstack_stack_stat.h" ++#include "lstack_virtio.h" + + #define US_PER_SEC 1000000 + +@@ -343,6 +344,13 @@ static void get_stack_dfx_data(struct gazelle_stack_dfx_data *dfx, struct protoc + LSTACK_LOG(ERR, LSTACK, "memcpy_s err ret=%d \n", ret); + } + break; ++ case GAZELLE_STAT_LSTACK_SHOW_VIRTIO: ++ ret = memcpy_s(&dfx->data.virtio, sizeof(dfx->data.virtio), virtio_instance_get(), ++ sizeof(*(virtio_instance_get()))); ++ if (ret != EOK) { ++ LSTACK_LOG(ERR, LSTACK, "memcpy_s err ret=%d \n", ret); ++ } ++ break; + case GAZELLE_STAT_LSTACK_SHOW_CONN: + rpc_call_result = rpc_call_conntable(&stack->dfx_rpc_queue, dfx->data.conn.conn_list, + GAZELLE_LSTACK_MAX_CONN); +diff --git a/src/lstack/include/lstack_virtio.h b/src/lstack/include/lstack_virtio.h +index 615d9c9..5298dbe 100644 +--- a/src/lstack/include/lstack_virtio.h ++++ b/src/lstack/include/lstack_virtio.h +@@ -30,7 +30,7 @@ + ((mac_addrs)->addr_bytes[4]), \ + ((mac_addrs)->addr_bytes[5]) + #endif +- ++// When modifying virtio_instance, gazelle_stat_lstack_virtio also needs to be modified together. + struct virtio_instance { + uint16_t lstack_port_id; + uint16_t virtio_port_id; +diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c +index 4351891..cdcd7b3 100644 +--- a/src/ltran/ltran_dfx.c ++++ b/src/ltran/ltran_dfx.c +@@ -128,6 +128,7 @@ static void gazelle_print_ltran_start_latency(void *buf, const struct gazelle_st + static void gazelle_print_lstack_stat_total(void *buf, const struct gazelle_stat_msg_request *req_msg); + static void gazelle_print_lstack_stat_rate(void *buf, const struct gazelle_stat_msg_request *req_msg); + static void gazelle_print_lstack_stat_snmp(void *buf, const struct gazelle_stat_msg_request *req_msg); ++static void gazelle_print_lstack_stat_virtio(void *buf, const struct gazelle_stat_msg_request *req_msg); + static void gazelle_print_lstack_stat_conn(void *buf, const struct gazelle_stat_msg_request *req_msg); + static void gazelle_print_lstack_stat_latency(void *buf, const struct gazelle_stat_msg_request *req_msg); + static void gazelle_print_lstack_stat_lpm(void *buf, const struct gazelle_stat_msg_request *req_msg); +@@ -163,6 +164,7 @@ static struct gazelle_dfx_list g_gazelle_dfx_tbl[] = { + {GAZELLE_STAT_LSTACK_LOG_LEVEL_SET, 0, gazelle_print_ltran_wait}, + {GAZELLE_STAT_LSTACK_SHOW_RATE, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_stat_rate}, + {GAZELLE_STAT_LSTACK_SHOW_SNMP, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_stat_snmp}, ++ {GAZELLE_STAT_LSTACK_SHOW_VIRTIO, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_stat_virtio}, + {GAZELLE_STAT_LSTACK_SHOW_CONN, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_stat_conn}, + {GAZELLE_STAT_LSTACK_SHOW_LATENCY, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_stat_latency}, + {GAZELLE_STAT_LSTACK_LOW_POWER_MDF, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_stat_lpm}, +@@ -1169,6 +1171,24 @@ static void gazelle_print_lstack_stat_proto(void *buf, const struct gazelle_stat + } while (true); + } + ++static void gazelle_print_lstack_stat_virtio(void *buf, const struct gazelle_stat_msg_request *req_msg) ++{ ++ struct gazelle_stack_dfx_data *stat = (struct gazelle_stack_dfx_data *)buf; ++ struct gazelle_stat_lstack_virtio *virtio = &stat->data.virtio; ++ printf("\nStatistics of lstack virtio:\n"); ++ ++ printf("\nlstack_port_id =%u virtio_port_id =%u rx_queue_num =%u tx_queue_num =%u \n", ++ virtio->lstack_port_id, virtio->virtio_port_id, virtio->rx_queue_num, ++ virtio->tx_queue_num); ++ ++ printf("\n%-8s %-8s %-8s %-8s %-8s\n", "queue_id", "rx_pkg", "rx_drop", "tx_pkg", "tx_drop"); ++ for (int i = 0; i < virtio->rx_queue_num; i++) { ++ printf("%-8d %-8lu %-8lu %-8lu %-8lu\n", i, ++ virtio->rx_pkg[i], virtio->rx_drop[i], virtio->tx_pkg[i], virtio->tx_drop[i]); ++ } ++ printf("\n"); ++} ++ + static void gazelle_keepalive_string(char* str, int buff_len, struct gazelle_stat_lstack_conn_info *conn_info) + { + if (conn_info->keepalive == 0) { +@@ -1298,6 +1318,7 @@ static void show_usage(void) + " show lstack all statistics \n" + " -r, rate show lstack statistics per second \n" + " -s, snmp show lstack snmp \n" ++ " -v, virtio show rx_pkg/rx_drop/tx_pkg/tx_drop num of virtio \n" + " -c, connect show lstack connect \n" + " -l, latency [time] show lstack latency \n" + " -x, xstats show lstack xstats \n" +@@ -1553,6 +1574,8 @@ static int32_t parse_dfx_lstack_show_args(int32_t argc, char *argv[], struct gaz + req_msg[cmd_index++].stat_mode = GAZELLE_STAT_MODE_MAX; + } else if (strcmp(param, "snmp") == 0 || strcmp(param, "-s") == 0) { + req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_SNMP; ++ } else if (strcmp(param, "virtio") == 0 || strcmp(param, "-v") == 0) { ++ req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_VIRTIO; + } else if (strcmp(param, "connect") == 0 || strcmp(param, "-c") == 0) { + req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_CONN; + } else if (strcmp(param, "xstats") == 0 || strcmp(param, "-x") == 0) { +-- +2.33.0 + diff --git a/0211-add-flow_bifurcation-switch-in-lstack_cfg-file.patch b/0211-add-flow_bifurcation-switch-in-lstack_cfg-file.patch new file mode 100644 index 0000000..ecd2031 --- /dev/null +++ b/0211-add-flow_bifurcation-switch-in-lstack_cfg-file.patch @@ -0,0 +1,24 @@ +From 4af8c587a4f5b861012cb2d1ca954af8e6872162 Mon Sep 17 00:00:00 2001 +From: hantwofish +Date: Tue, 2 Jul 2024 15:26:48 +0800 +Subject: [PATCH] add flow_bifurcation switch in lstack_cfg file + +--- + src/lstack/lstack.conf | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lstack/lstack.conf b/src/lstack/lstack.conf +index c65a25d..490bdfc 100644 +--- a/src/lstack/lstack.conf ++++ b/src/lstack/lstack.conf +@@ -15,6 +15,7 @@ stack_thread_mode="run-to-wakeup" + #ltran mode need add "--map-perfect" and "--legacy-mem" in dpdk_args + use_ltran=0 + kni_switch=0 ++flow_bifurcation=0 + + low_power_mode=0 + +-- +2.33.0 + diff --git a/gazelle.spec b/gazelle.spec index 6f9dd73..9e2cafc 100644 --- a/gazelle.spec +++ b/gazelle.spec @@ -2,7 +2,7 @@ Name: gazelle Version: 1.0.2 -Release: 46 +Release: 48 Summary: gazelle is a high performance user-mode stack License: MulanPSL-2.0 URL: https://gitee.com/openeuler/gazelle @@ -215,6 +215,19 @@ Patch9195: 0195-virtio-create-and-init-virtio_port.patch Patch9196: 0196-refactor-udp-send.patch Patch9197: 0197-solve-compile-err-in-20.03.patch Patch9198: 0198-fix-function-call-error.patch +Patch9199: 0199-perftool-add-latency-tool.patch +Patch9200: 0200-cfg-del-unnecessary-logs.patch +Patch9201: 0201-fix-dpdk_bond_primary_set-bug.patch +Patch9202: 0202-fix-build-failed-in-2003sp4.patch +Patch9203: 0203-virtio-cfg-ipv4-and-ipv6-addr.patch +Patch9204: 0204-parse-packages-type-in-rx_poll.patch +Patch9205: 0205-virtio-distribute-pkg-by-dst_port.patch +Patch9206: 0206-fix-coredump-when-get-empty-from-udp-sendring.patch +Patch9207: 0207-fix-poll-init-not-clear-old-fd.patch +Patch9208: 0208-virtio-mode-actual_queue_num.patch +Patch9209: 0209-virtio-update-g_rule_port-by-reg_ring_type-enum.patch +Patch9210: 0210-virtio-dfx-data-of-virtio.patch +Patch9211: 0211-add-flow_bifurcation-switch-in-lstack_cfg-file.patch %description %{name} is a high performance user-mode stack. @@ -256,6 +269,23 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b %config(noreplace) %{conf_path}/ltran.conf %changelog +* Fri Jul 5 2024 yinbin6 - 1.0.2-48 +- add flow_bifurcation switch in lstack_cfg file +- virtio: dfx data of virtio +- virtio: update g_rule_port by reg_ring_type enum +- virtio: mode actual_queue_num +- fix poll init not clear old fd + +* Fri Jun 28 2024 yinbin6 - 1.0.2-47 +- fix coredump when get empty from udp sendring +- [virtio]: distribute pkg by dst_port +- parse packages type in rx_poll +- [virtio]: cfg ipv4 and ipv6 addr +- fix build failed in 2003sp4 +- fix dpdk_bond_primary_set bug +- cfg: del unnecessary logs +- perftool: add latency tool + * Wed Jun 26 2024 yinbin6 - 1.0.2-46 - fix function call error