!927 [sync] PR-904: sync refector fill udp sendring

From: @openeuler-sync-bot 
Reviewed-by: @jiangheng12 
Signed-off-by: @jiangheng12
This commit is contained in:
openeuler-ci-bot 2024-08-20 03:32:18 +00:00 committed by Gitee
commit ea88070ddb
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
5 changed files with 399 additions and 2 deletions

View File

@ -0,0 +1,25 @@
From 4ab3c2ccc73f6a935e05b914adcdafdf416a0f2f Mon Sep 17 00:00:00 2001
From: yinbin <yinbin8@huawei.com>
Date: Fri, 2 Aug 2024 17:09:02 +0800
Subject: [PATCH] WRAP:fix double connect lead posix api disable
---
src/lstack/api/lstack_wrap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c
index 947b273..5e60c36 100644
--- a/src/lstack/api/lstack_wrap.c
+++ b/src/lstack/api/lstack_wrap.c
@@ -319,7 +319,7 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name
} else {
/* When the socket is POSIX_LWIP_OR_KERNEL, connect to lwip first and then connect to kernel. */
ret = g_wrap_api->connect_fn(s, name, namelen);
- if (ret == 0) {
+ if (ret == 0 || (ret != 0 && errno == EINPROGRESS)) {
POSIX_SET_TYPE(sock, POSIX_LWIP);
} else {
ret = posix_api->connect_fn(s, name, namelen);
--
2.33.0

View File

@ -0,0 +1,51 @@
From a547e495321969074b72331c0ae6b65a39975f6a Mon Sep 17 00:00:00 2001
From: hkk <hankangkang5@huawei.com>
Date: Mon, 5 Aug 2024 21:58:46 +0800
Subject: [PATCH] virtio_user: add vlan info for kernerl packets when vlan
switch is on
---
src/lstack/core/lstack_virtio.c | 14 ++++++++++++++
src/lstack/netif/lstack_vdev.c | 1 +
2 files changed, 15 insertions(+)
diff --git a/src/lstack/core/lstack_virtio.c b/src/lstack/core/lstack_virtio.c
index 70b025c..f95b289 100644
--- a/src/lstack/core/lstack_virtio.c
+++ b/src/lstack/core/lstack_virtio.c
@@ -179,6 +179,20 @@ void virtio_tap_process_rx(uint16_t port, uint32_t queue_id)
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);
+ /*
+ * For VLAN, the tap device defaults to tx-vlan-ofload as enabled and will not be modified by default,
+ * so the judgment is skipped.
+ * For checksum, tap devices are turned off by default, and it is assumed that they will not be modified,
+ * so no action will be taken.
+ * For TSO, tap devices do not support it, so no action will be taken.
+ */
+ if (get_global_cfg_params()->nic.vlan_mode != -1) {
+ for (int i = 0; i< pkg_num; i++) {
+ pkts_burst[i]->ol_flags |= RTE_MBUF_F_TX_VLAN;
+ pkts_burst[i]->vlan_tci = (u16_t)get_global_cfg_params()->nic.vlan_mode;
+ }
+ }
+
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);
diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c
index a590b30..9ca77ba 100644
--- a/src/lstack/netif/lstack_vdev.c
+++ b/src/lstack/netif/lstack_vdev.c
@@ -87,6 +87,7 @@ static inline void vdev_pkts_parse(struct rte_mbuf **pkts, int pkt_num)
pkts[i]->l2_len = sizeof(struct rte_ether_hdr);
}
+ pkts[i]->packet_type = 0;
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);
--
2.33.0

View File

