diff --git a/0026-epoll-adapt-epoll-interface-for-rtc-mode.patch b/0026-epoll-adapt-epoll-interface-for-rtc-mode.patch new file mode 100644 index 0000000..9d7dbc4 --- /dev/null +++ b/0026-epoll-adapt-epoll-interface-for-rtc-mode.patch @@ -0,0 +1,365 @@ +From 8afdae8f8f41bb62d3e57db638735c29abe132d1 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Mon, 9 Oct 2023 11:33:01 +0800 +Subject: [PATCH] epoll: adapt epoll interface for rtc mode + +--- + src/lstack/api/lstack_epoll.c | 158 +++++++++++++++++++++--- + src/lstack/api/lstack_rtc_api.c | 4 +- + src/lstack/api/lstack_rtw_api.c | 4 +- + src/lstack/include/lstack_rtc_api.h | 52 ++++---- + src/lstack/include/posix/lstack_epoll.h | 6 +- + 5 files changed, 178 insertions(+), 46 deletions(-) + +diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c +index 7c40792..d1fb209 100644 +--- a/src/lstack/api/lstack_epoll.c ++++ b/src/lstack/api/lstack_epoll.c +@@ -155,6 +155,34 @@ static uint32_t update_events(struct lwip_sock *sock) + return event; + } + ++static void rtc_raise_pending_events(struct wakeup_poll *wakeup, struct lwip_sock *sock) ++{ ++ uint32_t event = 0; ++ ++ if (sock->rcvevent) { ++ event |= EPOLLIN; ++ } ++ ++ if (sock->errevent > 0) { ++ event |= EPOLLERR | EPOLLIN; ++ } ++ ++ if (sock->sendevent) { ++ /* lwip_netconn_do_connected set LIBOS FLAGS when connected */ ++ if (sock->conn && CONN_TYPE_IS_LIBOS(sock->conn)) { ++ event |= EPOLLOUT; ++ } ++ } ++ ++ if (event) { ++ sock->events = event; ++ if (wakeup->type == WAKEUP_EPOLL && (sock->events & sock->epoll_events) && ++ list_is_null(&sock->event_list)) { ++ list_add_node(&wakeup->event_list, &sock->event_list); ++ } ++ } ++} ++ + static void raise_pending_events(struct wakeup_poll *wakeup, struct lwip_sock *sock) + { + uint32_t event = 0; +@@ -230,11 +258,16 @@ int32_t lstack_do_epoll_create(int32_t fd) + wakeup->epollfd = fd; + sock->wakeup = wakeup; + +- update_epoll_max_stack(wakeup); +- change_epollfd_kernel_thread(wakeup, wakeup->bind_stack, wakeup->max_stack); +- wakeup->bind_stack = wakeup->max_stack; +- if (get_global_cfg_params()->app_bind_numa) { +- bind_to_stack_numa(wakeup->bind_stack); ++ if (!get_global_cfg_params()->stack_mode_rtc) { ++ update_epoll_max_stack(wakeup); ++ change_epollfd_kernel_thread(wakeup, wakeup->bind_stack, wakeup->max_stack); ++ wakeup->bind_stack = wakeup->max_stack; ++ if (get_global_cfg_params()->app_bind_numa) { ++ bind_to_stack_numa(wakeup->bind_stack); ++ } ++ } else { ++ wakeup->bind_stack = wakeup->max_stack = get_protocol_stack(); ++ change_epollfd_kernel_thread(wakeup, NULL, wakeup->max_stack); + } + + return fd; +@@ -329,7 +362,45 @@ static void update_epoll_max_stack(struct wakeup_poll *wakeup) + wakeup->max_stack = stack_group->stacks[bind_id]; + } + +-int32_t lstack_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event *event) ++int32_t lstack_rtc_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event *event) ++{ ++ if (epfd < 0 || fd < 0 || epfd == fd || (event == NULL && op != EPOLL_CTL_DEL)) { ++ LSTACK_LOG(ERR, LSTACK, "fd=%d epfd=%d op=%d\n", fd, epfd, op); ++ GAZELLE_RETURN(EINVAL); ++ } ++ ++ struct lwip_sock *epoll_sock = get_socket_by_fd(epfd); ++ if (epoll_sock == NULL || epoll_sock->wakeup == NULL) { ++ return posix_api->epoll_ctl_fn(epfd, op, fd, event); ++ } ++ ++ struct wakeup_poll *wakeup = epoll_sock->wakeup; ++ struct lwip_sock *sock = get_socket(fd); ++ if (sock == NULL) { ++ return posix_api->epoll_ctl_fn(epfd, op, fd, event); ++ } ++ ++ switch (op) { ++ case EPOLL_CTL_ADD: ++ sock->wakeup = wakeup; ++ /* fall through */ ++ case EPOLL_CTL_MOD: ++ sock->epoll_events = event->events | EPOLLERR | EPOLLHUP; ++ sock->ep_data = event->data; ++ rtc_raise_pending_events(wakeup, sock); ++ break; ++ case EPOLL_CTL_DEL: ++ sock->epoll_events = 0; ++ list_del_node_null(&sock->event_list); ++ break; ++ default: ++ GAZELLE_RETURN(EINVAL); ++ } ++ ++ return 0; ++} ++ ++int32_t lstack_rtw_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event *event) + { + LSTACK_LOG(DEBUG, LSTACK, "op=%d events: fd: %d\n", op, fd); + +@@ -384,29 +455,28 @@ int32_t lstack_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_even + return 0; + } + +-static int32_t epoll_lwip_event(struct wakeup_poll *wakeup, struct epoll_event *events, uint32_t maxevents) ++int32_t epoll_lwip_event_nolock(struct wakeup_poll *wakeup, struct epoll_event *events, uint32_t maxevents) + { + int32_t event_num = 0; + struct list_node *node, *temp; + +- pthread_spin_lock(&wakeup->event_list_lock); +- + list_for_each_safe(node, temp, &wakeup->event_list) { + struct lwip_sock *sock = container_of(node, struct lwip_sock, event_list); + + if ((sock->epoll_events & sock->events) == 0) { +- list_del_node_null(&sock->event_list); ++ list_del_node_null(node); + continue; + } + + if (sock->epoll_events & EPOLLET) { +- list_del_node_null(&sock->event_list); ++ list_del_node_null(node); ++ sock->events = 0; + } + + /* EPOLLONESHOT: generate event after epoll_ctl add/mod event again + epoll_event set 0 avoid generating event util epoll_ctl set epoll_event a valu */ + if (sock->epoll_events & EPOLLONESHOT) { +- list_del_node_null(&sock->event_list); ++ list_del_node_null(node); + sock->epoll_events = 0; + } + +@@ -415,13 +485,25 @@ static int32_t epoll_lwip_event(struct wakeup_poll *wakeup, struct epoll_event * + event_num++; + + if (event_num >= maxevents) { ++ /* move list head after the current node, and start traversing from this node next time */ ++ list_del_node_null(&wakeup->event_list); ++ list_add_node(node, &wakeup->event_list); + break; + } + } + ++ wakeup->stat.app_events += event_num; ++ return event_num; ++} ++ ++static int32_t epoll_lwip_event(struct wakeup_poll *wakeup, struct epoll_event *events, uint32_t maxevents) ++{ ++ int32_t event_num; ++ ++ pthread_spin_lock(&wakeup->event_list_lock); ++ event_num = epoll_lwip_event_nolock(wakeup, events, maxevents); + pthread_spin_unlock(&wakeup->event_list_lock); + +- wakeup->stat.app_events += event_num; + return event_num; + } + +@@ -484,7 +566,55 @@ static void ms_to_timespec(struct timespec *timespec, int32_t timeout) + timespec->tv_nsec = timespec->tv_nsec % SEC_TO_NSEC; + } + +-int32_t lstack_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout) ++int32_t lstack_rtc_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout) ++{ ++ struct lwip_sock *sock = get_socket_by_fd(epfd); ++ ++ if (sock == NULL || sock->wakeup == NULL) { ++ return posix_api->epoll_wait_fn(epfd, events, maxevents, timeout); ++ } ++ ++ struct wakeup_poll *wakeup = sock->wakeup; ++ int32_t lwip_num = 0; ++ /* 16: avoid app process events for a long time */ ++ int32_t tmpmaxevents = 16; ++ /* avoid the starvation of epoll events from both netstack */ ++ int host_maxevents = tmpmaxevents / 2; ++ uint32_t poll_ts = sys_now(); ++ bool loop_flag; ++ int32_t kernel_num = 0; ++ int32_t tmptimeout = timeout; ++ ++ do { ++ stack_polling(0); ++ if (__atomic_load_n(&wakeup->have_kernel_event, __ATOMIC_ACQUIRE)) { ++ kernel_num = posix_api->epoll_wait_fn(epfd, events, host_maxevents, 0); ++ if (!kernel_num) { ++ __atomic_store_n(&wakeup->have_kernel_event, false, __ATOMIC_RELEASE); ++ } ++ } ++ if (tmptimeout > 0) { ++ tmptimeout = update_timeout(tmptimeout, poll_ts); ++ } ++ ++ loop_flag = false; ++ if (!kernel_num && list_is_empty(&wakeup->event_list) && tmptimeout != 0) { ++ loop_flag = true; ++ } ++ } while (loop_flag); ++ ++ if (kernel_num < 0) { ++ LSTACK_LOG(ERR, LSTACK, "lstack_rtc_epoll_wait: kernel event failed\n"); ++ return kernel_num; ++ } ++ ++ lwip_num = epoll_lwip_event_nolock(wakeup, &events[kernel_num], tmpmaxevents - kernel_num); ++ wakeup->stat.app_events += lwip_num; ++ ++ return lwip_num + kernel_num; ++} ++ ++int32_t lstack_rtw_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout) + { + struct lwip_sock *sock = get_socket_by_fd(epfd); + if (sock == NULL || sock->wakeup == NULL) { +diff --git a/src/lstack/api/lstack_rtc_api.c b/src/lstack/api/lstack_rtc_api.c +index b7c6380..b9abf0f 100644 +--- a/src/lstack/api/lstack_rtc_api.c ++++ b/src/lstack/api/lstack_rtc_api.c +@@ -29,7 +29,7 @@ int rtc_poll(struct pollfd *fds, nfds_t nfds, int timeout) + + int rtc_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout) + { +- return -1; ++ return lstack_rtc_epoll_wait(epfd, events, maxevents, timeout); + } + + int rtc_socket(int domain, int type, int protocol) +@@ -68,5 +68,5 @@ int rtc_epoll_create1(int flags) + + int rtc_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) + { +- return lstack_epoll_ctl(epfd, op, fd, event); ++ return lstack_rtc_epoll_ctl(epfd, op, fd, event); + } +diff --git a/src/lstack/api/lstack_rtw_api.c b/src/lstack/api/lstack_rtw_api.c +index 9b8678a..7d14ffa 100644 +--- a/src/lstack/api/lstack_rtw_api.c ++++ b/src/lstack/api/lstack_rtw_api.c +@@ -206,7 +206,7 @@ ssize_t rtw_sendto(int sockfd, const void *buf, size_t len, int flags, + + int rtw_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout) + { +- return lstack_epoll_wait(epfd, events, maxevents, timeout); ++ return lstack_rtw_epoll_wait(epfd, events, maxevents, timeout); + } + + int rtw_poll(struct pollfd *fds, nfds_t nfds, int timeout) +@@ -225,7 +225,7 @@ int rtw_close(int s) + + int rtw_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) + { +- return lstack_epoll_ctl(epfd, op, fd, event); ++ return lstack_rtw_epoll_ctl(epfd, op, fd, event); + } + + int rtw_epoll_create1(int flags) +diff --git a/src/lstack/include/lstack_rtc_api.h b/src/lstack/include/lstack_rtc_api.h +index 563cbd8..0aff928 100644 +--- a/src/lstack/include/lstack_rtc_api.h ++++ b/src/lstack/include/lstack_rtc_api.h +@@ -17,32 +17,32 @@ + + /* don't include lwip/sockets.h, conflict with sys/socket.h */ + /* extern lwip_api here */ +-int lwip_fcntl(int s, int cmd, int val); +-int lwip_ioctl(int s, long cmd, ...); +-int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +-int lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags); +-int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); +-int lwip_shutdown(int s, int how); +-int lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen); +-int lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen); +-int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); +-int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); +-int lwip_close(int s); +-int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); +-int lwip_listen(int s, int backlog); +-ssize_t lwip_recv(int s, void *mem, size_t len, int flags); +-ssize_t lwip_read(int s, void *mem, size_t len); +-ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt); +-ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags, +- struct sockaddr *from, socklen_t *fromlen); +-ssize_t lwip_recvmsg(int s, const struct msghdr *message, int flags); +-ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags); +-ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags); +-ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, +- const struct sockaddr *to, socklen_t tolen); +-int lwip_socket(int domain, int type, int protocol); +-ssize_t lwip_write(int s, const void *dataptr, size_t size); +-ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt); ++extern int lwip_fcntl(int s, int cmd, int val); ++extern int lwip_ioctl(int s, long cmd, ...); ++extern int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); ++extern int lwip_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags); ++extern int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); ++extern int lwip_shutdown(int s, int how); ++extern int lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen); ++extern int lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen); ++extern int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); ++extern int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); ++extern int lwip_close(int s); ++extern int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); ++extern int lwip_listen(int s, int backlog); ++extern ssize_t lwip_recv(int s, void *mem, size_t len, int flags); ++extern ssize_t lwip_read(int s, void *mem, size_t len); ++extern ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt); ++extern ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags, ++ struct sockaddr *from, socklen_t *fromlen); ++extern ssize_t lwip_recvmsg(int s, const struct msghdr *message, int flags); ++extern ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags); ++extern ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags); ++extern ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, ++ const struct sockaddr *to, socklen_t tolen); ++extern int lwip_socket(int domain, int type, int protocol); ++extern ssize_t lwip_write(int s, const void *dataptr, size_t size); ++extern ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt); + + int rtc_poll(struct pollfd *fds, nfds_t nfds, int timeout); + int rtc_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout); +diff --git a/src/lstack/include/posix/lstack_epoll.h b/src/lstack/include/posix/lstack_epoll.h +index 699a951..c42f3a5 100644 +--- a/src/lstack/include/posix/lstack_epoll.h ++++ b/src/lstack/include/posix/lstack_epoll.h +@@ -73,8 +73,10 @@ void wakeup_stack_epoll(struct protocol_stack *stack); + + int32_t lstack_epoll_create(int32_t size); + int32_t lstack_epoll_create1(int32_t flags); +-int32_t lstack_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event *event); +-int32_t lstack_epoll_wait(int32_t epfd, struct epoll_event *events, int32_t maxevents, int32_t timeout); ++int32_t lstack_rtw_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event *event); ++int32_t lstack_rtc_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_event *event); ++int32_t lstack_rtw_epoll_wait(int32_t epfd, struct epoll_event *events, int32_t maxevents, int32_t timeout); ++int32_t lstack_rtc_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout); + int32_t lstack_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout); + + #ifdef __cplusplus +-- +2.27.0 + diff --git a/0027-clean-useless-code.patch b/0027-clean-useless-code.patch new file mode 100644 index 0000000..3be5e8a --- /dev/null +++ b/0027-clean-useless-code.patch @@ -0,0 +1,27 @@ +From 0398acfead1f6c118234559b3473ace2c5676015 Mon Sep 17 00:00:00 2001 +From: compile_success <980965867@qq.com> +Date: Thu, 26 Oct 2023 13:20:03 +0000 +Subject: [PATCH] clean useless code + +--- + src/lstack/core/lstack_dpdk.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index a53e85c..48fa67d 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -740,10 +740,6 @@ int32_t init_dpdk_ethdev(void) + return -1; + } + +- /* 20: sleep for lacp ,this is a temp plan, it will be changed in future */ +- int wait_lacp = 20; +- sleep(wait_lacp); +- + } else { + ret = dpdk_ethdev_init(0, 0); + if (ret != 0) { +-- +2.27.0 + diff --git a/0028-ethdev-fix-arp-unicast-packets-cannot-be-transmitted.patch b/0028-ethdev-fix-arp-unicast-packets-cannot-be-transmitted.patch new file mode 100644 index 0000000..0ed2539 --- /dev/null +++ b/0028-ethdev-fix-arp-unicast-packets-cannot-be-transmitted.patch @@ -0,0 +1,55 @@ +From aa2e11540cf897d2b1051ab33245e8c988618aaa Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Thu, 26 Oct 2023 17:45:56 +0800 +Subject: [PATCH] ethdev: fix arp unicast packets cannot be transmitted to + current procotol stack + +--- + src/lstack/core/lstack_protocol_stack.c | 8 ++++++++ + src/lstack/netif/lstack_ethdev.c | 11 ++--------- + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 0726054..511d2b9 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -837,6 +837,14 @@ void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack + return; + } + } ++ ret = dpdk_alloc_pktmbuf(stack->rxtx_pktmbuf_pool, &mbuf_copy, 1); ++ if (ret != 0) { ++ stack->stats.rx_allocmbuf_fail++; ++ return; ++ } ++ copy_mbuf(mbuf_copy, mbuf); ++ kni_handle_tx(mbuf_copy); ++ return; + } + + void stack_broadcast_clean_epoll(struct wakeup_poll *wakeup) +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 30c3c9a..f2353f8 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -780,15 +780,8 @@ int32_t gazelle_eth_dev_poll(struct protocol_stack *stack, uint8_t use_ltran_fla + struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(stack->pkts[i], struct rte_ether_hdr *); + if (unlikely(RTE_BE16(RTE_ETHER_TYPE_ARP) == ethh->ether_type)) { + stack_broadcast_arp(stack->pkts[i], stack); +-#if DPDK_VERSION_1911 +- if (!rte_is_broadcast_ether_addr(ðh->d_addr)) { +-#else /* DPDK_VERSION_1911 */ +- if (!rte_is_broadcast_ether_addr(ðh->dst_addr)) { +-#endif /* DPDK_VERSION_1911 */ +- // copy arp into other process +- transfer_arp_to_other_process(stack->pkts[i]); +- transfer_type = TRANSFER_KERNEL; +- } ++ /* copy arp into other process */ ++ transfer_arp_to_other_process(stack->pkts[i]); + } else { + if (get_global_cfg_params()->tuple_filter && stack->queue_id == 0) { + transfer_type = distribute_pakages(stack->pkts[i]); +-- +2.27.0 + diff --git a/0029-stack-add-semaphore-to-ensure-all-stack-threads-setu.patch b/0029-stack-add-semaphore-to-ensure-all-stack-threads-setu.patch new file mode 100644 index 0000000..394ce6a --- /dev/null +++ b/0029-stack-add-semaphore-to-ensure-all-stack-threads-setu.patch @@ -0,0 +1,102 @@ +From 24deab28953f33ab4dc1596291289b91b805b4de Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Thu, 26 Oct 2023 19:36:02 +0800 +Subject: [PATCH] stack: add semaphore to ensure all stack threads setup + success in rtw mode before call main() + +--- + src/lstack/core/lstack_protocol_stack.c | 19 +++++++++++++++++-- + src/lstack/include/lstack_protocol_stack.h | 2 ++ + src/lstack/netif/lstack_ethdev.c | 4 ++-- + 3 files changed, 21 insertions(+), 4 deletions(-) + +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 0726054..27e5005 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -289,6 +289,7 @@ static void* gazelle_kernelevent_thread(void *arg) + + LSTACK_LOG(INFO, LSTACK, "kernelevent_%02hu start\n", idx); + free(arg); ++ sem_post(&g_stack_group.sem_stack_setup); + + for (;;) { + stack->kernel_event_num = posix_api->epoll_wait_fn(stack->epollfd, stack->kernel_events, KERNEL_EPOLL_MAX, -1); +@@ -493,9 +494,12 @@ static void* gazelle_stack_thread(void *arg) + free(arg); + if (stack == NULL) { + LSTACK_LOG(ERR, LSTACK, "stack_thread_init failed queue_id=%hu\n", queue_id); +- /* exit in signal thread */ +- raise(SIGTERM); ++ g_stack_group.stack_setup_fail = 1; ++ sem_post(&g_stack_group.sem_stack_setup); ++ return NULL; + } ++ sem_post(&g_stack_group.sem_stack_setup); ++ + if (!use_ltran() && queue_id == 0) { + init_listen_and_user_ports(); + } +@@ -531,6 +535,11 @@ int32_t stack_group_init(void) + init_list_node(&stack_group->poll_list); + pthread_spin_init(&stack_group->poll_list_lock, PTHREAD_PROCESS_PRIVATE); + pthread_spin_init(&stack_group->socket_lock, PTHREAD_PROCESS_PRIVATE); ++ if (sem_init(&stack_group->sem_stack_setup, 0, 0) < 0) { ++ LSTACK_LOG(ERR, LSTACK, "sem_init failed errno=%d\n", errno); ++ return -1; ++ } ++ stack_group->stack_setup_fail = 0; + + if (get_global_cfg_params()->is_primary) { + uint32_t total_mbufs = get_global_cfg_params()->mbuf_count_per_conn * get_global_cfg_params()->tcp_conn_count; +@@ -622,6 +631,12 @@ int32_t stack_setup_thread(void) + } + } + ++ /* 2: wait stack thread and kernel_event thread init finish */ ++ wait_sem_value(&g_stack_group.sem_stack_setup, g_stack_group.stack_num * 2); ++ if (g_stack_group.stack_setup_fail) { ++ return -1; ++ } ++ + return 0; + } + +diff --git a/src/lstack/include/lstack_protocol_stack.h b/src/lstack/include/lstack_protocol_stack.h +index 4f1b127..2c581b3 100644 +--- a/src/lstack/include/lstack_protocol_stack.h ++++ b/src/lstack/include/lstack_protocol_stack.h +@@ -96,6 +96,8 @@ struct protocol_stack_group { + pthread_spinlock_t poll_list_lock; + sem_t sem_listen_thread; + struct rte_mempool *total_rxtx_pktmbuf_pool[PROTOCOL_STACK_MAX]; ++ sem_t sem_stack_setup; ++ bool stack_setup_fail; + + /* dfx stats */ + bool latency_start; +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 30c3c9a..b0dbba4 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -319,7 +319,7 @@ struct rte_flow *create_flow_director(uint16_t port_id, uint16_t queue_id, + if (!res) { + flow = rte_flow_create(port_id, &attr, pattern, action, error); + } else { +- LSTACK_LOG(ERR, PORT, "rte_flow_create.rte_flow_validate error, res %d \n", res); ++ LSTACK_LOG(ERR, LSTACK, "rte_flow_create.rte_flow_validate error, res %d \n", res); + } + + return flow; +@@ -364,7 +364,7 @@ void delete_flow_director(uint32_t dst_ip, uint16_t src_port, uint16_t dst_port) + struct rte_flow_error error; + int ret = rte_flow_destroy(port_id, fl->flow, &error); + if(ret != 0){ +- LSTACK_LOG(ERR, PORT, "Flow can't be delete %d message: %s\n", ++ LSTACK_LOG(ERR, LSTACK, "Flow can't be delete %d message: %s\n", + error.type, error.message ? error.message : "(no stated reason)"); + } + delete_rule(rule_key); +-- +2.27.0 + diff --git a/0030-ethdev-register-offload-to-netif.patch b/0030-ethdev-register-offload-to-netif.patch new file mode 100644 index 0000000..a3e8656 --- /dev/null +++ b/0030-ethdev-register-offload-to-netif.patch @@ -0,0 +1,29 @@ +From f15f4d7c178b35b41bab7c42162517e4142ae77a Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Fri, 27 Oct 2023 20:11:29 +0800 +Subject: [PATCH] ethdev: register offload to netif + +--- + src/lstack/netif/lstack_ethdev.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 6e4c9de..80932c8 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -895,6 +895,12 @@ static err_t eth_dev_init(struct netif *netif) + + netif->hwaddr_len = ETHER_ADDR_LEN; + ++ netif_set_rxol_flags(netif, get_protocol_stack_group()->rx_offload); ++ netif_set_txol_flags(netif, get_protocol_stack_group()->tx_offload); ++ if (get_global_cfg_params()->stack_mode_rtc) { ++ netif_set_rtc_mode(netif); ++ } ++ + return ERR_OK; + } + +-- +2.27.0 + diff --git a/0031-epoll-fix-epollet-mode-error.patch b/0031-epoll-fix-epollet-mode-error.patch new file mode 100644 index 0000000..a7a674a --- /dev/null +++ b/0031-epoll-fix-epollet-mode-error.patch @@ -0,0 +1,44 @@ +From c6cca5f100c09769a5d260e729f4c149be964ea4 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Sat, 28 Oct 2023 20:17:26 +0800 +Subject: [PATCH] epoll: fix epollet mode error + +--- + src/lstack/api/lstack_epoll.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c +index d1fb209..a711ae3 100644 +--- a/src/lstack/api/lstack_epoll.c ++++ b/src/lstack/api/lstack_epoll.c +@@ -468,22 +468,22 @@ int32_t epoll_lwip_event_nolock(struct wakeup_poll *wakeup, struct epoll_event * + continue; + } + ++ events[event_num].events = sock->events & sock->epoll_events; ++ events[event_num].data = sock->ep_data; ++ event_num++; ++ + if (sock->epoll_events & EPOLLET) { + list_del_node_null(node); + sock->events = 0; + } + + /* EPOLLONESHOT: generate event after epoll_ctl add/mod event again +- epoll_event set 0 avoid generating event util epoll_ctl set epoll_event a valu */ ++ epoll_event set 0 avoid generating event util epoll_ctl reset epoll_event */ + if (sock->epoll_events & EPOLLONESHOT) { + list_del_node_null(node); + sock->epoll_events = 0; + } + +- events[event_num].events = sock->events & sock->epoll_events; +- events[event_num].data = sock->ep_data; +- event_num++; +- + if (event_num >= maxevents) { + /* move list head after the current node, and start traversing from this node next time */ + list_del_node_null(&wakeup->event_list); +-- +2.27.0 + diff --git a/0032-bond6.patch b/0032-bond6.patch new file mode 100644 index 0000000..3933e16 --- /dev/null +++ b/0032-bond6.patch @@ -0,0 +1,210 @@ +From c3cc06b64d2da294001289d7610f186a6af7a8c4 Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Mon, 30 Oct 2023 21:52:29 +0800 +Subject: [PATCH] bond6 + +--- + src/lstack/core/lstack_cfg.c | 34 +++++++++++++++++++++------------ + src/lstack/core/lstack_dpdk.c | 33 +++++++++++++++++++------------- + src/lstack/include/lstack_cfg.h | 6 +++--- + 3 files changed, 45 insertions(+), 28 deletions(-) + +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index ad89bca..c4278b5 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -24,6 +24,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -70,8 +71,8 @@ static int32_t parse_process_numa(void); + static int32_t parse_process_index(void); + static int32_t parse_seperate_sendrecv_args(void); + static int32_t parse_tuple_filter(void); +-static int32_t parse_use_bond4(void); +-static int32_t parse_bond4_slave_mac(void); ++static int32_t parse_bond_mode(void); ++static int32_t parse_bond_slave_mac(void); + static int32_t parse_use_sockmap(void); + static int32_t parse_udp_enable(void); + static int32_t parse_nic_rxqueue_size(void); +@@ -130,8 +131,8 @@ static struct config_vector_t g_config_tbl[] = { + { "process_numa", parse_process_numa }, + { "process_idx", parse_process_index }, + { "tuple_filter", parse_tuple_filter }, +- { "use_bond4", parse_use_bond4 }, +- { "bond4_slave_mac", parse_bond4_slave_mac }, ++ { "bond_mode", parse_bond_mode }, ++ { "bond_slave_mac", parse_bond_slave_mac }, + { "use_sockmap", parse_use_sockmap }, + { "udp_enable", parse_udp_enable }, + { "nic_rxqueue_size", parse_nic_rxqueue_size}, +@@ -1114,16 +1115,25 @@ static int32_t parse_udp_enable(void) + return ret; + } + +-static int32_t parse_use_bond4(void) ++static int32_t parse_bond_mode(void) + { +- int32_t ret; +- PARSE_ARG(g_config_params.use_bond4, "use_bond4", 0, 0, 1, ret); +- return ret; ++ const config_setting_t *bond_mode = NULL; ++ bond_mode = config_lookup(&g_config, "bond_mode"); ++ g_config_params.bond_mode = config_setting_get_int(bond_mode); ++ if (g_config_params.bond_mode == -1) { ++ return 0; ++ } ++ if (g_config_params.bond_mode != BONDING_MODE_8023AD && g_config_params.bond_mode != BONDING_MODE_ALB) { ++ LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid bond mode = %d. only supports bond mode = 4,6.\n", ++ g_config_params.bond_mode); ++ return -EINVAL; ++ } ++ return 0; + } + +-static int32_t parse_bond4_slave_mac(void) ++static int32_t parse_bond_slave_mac(void) + { +- if (g_config_params.use_bond4 == 0) { ++ if (g_config_params.bond_mode == -1) { + return 0; + } + +@@ -1151,13 +1161,13 @@ static int32_t parse_bond4_slave_mac(void) + } + + /* add dev */ +- ret = str_to_eth_addr(slave_mac1, g_config_params.bond4_slave1_mac_addr); ++ ret = str_to_eth_addr(slave_mac1, g_config_params.bond_slave1_mac_addr); + if (ret != 0) { + LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid device name %s ret=%d.\n", slave_mac1, ret); + return ret; + } + +- ret = str_to_eth_addr(slave_mac2, g_config_params.bond4_slave2_mac_addr); ++ ret = str_to_eth_addr(slave_mac2, g_config_params.bond_slave2_mac_addr); + if (ret != 0) { + LSTACK_PRE_LOG(LSTACK_ERR, "cfg: invalid device name %s ret=%d.\n", slave_mac2, ret); + } +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 48fa67d..1a5b568 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -463,7 +463,6 @@ static void rss_setup(const int port_id, const uint16_t nb_queues) + int32_t dpdk_ethdev_init(int port_id, bool bond_port) + { + uint16_t nb_queues = get_global_cfg_params()->num_cpu; +- int32_t use_bond4 = get_global_cfg_params()->use_bond4; + if (get_global_cfg_params()->seperate_send_recv) { + nb_queues = get_global_cfg_params()->num_cpu * 2; + } +@@ -474,7 +473,7 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + + struct protocol_stack_group *stack_group = get_protocol_stack_group(); + +- if (!use_bond4) { ++ if (get_global_cfg_params()->bond_mode < 0) { + port_id = ethdev_port_id(get_global_cfg_params()->mac_addr); + if (port_id < 0) { + return port_id; +@@ -499,13 +498,13 @@ int32_t dpdk_ethdev_init(int port_id, bool bond_port) + if (bond_port) { + int slave_num = 2; + int32_t slave_port_id[2]; +- slave_port_id[0] = ethdev_port_id(get_global_cfg_params()->bond4_slave1_mac_addr); ++ slave_port_id[0] = ethdev_port_id(get_global_cfg_params()->bond_slave1_mac_addr); + if (slave_port_id[0] < 0) { + LSTACK_LOG(ERR, LSTACK, "get slave port id failed port = %d\n", slave_port_id[0]); + return slave_port_id[0]; + } + +- slave_port_id[1] = ethdev_port_id(get_global_cfg_params()->bond4_slave2_mac_addr); ++ slave_port_id[1] = ethdev_port_id(get_global_cfg_params()->bond_slave2_mac_addr); + if (slave_port_id[1] < 0) { + LSTACK_LOG(ERR, LSTACK, "get slave port id failed port = %d\n", slave_port_id[1]); + return slave_port_id[1]; +@@ -648,7 +647,7 @@ int32_t dpdk_ethdev_start(void) + } + } + +- if (get_global_cfg_params()->use_bond4) { ++ if (get_global_cfg_params()->bond_mode >= 0) { + return 0; + } + +@@ -697,15 +696,16 @@ int32_t init_dpdk_ethdev(void) + { + int32_t ret; + +- if (get_global_cfg_params()->use_bond4) { +- int bond_port_id = rte_eth_bond_create("net_bonding0", 4, (uint8_t)rte_socket_id()); ++ if (get_global_cfg_params()->bond_mode >= 0) { ++ uint8_t socket_id = rte_socket_id(); ++ int bond_port_id = rte_eth_bond_create("net_bonding0", get_global_cfg_params()->bond_mode, socket_id); + if (bond_port_id < 0) { + LSTACK_LOG(ERR, LSTACK, "get bond port id failed ret=%d\n", bond_port_id); + return bond_port_id; + } + + ret = dpdk_ethdev_init(bond_port_id, 1); +- if (ret != 0) { ++ if (ret != 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk_ethdev_init failed ret = %d\n", ret); + return -1; + } +@@ -716,10 +716,17 @@ int32_t init_dpdk_ethdev(void) + return -1; + } + +- ret = rte_eth_bond_8023ad_dedicated_queues_enable(bond_port_id); +- if (ret < 0) { +- LSTACK_LOG(ERR, LSTACK, "dpdk enable 8023 dedicated queues failed ret = %d\n", ret); +- return -1; ++ if (get_global_cfg_params()->bond_mode == BONDING_MODE_8023AD) { ++ ret = rte_eth_bond_8023ad_dedicated_queues_enable(bond_port_id); ++ if (ret < 0) { ++ LSTACK_LOG(ERR, LSTACK, "dpdk enable 8023 dedicated queues failed ret = %d\n", ret); ++ return -1; ++ } ++ } else { ++ ret = rte_eth_bond_mode_set(bond_port_id, get_global_cfg_params()->bond_mode); ++ if (ret < 0) { ++ LSTACK_LOG(ERR, LSTACK, "dpdk enable mode set failed ret = %d\n", ret); ++ } + } + + ret = rte_eth_promiscuous_enable(bond_port_id); +@@ -735,7 +742,7 @@ int32_t init_dpdk_ethdev(void) + } + + ret = rte_eth_dev_start(bond_port_id); +- if (ret < 0) { ++ if (ret < 0) { + LSTACK_LOG(ERR, LSTACK, "dpdk start bond port failed ret = %d\n", ret); + return -1; + } +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index 1d895ec..fc627e3 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -110,9 +110,9 @@ struct cfg_params { + uint16_t send_ring_size; + bool expand_send_ring; + bool tuple_filter; +- bool use_bond4; +- uint8_t bond4_slave1_mac_addr[ETHER_ADDR_LEN]; +- uint8_t bond4_slave2_mac_addr[ETHER_ADDR_LEN]; ++ int8_t bond_mode; ++ uint8_t bond_slave1_mac_addr[ETHER_ADDR_LEN]; ++ uint8_t bond_slave2_mac_addr[ETHER_ADDR_LEN]; + bool use_sockmap; + bool udp_enable; + struct cfg_nic_params nic; +-- +2.27.0 + diff --git a/gazelle.spec b/gazelle.spec index e88a2e1..8245bc6 100644 --- a/gazelle.spec +++ b/gazelle.spec @@ -2,7 +2,7 @@ Name: gazelle Version: 1.0.2 -Release: 9 +Release: 10 Summary: gazelle is a high performance user-mode stack License: MulanPSL-2.0 URL: https://gitee.com/openeuler/gazelle @@ -41,6 +41,13 @@ Patch9022: 0022-tools-gazelle_setup-adapt-non-ltran-mode.patch Patch9023: 0023-wrap-add-run-to-completion-wakeup-mode-api.patch Patch9024: 0024-fix-arping-gazelle-return-value-is-1.patch Patch9025: 0025-init-stack-setup-in-app-thread-when-app-call-socket-.patch +Patch9026: 0026-epoll-adapt-epoll-interface-for-rtc-mode.patch +Patch9027: 0027-clean-useless-code.patch +Patch9028: 0028-ethdev-fix-arp-unicast-packets-cannot-be-transmitted.patch +Patch9029: 0029-stack-add-semaphore-to-ensure-all-stack-threads-setu.patch +Patch9030: 0030-ethdev-register-offload-to-netif.patch +Patch9031: 0031-epoll-fix-epollet-mode-error.patch +Patch9032: 0032-bond6.patch %description %{name} is a high performance user-mode stack. @@ -82,6 +89,15 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b %config(noreplace) %{conf_path}/ltran.conf %changelog +* Sat Nov 4 2023 yinbin6 - 1.0.2-10 +- bond6 +- epoll: fix epollet mode error +- ethdev: register offload to netif +- stack: add semaphore to ensure all stack threads setup success in rtw mode before call main() +- ethdev: fix arp unicast packets cannot be transmitted to current procotol stack +- clean useless code +- epoll: adapt epoll interface for rtc mode + * Sat Nov 4 2023 yinbin6 - 1.0.2-9 - init: stack setup in app thread when app call socket/epoll_create first in rtc mode - fix arping gazelle return value is 1