• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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