1From 71d82a830005540ef92b2bcd7c121c9ff85beb64 Mon Sep 17 00:00:00 2001 2From: j00660176 <jiangheng14@huawei.com> 3Date: Mon, 12 Jun 2023 20:21:23 +0800 4Subject: [PATCH] fix udp send/recv in multiple queue 5 6--- 7 src/core/udp.c | 73 +++++++++++++++++++++++++++++++++++++++--- 8 src/include/lwip/udp.h | 4 +++ 9 2 files changed, 73 insertions(+), 4 deletions(-) 10 11diff --git a/src/core/udp.c b/src/core/udp.c 12index fba645b..0b1fa65 100644 13--- a/src/core/udp.c 14+++ b/src/core/udp.c 15@@ -65,10 +65,12 @@ 16 17 #include <string.h> 18 19-#if GAZELLE_ENABLE 20-#include "lwipsock.h" 21+#if GAZELLE_UDP_ENABLE 22+#include <pthread.h> 23 #include <rte_prefetch.h> 24+#include "lwipsock.h" 25 #include "dpdk_cksum.h" 26+#include "reg_sock.h" 27 #endif 28 29 #ifndef UDP_LOCAL_PORT_RANGE_START 30@@ -81,10 +83,24 @@ 31 32 /* last local UDP port */ 33 static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; 34+#if GAZELLE_UDP_ENABLE 35+static pthread_mutex_t g_udp_port_mutex = PTHREAD_MUTEX_INITIALIZER; 36+static u8_t port_state[UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START + 1] = {0}; 37+static void udp_release_port(u16_t port) 38+{ 39+ if (port >= UDP_LOCAL_PORT_RANGE_START && port <= UDP_LOCAL_PORT_RANGE_END) { 40+ port_state[port - UDP_LOCAL_PORT_RANGE_START] = 0; 41+ } 42+} 43+#endif 44 45 /* The list of UDP PCBs */ 46 /* exported in udp.h (was static) */ 47+#if GAZELLE_UDP_ENABLE 48+PER_THREAD struct udp_pcb *udp_pcbs; 49+#else 50 struct udp_pcb *udp_pcbs; 51+#endif 52 53 /** 54 * Initialize this module. 55@@ -102,6 +118,37 @@ udp_init(void) 56 * 57 * @return a new (free) local UDP port number 58 */ 59+#if GAZELLE_UDP_ENABLE 60+static u16_t 61+udp_new_port(struct udp_pcb *dst_pcb) 62+{ 63+ u16_t n = 0; 64+ u16_t tmp_port = 0; 65+ 66+ pthread_mutex_lock(&g_udp_port_mutex); 67+ do { 68+ if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { 69+ udp_port = UDP_LOCAL_PORT_RANGE_START; 70+ } 71+ 72+ if (__atomic_load_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) { 73+ if (port_in_stack_queue(dst_pcb->remote_ip.addr, dst_pcb->local_ip.addr, dst_pcb->remote_port, udp_port)) { 74+ tmp_port = udp_port; 75+ __atomic_store_n(&port_state[udp_port - UDP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE); 76+ break; 77+ } 78+ } 79+ n++; 80+ if (n > UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START) { 81+ break; 82+ } 83+ } while (tmp_port == 0); 84+ 85+ pthread_mutex_unlock(&g_udp_port_mutex); 86+ 87+ return tmp_port; 88+} 89+#else 90 static u16_t 91 udp_new_port(void) 92 { 93@@ -123,6 +170,7 @@ again: 94 } 95 return udp_port; 96 } 97+#endif 98 99 /** Common code to see if the current input packet matches the pcb 100 * (current input packet is accessed via ip(4/6)_current_* macros) 101@@ -789,7 +837,21 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d 102 /* if the PCB is not yet bound to a port, bind it here */ 103 if (pcb->local_port == 0) { 104 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); 105+#if GAZELLE_UDP_ENABLE 106+ ip_addr_t tmp_local_ip = pcb->local_ip; 107+ ip_addr_t tmp_remote_ip = pcb->remote_ip; 108+ u16_t tmp_remote_port = pcb->remote_port; 109+ 110+ pcb->local_ip = netif->ip_addr; 111+ pcb->remote_port = dst_port; 112+ pcb->remote_ip = *dst_ip; 113+#endif 114 err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); 115+#if GAZELLE_UDP_ENABLE 116+ pcb->local_ip = tmp_local_ip; 117+ pcb->remote_ip = tmp_remote_ip; 118+ pcb->remote_port = tmp_remote_port; 119+#endif 120 if (err != ERR_OK) { 121 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); 122 return err; 123@@ -941,7 +1003,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d 124 /* @todo: must this be increased even if error occurred? */ 125 MIB2_STATS_INC(mib2.udpoutdatagrams); 126 127-#if !GAZELLE_ENABLE 128+#if !GAZELLE_UDP_ENABLE 129 /* did we chain a separate header pbuf earlier? */ 130 if (q != p) 131 #endif 132@@ -1026,7 +1088,7 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) 133 134 /* no port specified? */ 135 if (port == 0) { 136- port = udp_new_port(); 137+ port = udp_new_port(pcb); 138 if (port == 0) { 139 /* no more ports available in local range */ 140 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); 141@@ -1252,6 +1314,9 @@ udp_remove(struct udp_pcb *pcb) 142 } 143 } 144 } 145+#if GAZELLE_UDP_ENABLE 146+ udp_release_port(pcb->local_port); 147+#endif 148 memp_free(MEMP_UDP_PCB, pcb); 149 } 150 151diff --git a/src/include/lwip/udp.h b/src/include/lwip/udp.h 152index b1c78e5..f588d90 100644 153--- a/src/include/lwip/udp.h 154+++ b/src/include/lwip/udp.h 155@@ -112,7 +112,11 @@ struct udp_pcb { 156 void *recv_arg; 157 }; 158 /* udp_pcbs export for external reference (e.g. SNMP agent) */ 159+#if GAZELLE_UDP_ENABLE 160+extern PER_THREAD struct udp_pcb *udp_pcbs; 161+#else 162 extern struct udp_pcb *udp_pcbs; 163+#endif 164 165 /* The following functions is the application layer interface to the 166 UDP code. */ 167-- 1682.33.0 169 170