@ -0,0 +1,88 @@
From b193256f4e3e5967ec2fc85600ec0883edc4bcc1 Mon Sep 17 00:00:00 2001
From: hkk <hankangkang5@huawei.com>
Date: Thu, 8 Aug 2024 10:54:40 +0800
Subject: [PATCH] virtio_user: solve the issue that failed to bind
virtio_user's IPv6 address
---
src/lstack/api/lstack_wrap.c | 57 ++++++++++++++++++++++++++----------
1 file changed, 42 insertions(+), 15 deletions(-)
diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c
index 5e60c36..afcd227 100644
--- a/src/lstack/api/lstack_wrap.c
+++ b/src/lstack/api/lstack_wrap.c
@@ -199,6 +199,46 @@ static int32_t do_accept4(int32_t s, struct sockaddr *addr, socklen_t *addrlen,
return posix_api->accept4_fn(s, addr, addrlen, flags);
}
+static int kernel_bind_process(int32_t s, const struct sockaddr *name, socklen_t namelen)
+{
+ struct lwip_sock *sock = NULL;
+ int times = 10;
+ int ret = 0;
+
+ if (get_global_cfg_params()->kni_switch == 0 && get_global_cfg_params()->flow_bifurcation == 0) {
+ return 0;
+ }
+ ret = posix_api->bind_fn(s, name, namelen);
+ /* maybe kni addr, ipv6 addr maybe is tentative,need to wait a few seconds */
+ if (name->sa_family == AF_INET6 && ret < 0 && errno == EADDRNOTAVAIL) {
+ LSTACK_LOG(WARNING, LSTACK, "virtio_user addr is tentative, please wait... \n");
+ while (ret != 0 && times-- > 0) {
+ sleep(1);
+ ret = posix_api->bind_fn(s, name, namelen);
+ }
+ }
+
+ if (ret == 0) {
+ /* reuse the port allocated by kernel when port == 0 */
+ if (((struct sockaddr_in *)name)->sin_port == 0) {
+ struct sockaddr_in kerneladdr;
+ socklen_t len = sizeof(kerneladdr);
+ if (posix_api->getsockname_fn(s, (struct sockaddr *)&kerneladdr, &len) < 0) {
+ LSTACK_LOG(ERR, LSTACK, "kernel getsockname failed, fd=%d, errno=%d\n", s, errno);
+ return -1;
+ }
+ ((struct sockaddr_in *)name)->sin_port = kerneladdr.sin_port;
+ }
+ /* not sure POSIX_LWIP or POSIX_KERNEL */
+ } else {
+ sock = lwip_get_socket(s);
+ POSIX_SET_TYPE(sock, POSIX_LWIP);
+ LSTACK_LOG(ERR, LSTACK, "kernel bind failed ret %d errno %d sa_family %u times %u\n",
+ ret, errno, name->sa_family, times);
+ }
+ return 0;
+}
+
static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen)
{
if (name == NULL) {
@@ -231,21 +271,8 @@ static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen
return posix_api->bind_fn(s, name, namelen);
}
- /* maybe kni addr */
- if (posix_api->bind_fn(s, name, namelen) == 0) {
- /* reuse the port allocated by kernel when port == 0 */
- if (((struct sockaddr_in *)name)->sin_port == 0) {
- struct sockaddr_in kerneladdr;
- socklen_t len = sizeof(kerneladdr);
- if (posix_api->getsockname_fn(s, (struct sockaddr *)&kerneladdr, &len) < 0) {
- LSTACK_LOG(ERR, LSTACK, "kernel getsockname failed, fd=%d, errno=%d\n", s, errno);
- return -1;
- }
- ((struct sockaddr_in *)name)->sin_port = kerneladdr.sin_port;
- }
- /* not sure POSIX_LWIP or POSIX_KERNEL */
- } else {
- POSIX_SET_TYPE(sock, POSIX_LWIP);
+ if (kernel_bind_process(s, name, namelen) < 0) {
+ return -1;
}
return g_wrap_api->bind_fn(s, name, namelen);
}
--
2.33.0

View File

@ -0,0 +1,223 @@
From eedeee26cb113f550339d54238ca41eb012697e3 Mon Sep 17 00:00:00 2001
From: yinbin <yinbin8@huawei.com>
Date: Wed, 31 Jul 2024 20:31:57 +0800
Subject: [PATCH] refector fill udp sendring
---
src/lstack/core/lstack_lwip.c | 109 ++++++++++++++++++------
src/lstack/core/lstack_protocol_stack.c | 11 +--
2 files changed, 84 insertions(+), 36 deletions(-)
diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c
index 271e94f..19ff22d 100644
--- a/src/lstack/core/lstack_lwip.c
+++ b/src/lstack/core/lstack_lwip.c
@@ -457,22 +457,67 @@ int sem_timedwait_nsecs(sem_t *sem)
return sem_timedwait(sem, &ts);
}
-static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, size_t len,
- const struct sockaddr *addr, socklen_t addrlen)
+static ssize_t do_lwip_udp_fill_sendring(struct lwip_sock *sock, const void *buf, size_t len,
+ const struct sockaddr *addr, socklen_t addrlen)
{
- if (sock->errevent > 0) {
- GAZELLE_RETURN(ENOTCONN);
+ if (len > GAZELLE_UDP_PKGLEN_MAX) {
+ LSTACK_LOG(ERR, LSTACK, "Message too long\n");
+ GAZELLE_RETURN(EMSGSIZE);
+ }
+
+ ssize_t send_len = 0;
+ uint32_t write_num = (len + MBUF_MAX_DATA_LEN - 1) / MBUF_MAX_DATA_LEN;
+ uint32_t write_avail = gazelle_ring_readable_count(sock->send_ring);
+ struct wakeup_poll *wakeup = sock->wakeup;
+
+ if (write_num > rte_ring_get_capacity(sock->send_ring)) {
+ LSTACK_LOG(ERR, LSTACK, "sock send_ring size is not enough\n");
+ GAZELLE_RETURN(ENOMEM);
+ }
+
+ /* if udp send 0 packet, set write_num to at least 1 */
+ if (write_num == 0) {
+ write_num = 1;
+ }
+
+ while (!netconn_is_nonblocking(sock->conn) && (write_avail < write_num)) {
+ if (sock->errevent > 0) {
+ GAZELLE_RETURN(ENOTCONN);
+ }
+ write_avail = gazelle_ring_readable_count(sock->send_ring);
+ }
+
+ if (write_avail < write_num) {
+ sem_timedwait_nsecs(&sock->snd_ring_sem);
+ GAZELLE_RETURN(ENOMEM);
+ }
+
+ send_len = app_buff_write(sock, (char *)buf, len, write_num, addr, addrlen);
+
+ if (wakeup && wakeup->type == WAKEUP_EPOLL && (sock->events & EPOLLOUT)
+ && !NETCONN_IS_OUTIDLE(sock)) {
+ del_sock_event(sock, EPOLLOUT);
+ }
+
+ if (wakeup) {
+ wakeup->stat.app_write_cnt += write_num;
}
- struct protocol_stack *stack = sock->stack;
- if (!stack) {
+ return send_len;
+}
+
+static ssize_t do_lwip_tcp_fill_sendring(struct lwip_sock *sock, const void *buf, size_t len,
+ const struct sockaddr *addr, socklen_t addrlen)
+{
+ /* refer to the lwip implementation. */
+ if (len == 0) {
return 0;
}
ssize_t send_len = 0;
/* merge data into last pbuf */
- if (!NETCONN_IS_UDP(sock) && sock->remain_len) {
+ if (sock->remain_len) {
sock->stack->stats.sock_tx_merge++;
send_len = merge_data_lastpbuf(sock, (char *)buf, len);
if (send_len >= len) {
@@ -485,11 +530,6 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si
uint32_t write_avail = gazelle_ring_readable_count(sock->send_ring);
struct wakeup_poll *wakeup = sock->wakeup;
- /* if udp send 0 packet, set write_num to at least 1 */
- if (NETCONN_IS_UDP(sock) && write_num == 0) {
- write_num = 1;
- }
-
while (!netconn_is_nonblocking(sock->conn) && (write_avail < write_num)) {
if (sock->errevent > 0) {
GAZELLE_RETURN(ENOTCONN);
@@ -500,9 +540,6 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si
/* send_ring is full, data attach last pbuf */
if (write_avail == 0) {
sem_timedwait_nsecs(&sock->snd_ring_sem);
- if (likely(sock->send_ring != NULL)) {
- write_avail = gazelle_ring_readable_count(sock->send_ring);
- }
goto END;
}
@@ -523,10 +560,11 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si
}
END:
- if (send_len == 0 && !NETCONN_IS_UDP(sock)) {
+ if (send_len == 0) {
errno = EAGAIN;
return -1;
}
+
return send_len;
}
@@ -817,28 +855,39 @@ static inline void thread_bind_stack(struct lwip_sock *sock)
ssize_t do_lwip_send_to_stack(int32_t fd, const void *buf, size_t len, int32_t flags,
const struct sockaddr *addr, socklen_t addrlen)
{
+ ssize_t send = 0;
+
if (buf == NULL) {
GAZELLE_RETURN(EINVAL);
}
- struct lwip_sock *sock = lwip_get_socket(fd);
- if (len == 0 && !NETCONN_IS_UDP(sock)) {
- return 0;
- }
-
- if (NETCONN_IS_UDP(sock) && (len > GAZELLE_UDP_PKGLEN_MAX)) {
- LSTACK_LOG(ERR, LSTACK, "Message too long\n");
- GAZELLE_RETURN(EMSGSIZE);
+ if (addr && addr->sa_family != AF_INET && addr->sa_family != AF_INET6) {
+ GAZELLE_RETURN(EINVAL);
}
+
+ struct lwip_sock *sock = lwip_get_socket(fd);
thread_bind_stack(sock);
if (sock->same_node_tx_ring != NULL) {
return gazelle_same_node_ring_send(sock, buf, len, flags);
}
- ssize_t send = do_lwip_fill_sendring(sock, buf, len, addr, addrlen);
- if (send < 0 || (send == 0 && !NETCONN_IS_UDP(sock))) {
- return send;
+ if (sock->errevent > 0 || sock->stack == NULL) {
+ GAZELLE_RETURN(ENOTCONN);
+ }
+
+ if (NETCONN_IS_UDP(sock)) {
+ send = do_lwip_udp_fill_sendring(sock, buf, len, addr, addrlen);
+ /* send = 0: udp send a empty package */
+ if (send < 0) {
+ return send;
+ }
+ } else {
+ send = do_lwip_tcp_fill_sendring(sock, buf, len, addr, addrlen);
+ // send = 0 : tcp peer close connection ?
+ if (send <= 0) {
+ return send;
+ }
}
notice_stack_send(sock, fd, send, flags);
@@ -860,7 +909,11 @@ ssize_t do_lwip_sendmsg_to_stack(struct lwip_sock *sock, int32_t s, const struct
continue;
}
- ret = do_lwip_fill_sendring(sock, message->msg_iov[i].iov_base, message->msg_iov[i].iov_len, NULL, 0);
+ if (NETCONN_IS_UDP(sock)) {
+ ret = do_lwip_udp_fill_sendring(sock, message->msg_iov[i].iov_base, message->msg_iov[i].iov_len, NULL, 0);
+ } else {
+ ret = do_lwip_tcp_fill_sendring(sock, message->msg_iov[i].iov_base, message->msg_iov[i].iov_len, NULL, 0);
+ }
if (ret <= 0) {
buflen = (buflen == 0) ? ret : buflen;
break;
diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c
index 2867711..f433d0d 100644
--- a/src/lstack/core/lstack_protocol_stack.c
+++ b/src/lstack/core/lstack_protocol_stack.c
@@ -916,7 +916,6 @@ void stack_udp_send(struct rpc_msg *msg)
size_t len = msg->args[MSG_ARG_1].size;
struct protocol_stack *stack = get_protocol_stack();
int replenish_again;
- uint32_t call_num;
struct lwip_sock *sock = lwip_get_socket(fd);
if (sock == NULL) {
@@ -930,16 +929,12 @@ void stack_udp_send(struct rpc_msg *msg)
}
replenish_again = do_lwip_send(stack, sock->conn->callback_arg.socket, sock, len, 0);
- call_num = __sync_fetch_and_sub(&sock->call_num, 1);
- if (replenish_again < 0) {
- return;
- }
-
- if ((call_num == 1) && (replenish_again > 0)) {
+ if ((replenish_again > 0) && (__atomic_load_n(&sock->call_num, __ATOMIC_ACQUIRE) == 1)) {
rpc_call_replenish(&stack->rpc_queue, sock);
return;
}
-
+
+ __sync_fetch_and_sub(&sock->call_num, 1);
return;
}
--
2.33.0

View File

@ -2,14 +2,14 @@
Name: gazelle
Version: 1.0.2
Release: 53
Release: 54
Summary: gazelle is a high performance user-mode stack
License: MulanPSL-2.0
URL: https://gitee.com/openeuler/gazelle
Source0: %{name}-%{version}.tar.gz
BuildRequires: cmake gcc-c++
BuildRequires: lwip >= 2.1.3-78
BuildRequires: lwip >= 2.2.0-51
BuildRequires: dpdk-devel >= 21.11-5
BuildRequires: numactl-devel libpcap-devel libconfig-devel libboundscheck uthash-devel
%ifarch ppc64le
@ -250,6 +250,10 @@ Patch9230: 0230-dfx-optimize-gazellectl-x-for-bond.patch
Patch9231: 0231-virtio-fix-dfx-error-with-multiple-cpus.patch
Patch9232: 0232-fix-issue-create-virtio_user-based-on-bond4-main-net.patch
Patch9233: 0233-virtio_user-modify-mbuf-index-for-bond4.patch
Patch9234: 0234-WRAP-fix-double-connect-lead-posix-api-disable.patch
Patch9235: 0235-virtio_user-add-vlan-info-for-kernerl-packets-when-v.patch
Patch9236: 0236-virtio_user-solve-the-issue-that-failed-to-bind-virt.patch
Patch9237: 0237-refector-fill-udp-sendring.patch
%description
%{name} is a high performance user-mode stack.
@ -291,6 +295,12 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b
%config(noreplace) %{conf_path}/ltran.conf
%changelog
* Fri Aug 9 2024 yinbin6 <yinbin8@huawei.com> - 1.0.2-54
- refector fill udp sendring
- virtio_user: solve the issue that failed to bind virtio_user's IPv6 address
- virtio_user: add vlan info for kernerl packets when vlan switch is on
- WRAP:fix double connect lead posix api disable
* Fri Aug 2 2024 yinbin6 <yinbin8@huawei.com> - 1.0.2-53
- virtio_user: modify mbuf index for bond4
- fix issue: create virtio_user based on bond4 main network card