1195972f6Sopenharmony_ciFrom 71d82a830005540ef92b2bcd7c121c9ff85beb64 Mon Sep 17 00:00:00 2001 2195972f6Sopenharmony_ciFrom: j00660176 <jiangheng14@huawei.com> 3195972f6Sopenharmony_ciDate: Mon, 12 Jun 2023 20:21:23 +0800 4195972f6Sopenharmony_ciSubject: [PATCH] fix udp send/recv in multiple queue 5195972f6Sopenharmony_ci 6195972f6Sopenharmony_ci--- 7195972f6Sopenharmony_ci src/core/udp.c | 73 +++++++++++++++++++++++++++++++++++++++--- 8195972f6Sopenharmony_ci src/include/lwip/udp.h | 4 +++ 9195972f6Sopenharmony_ci 2 files changed, 73 insertions(+), 4 deletions(-) 10195972f6Sopenharmony_ci 11195972f6Sopenharmony_cidiff --git a/src/core/udp.c b/src/core/udp.c 12195972f6Sopenharmony_ciindex fba645b..0b1fa65 100644 13195972f6Sopenharmony_ci--- a/src/core/udp.c 14195972f6Sopenharmony_ci+++ b/src/core/udp.c 15195972f6Sopenharmony_ci@@ -65,10 +65,12 @@ 16195972f6Sopenharmony_ci 17195972f6Sopenharmony_ci #include <string.h> 18195972f6Sopenharmony_ci 19195972f6Sopenharmony_ci-#if GAZELLE_ENABLE 20195972f6Sopenharmony_ci-#include "lwipsock.h" 21195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE 22195972f6Sopenharmony_ci+#include <pthread.h> 23195972f6Sopenharmony_ci #include <rte_prefetch.h> 24195972f6Sopenharmony_ci+#include "lwipsock.h" 25195972f6Sopenharmony_ci #include "dpdk_cksum.h" 26195972f6Sopenharmony_ci+#include "reg_sock.h" 27195972f6Sopenharmony_ci #endif 28195972f6Sopenharmony_ci 29195972f6Sopenharmony_ci #ifndef UDP_LOCAL_PORT_RANGE_START 30195972f6Sopenharmony_ci@@ -81,10 +83,24 @@ 31195972f6Sopenharmony_ci 32195972f6Sopenharmony_ci /* last local UDP port */ 33195972f6Sopenharmony_ci static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; 34195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE 35195972f6Sopenharmony_ci+static pthread_mutex_t g_udp_port_mutex = PTHREAD_MUTEX_INITIALIZER; 36195972f6Sopenharmony_ci+static u8_t port_state[UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START + 1] = {0}; 37195972f6Sopenharmony_ci+static void udp_release_port(u16_t port) 38195972f6Sopenharmony_ci+{ 39195972f6Sopenharmony_ci+ if (port >= UDP_LOCAL_PORT_RANGE_START && port <= UDP_LOCAL_PORT_RANGE_END) { 40195972f6Sopenharmony_ci+ port_state[port - UDP_LOCAL_PORT_RANGE_START] = 0; 41195972f6Sopenharmony_ci+ } 42195972f6Sopenharmony_ci+} 43195972f6Sopenharmony_ci+#endif 44195972f6Sopenharmony_ci 45195972f6Sopenharmony_ci /* The list of UDP PCBs */ 46195972f6Sopenharmony_ci /* exported in udp.h (was static) */ 47195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE 48195972f6Sopenharmony_ci+PER_THREAD struct udp_pcb *udp_pcbs; 49195972f6Sopenharmony_ci+#else 50195972f6Sopenharmony_ci struct udp_pcb *udp_pcbs; 51195972f6Sopenharmony_ci+#endif 52195972f6Sopenharmony_ci 53195972f6Sopenharmony_ci /** 54195972f6Sopenharmony_ci * Initialize this module. 55195972f6Sopenharmony_ci@@ -102,6 +118,37 @@ udp_init(void) 56195972f6Sopenharmony_ci * 57195972f6Sopenharmony_ci * @return a new (free) local UDP port number 58195972f6Sopenharmony_ci */ 59195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE 60195972f6Sopenharmony_ci+static u16_t 61195972f6Sopenharmony_ci+udp_new_port(struct udp_pcb *dst_pcb) 62195972f6Sopenharmony_ci+{ 63195972f6Sopenharmony_ci+ u16_t n = 0; 64195972f6Sopenharmony_ci+ u16_t tmp_port = 0; 65195972f6Sopenharmony_ci+ 66195972f6Sopenharmony_ci+ pthread_mutex_lock(&g_udp_port_mutex); 67195972f6Sopenharmony_ci+ do { 68195972f6Sopenharmony_ci+ if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { 69195972f6Sopenharmony_ci+ udp_port = UDP_LOCAL_PORT_RANGE_START; 70195972f6Sopenharmony_ci+ } 71195972f6Sopenharmony_ci+ 72195972f6Sopenharmony_ci+ if (__atomic_load_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) { 73195972f6Sopenharmony_ci+ if (port_in_stack_queue(dst_pcb->remote_ip.addr, dst_pcb->local_ip.addr, dst_pcb->remote_port, udp_port)) { 74195972f6Sopenharmony_ci+ tmp_port = udp_port; 75195972f6Sopenharmony_ci+ __atomic_store_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE); 76195972f6Sopenharmony_ci+ break; 77195972f6Sopenharmony_ci+ } 78195972f6Sopenharmony_ci+ } 79195972f6Sopenharmony_ci+ n++; 80195972f6Sopenharmony_ci+ if (n > UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START) { 81195972f6Sopenharmony_ci+ break; 82195972f6Sopenharmony_ci+ } 83195972f6Sopenharmony_ci+ } while (tmp_port == 0); 84195972f6Sopenharmony_ci+ 85195972f6Sopenharmony_ci+ pthread_mutex_unlock(&g_udp_port_mutex); 86195972f6Sopenharmony_ci+ 87195972f6Sopenharmony_ci+ return tmp_port; 88195972f6Sopenharmony_ci+} 89195972f6Sopenharmony_ci+#else 90195972f6Sopenharmony_ci static u16_t 91195972f6Sopenharmony_ci udp_new_port(void) 92195972f6Sopenharmony_ci { 93195972f6Sopenharmony_ci@@ -123,6 +170,7 @@ again: 94195972f6Sopenharmony_ci } 95195972f6Sopenharmony_ci return udp_port; 96195972f6Sopenharmony_ci } 97195972f6Sopenharmony_ci+#endif 98195972f6Sopenharmony_ci 99195972f6Sopenharmony_ci /** Common code to see if the current input packet matches the pcb 100195972f6Sopenharmony_ci * (current input packet is accessed via ip(4/6)_current_* macros) 101195972f6Sopenharmony_ci@@ -789,7 +837,21 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d 102195972f6Sopenharmony_ci /* if the PCB is not yet bound to a port, bind it here */ 103195972f6Sopenharmony_ci if (pcb->local_port == 0) { 104195972f6Sopenharmony_ci LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); 105195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE 106195972f6Sopenharmony_ci+ ip_addr_t tmp_local_ip = pcb->local_ip; 107195972f6Sopenharmony_ci+ ip_addr_t tmp_remote_ip = pcb->remote_ip; 108195972f6Sopenharmony_ci+ u16_t tmp_remote_port = pcb->remote_port; 109195972f6Sopenharmony_ci+ 110195972f6Sopenharmony_ci+ pcb->local_ip = netif->ip_addr; 111195972f6Sopenharmony_ci+ pcb->remote_port = dst_port; 112195972f6Sopenharmony_ci+ pcb->remote_ip = *dst_ip; 113195972f6Sopenharmony_ci+#endif 114195972f6Sopenharmony_ci err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); 115195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE 116195972f6Sopenharmony_ci+ pcb->local_ip = tmp_local_ip; 117195972f6Sopenharmony_ci+ pcb->remote_ip = tmp_remote_ip; 118195972f6Sopenharmony_ci+ pcb->remote_port = tmp_remote_port; 119195972f6Sopenharmony_ci+#endif 120195972f6Sopenharmony_ci if (err != ERR_OK) { 121195972f6Sopenharmony_ci LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); 122195972f6Sopenharmony_ci return err; 123195972f6Sopenharmony_ci@@ -941,7 +1003,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d 124195972f6Sopenharmony_ci /* @todo: must this be increased even if error occurred? */ 125195972f6Sopenharmony_ci MIB2_STATS_INC(mib2.udpoutdatagrams); 126195972f6Sopenharmony_ci 127195972f6Sopenharmony_ci-#if !GAZELLE_ENABLE 128195972f6Sopenharmony_ci+#if !GAZELLE_UDP_ENABLE 129195972f6Sopenharmony_ci /* did we chain a separate header pbuf earlier? */ 130195972f6Sopenharmony_ci if (q != p) 131195972f6Sopenharmony_ci #endif 132195972f6Sopenharmony_ci@@ -1026,7 +1088,7 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) 133195972f6Sopenharmony_ci 134195972f6Sopenharmony_ci /* no port specified? */ 135195972f6Sopenharmony_ci if (port == 0) { 136195972f6Sopenharmony_ci- port = udp_new_port(); 137195972f6Sopenharmony_ci+ port = udp_new_port(pcb); 138195972f6Sopenharmony_ci if (port == 0) { 139195972f6Sopenharmony_ci /* no more ports available in local range */ 140195972f6Sopenharmony_ci LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); 141195972f6Sopenharmony_ci@@ -1252,6 +1314,9 @@ udp_remove(struct udp_pcb *pcb) 142195972f6Sopenharmony_ci } 143195972f6Sopenharmony_ci } 144195972f6Sopenharmony_ci } 145195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE 146195972f6Sopenharmony_ci+ udp_release_port(pcb->local_port); 147195972f6Sopenharmony_ci+#endif 148195972f6Sopenharmony_ci memp_free(MEMP_UDP_PCB, pcb); 149195972f6Sopenharmony_ci } 150195972f6Sopenharmony_ci 151195972f6Sopenharmony_cidiff --git a/src/include/lwip/udp.h b/src/include/lwip/udp.h 152195972f6Sopenharmony_ciindex b1c78e5..f588d90 100644 153195972f6Sopenharmony_ci--- a/src/include/lwip/udp.h 154195972f6Sopenharmony_ci+++ b/src/include/lwip/udp.h 155195972f6Sopenharmony_ci@@ -112,7 +112,11 @@ struct udp_pcb { 156195972f6Sopenharmony_ci void *recv_arg; 157195972f6Sopenharmony_ci }; 158195972f6Sopenharmony_ci /* udp_pcbs export for external reference (e.g. SNMP agent) */ 159195972f6Sopenharmony_ci+#if GAZELLE_UDP_ENABLE 160195972f6Sopenharmony_ci+extern PER_THREAD struct udp_pcb *udp_pcbs; 161195972f6Sopenharmony_ci+#else 162195972f6Sopenharmony_ci extern struct udp_pcb *udp_pcbs; 163195972f6Sopenharmony_ci+#endif 164195972f6Sopenharmony_ci 165195972f6Sopenharmony_ci /* The following functions is the application layer interface to the 166195972f6Sopenharmony_ci UDP code. */ 167195972f6Sopenharmony_ci-- 168195972f6Sopenharmony_ci2.33.0 169195972f6Sopenharmony_ci 170