From 8dfa19585b0e5b23e7855e1d544c41dd7a6a1dd9 Mon Sep 17 00:00:00 2001
From: yangchen <yangchen145@huawei.com>
Date: Fri, 15 Dec 2023 17:56:30 +0800
Subject: [PATCH] support netperf

---
 src/lstack/api/lstack_wrap.c            | 13 ++++++-------
 src/lstack/core/lstack_lwip.c           | 21 +++++++++++++++++++--
 src/lstack/core/lstack_protocol_stack.c | 19 +++++++++++--------
 src/lstack/include/posix/lstack_epoll.h | 19 +++++++++++++++++++
 src/ltran/ltran_dfx.c                   |  2 +-
 5 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c
index 65a0a5a..a226dc4 100644
--- a/src/lstack/api/lstack_wrap.c
+++ b/src/lstack/api/lstack_wrap.c
@@ -276,11 +276,6 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name
         return posix_api->connect_fn(s, name, namelen);
     }
 
-    if (!netconn_is_nonblocking(sock->conn)) {
-        LSTACK_LOG(ERR, LSTACK, "connect does not support blocking fd currently\n");
-        GAZELLE_RETURN(EINVAL);
-    }
-
     int32_t ret = 0;
     int32_t remote_port;
     bool is_local = is_dst_ip_localhost(name);
@@ -347,7 +342,11 @@ static bool unsupport_optname(int32_t optname)
         optname == SO_PROTOCOL  ||
         optname == TCP_QUICKACK ||
         optname == SO_SNDTIMEO  ||
-        optname == SO_RCVTIMEO) {
+        optname == SO_RCVTIMEO  ||
+        optname == SO_SNDBUF    ||
+        optname == TCP_INFO     ||
+        optname == TCP_MAXSEG   ||
+        optname == TCP_CONGESTION) {
         return true;
     }
     return false;
@@ -615,7 +614,7 @@ static int32_t do_select(int32_t nfds, fd_set *readfds, fd_set *writefds, fd_set
         return posix_api->select_fn(nfds, readfds, writefds, exceptfds, timeout);
     }
     
-    return posix_api->select_fn(nfds, readfds, writefds, exceptfds, timeout);
+    return g_wrap_api->select_fn(nfds, readfds, writefds, exceptfds, timeout);
 }
 
 #define WRAP_VA_PARAM(_fd, _cmd, _lwip_fcntl, _fcntl_fn) \
diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c
index fb286d6..a944f7a 100644
--- a/src/lstack/core/lstack_lwip.c
+++ b/src/lstack/core/lstack_lwip.c
@@ -564,6 +564,12 @@ 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 (!netconn_is_nonblocking(sock->conn)) {
+        while (write_avail < write_num) {
+            write_avail = gazelle_ring_readable_count(sock->send_ring);
+        }
+    }
+
     /* send_ring is full, data attach last pbuf */
     if (write_avail == 0) {
         if (!get_global_cfg_params()->expand_send_ring) {
@@ -1005,8 +1011,19 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags
             pbuf = sock->recv_lastdata;
             sock->recv_lastdata = NULL;
         } else {
-            if (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1) {
-                break;
+            if (netconn_is_nonblocking(sock->conn)) {
+                if (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1) {
+                    break;
+                }
+            } else {
+                while (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1 && recvd == 0) {
+                    /* if the connection is disconnected, recv return 0 */
+                    if ((sock->errevent > 0 || (sock->conn->pcb.tcp->flags & TF_FIN)) && !NETCONN_IS_DATAIN(sock)) {
+                        return 0;
+                    }
+
+                    lstack_block_wait(sock->wakeup);
+                }
             }
         }
 
diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c
index 8dbd9ad..414b5f8 100644
--- a/src/lstack/core/lstack_protocol_stack.c
+++ b/src/lstack/core/lstack_protocol_stack.c
@@ -268,12 +268,8 @@ static void wakeup_kernel_event(struct protocol_stack *stack)
             continue;
         }
 
-         __atomic_store_n(&wakeup->have_kernel_event, true, __ATOMIC_RELEASE);
-        if (__atomic_load_n(&wakeup->in_wait, __ATOMIC_ACQUIRE)) {
-             __atomic_store_n(&wakeup->in_wait, false, __ATOMIC_RELEASE);
-            rte_mb();
-            pthread_mutex_unlock(&wakeup->wait);
-        }
+        __atomic_store_n(&wakeup->have_kernel_event, true, __ATOMIC_RELEASE);
+        lstack_block_wakeup(wakeup);
     }
 
     return;
@@ -1233,14 +1229,21 @@ int32_t stack_broadcast_bind(int32_t fd, const struct sockaddr *name, socklen_t
 int32_t stack_broadcast_accept4(int32_t fd, struct sockaddr *addr, socklen_t *addrlen, int flags)
 {
     int32_t ret = -1;
-
+    struct lwip_sock *min_sock = NULL;
     struct lwip_sock *sock = get_socket(fd);
     if (sock == NULL) {
         errno = EINVAL;
         return -1;
     }
 
-    struct lwip_sock *min_sock = get_min_accept_sock(fd);
+    if (netconn_is_nonblocking(sock->conn)) {
+        min_sock = get_min_accept_sock(fd);
+    } else {
+        while ((min_sock = get_min_accept_sock(fd)) == NULL) {
+            lstack_block_wait(sock->wakeup);
+	}
+    }
+
     if (min_sock && min_sock->conn) {
         ret = rpc_call_accept(min_sock->conn->socket, addr, addrlen, flags);
     }
diff --git a/src/lstack/include/posix/lstack_epoll.h b/src/lstack/include/posix/lstack_epoll.h
index 9c34eb3..7591f0f 100644
--- a/src/lstack/include/posix/lstack_epoll.h
+++ b/src/lstack/include/posix/lstack_epoll.h
@@ -80,6 +80,25 @@ int32_t lstack_rtc_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t
 int32_t lstack_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout);
 int lstack_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeval);
 
+static inline void lstack_block_wait(struct wakeup_poll *wakeup)
+{
+    if (wakeup == NULL) {
+        return;
+    }
+
+    __atomic_store_n(&wakeup->in_wait, true, __ATOMIC_RELEASE);
+    pthread_mutex_lock(&wakeup->wait);
+}
+
+static inline void lstack_block_wakeup(struct wakeup_poll *wakeup)
+{
+    if (wakeup && __atomic_load_n(&wakeup->in_wait, __ATOMIC_ACQUIRE)) {
+        __atomic_store_n(&wakeup->in_wait, false, __ATOMIC_RELEASE);
+        rte_mb();
+        pthread_mutex_unlock(&wakeup->wait);
+    }
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c
index 2a84cb8..ee80359 100644
--- a/src/ltran/ltran_dfx.c
+++ b/src/ltran/ltran_dfx.c
@@ -168,7 +168,7 @@ static void gazelle_print_lstack_nic_features(void *buf, const struct gazelle_st
     printf("###### NIC offload and other features for port %-2d #########\n", f->port_id);
 
     printf("tx-ipv4-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_IPV4_CKSUM) ? "on" : "off");
-    printf("tx-tcp_checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_CKSUM) ? "on" : "off");
+    printf("tx-tcp-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_CKSUM) ? "on" : "off");
     printf("tx-tcp-tso: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_TSO) ? "on" : "off");
     printf("tx-udp-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_UDP_CKSUM) ? "on" : "off");
     printf("tx-vlan-insert: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_VLAN_INSERT) ? "on" : "off");
-- 
2.27.0

