1From be56e9eed8acf82a862d19ef4f890f309018ddde Mon Sep 17 00:00:00 2001 2From: jiangheng <jiangheng14@huawei.com> 3Date: Sat, 28 Oct 2023 17:21:46 +0800 4Subject: [PATCH] adapt read/write for rtc mode 5 6--- 7 src/api/api_msg.c | 14 ++-- 8 src/api/sockets.c | 21 ++--- 9 src/core/init.c | 2 +- 10 src/core/pbuf.c | 7 ++ 11 src/core/tcp_out.c | 171 +++++++++++++++++++++++++++++++++-------- 12 src/core/udp.c | 2 +- 13 src/include/lwip/tcp.h | 4 + 14 src/include/lwipopts.h | 6 +- 15 8 files changed, 174 insertions(+), 53 deletions(-) 16 17diff --git a/src/api/api_msg.c b/src/api/api_msg.c 18index 3e982ab..d8b99ee 100644 19--- a/src/api/api_msg.c 20+++ b/src/api/api_msg.c 21@@ -1753,11 +1753,15 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) 22 write_more = 0; 23 } 24 #if GAZELLE_ENABLE 25- /* vector->ptr is private arg sock */ 26- LWIP_UNUSED_ARG(dataptr); 27- write_more = 0; 28- err = tcp_write(conn->pcb.tcp, conn->current_msg->msg.w.vector->ptr, len, apiflags); 29- conn->current_msg->msg.w.len = len; 30+ if (netif_is_rtc_mode(netif_default)) { 31+ err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); 32+ } else { 33+ /* vector->ptr is private arg sock */ 34+ LWIP_UNUSED_ARG(dataptr); 35+ write_more = 0; 36+ err = tcp_write_from_stack(conn->pcb.tcp, conn->current_msg->msg.w.vector->ptr, len, apiflags); 37+ conn->current_msg->msg.w.len = len; 38+ } 39 conn->pcb.tcp->need_tso_send = 1; 40 #else 41 err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); 42diff --git a/src/api/sockets.c b/src/api/sockets.c 43index 8d573aa..e374f96 100644 44--- a/src/api/sockets.c 45+++ b/src/api/sockets.c 46@@ -1087,7 +1087,15 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) 47 apiflags |= NETCONN_DONTBLOCK; 48 } 49 50-#if !GAZELLE_ENABLE 51+#if GAZELLE_ENABLE 52+ if (!netif_is_rtc_mode(netif_default)) { 53+ LWIP_UNUSED_ARG(recv_left); 54+ recvd = do_lwip_read_from_lwip(sock, flags, apiflags); 55+ if (recvd <= 0) { 56+ return recvd; 57+ } 58+ } else { 59+#endif 60 do { 61 struct pbuf *p; 62 err_t err; 63@@ -1166,15 +1174,10 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) 64 apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN; 65 /* @todo: do we need to support peeking more than one pbuf? */ 66 } while ((recv_left > 0) && !(flags & MSG_PEEK)); 67- 68-lwip_recv_tcp_done: 69-#else /* GAZELLE_ENABLE */ 70- LWIP_UNUSED_ARG(recv_left); 71- recvd = do_lwip_read_from_lwip(sock, flags, apiflags); 72- if (recvd <= 0) { 73- return recvd; 74+#if GAZELLE_ENABLE 75 } 76-#endif /* GAZELLE_ENABLE */ 77+#endif 78+lwip_recv_tcp_done: 79 if (apiflags & NETCONN_NOAUTORCVD) { 80 if ((recvd > 0) && !(flags & MSG_PEEK)) { 81 /* ensure window update after copying all data */ 82diff --git a/src/core/init.c b/src/core/init.c 83index 7b6214f..60e1c68 100644 84--- a/src/core/init.c 85+++ b/src/core/init.c 86@@ -306,7 +306,7 @@ PACK_STRUCT_END 87 #if TCP_SNDLOWAT >= TCP_SND_BUF 88 #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." 89 #endif 90-#if TCP_SNDLOWAT >= (0xFFFFFFFF - (4 * TCP_MSS)) 91+#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS)) 92 #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!" 93 #endif 94 #if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN 95diff --git a/src/core/pbuf.c b/src/core/pbuf.c 96index 975e240..61690ff 100644 97--- a/src/core/pbuf.c 98+++ b/src/core/pbuf.c 99@@ -117,6 +117,7 @@ pbuf_skip_const(const struct pbuf *in, u16_t in_offset, u16_t *out_offset); 100 volatile u8_t pbuf_free_ooseq_pending; 101 #define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() 102 103+#if !GAZELLE_ENABLE 104 /** 105 * Attempt to reclaim some memory from queued out-of-sequence TCP segments 106 * if we run out of pool pbufs. It's better to give priority to new packets 107@@ -176,6 +177,7 @@ pbuf_pool_is_empty(void) 108 } 109 #endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ 110 } 111+#endif /* GAZELLE_ENABLE */ 112 #endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ 113 114 /* Initialize members of struct pbuf after allocation */ 115@@ -238,6 +240,10 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) 116 p = pbuf_alloc_reference(NULL, length, type); 117 break; 118 case PBUF_POOL: { 119+#if GAZELLE_ENABLE 120+ // alloc from pktmbuf pool, one pbuf is enough 121+ p = do_lwip_alloc_pbuf(layer, length, type); 122+#else 123 struct pbuf *q, *last; 124 u16_t rem_len; /* remaining length */ 125 p = NULL; 126@@ -273,6 +279,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) 127 rem_len = (u16_t)(rem_len - qlen); 128 offset = 0; 129 } while (rem_len > 0); 130+#endif /* GAZELLE_ENABLE */ 131 break; 132 } 133 case PBUF_RAM: { 134diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c 135index e2c9d63..073d989 100644 136--- a/src/core/tcp_out.c 137+++ b/src/core/tcp_out.c 138@@ -515,15 +515,18 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 139 * pos records progress as data is segmented. 140 */ 141 142-#if !GAZELLE_ENABLE 143 /* Find the tail of the unsent queue. */ 144 if (pcb->unsent != NULL) { 145 u16_t space; 146 u16_t unsent_optlen; 147 148+#if GAZELLE_ENABLE 149+ last_unsent = pcb->last_unsent; 150+#else 151 /* @todo: this could be sped up by keeping last_unsent in the pcb */ 152 for (last_unsent = pcb->unsent; last_unsent->next != NULL; 153 last_unsent = last_unsent->next); 154+#endif 155 156 /* Usable space at the end of the last unsent segment */ 157 unsent_optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(last_unsent->flags, pcb); 158@@ -631,9 +634,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 159 pcb->unsent_oversize == 0); 160 #endif /* TCP_OVERSIZE */ 161 } 162-#else /* GAZELLE_ENABLE */ 163- last_unsent = pcb->last_unsent; 164-#endif /* GAZELLE_ENABLE */ 165 166 /* 167 * Phase 3: Create new segments. 168@@ -651,7 +651,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 169 u8_t chksum_swapped = 0; 170 #endif /* TCP_CHECKSUM_ON_COPY */ 171 172-#if !GAZELLE_ENABLE 173 if (apiflags & TCP_WRITE_FLAG_COPY) { 174 /* If copy is set, memory should be allocated and data copied 175 * into pbuf */ 176@@ -698,13 +697,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 177 /* Concatenate the headers and data pbufs together. */ 178 pbuf_cat(p/*header*/, p2/*data*/); 179 } 180-#else /* GAZELLE_ENABLE */ 181- p = do_lwip_get_from_sendring((struct lwip_sock *)arg, len - pos, &apiflags); 182- if (p == NULL) { 183- break; 184- } 185- seglen = p->tot_len; 186-#endif /* GAZELLE_ENABLE */ 187 188 queuelen += pbuf_clen(p); 189 190@@ -714,14 +706,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 191 if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) { 192 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", 193 queuelen, (int)TCP_SND_QUEUELEN)); 194-#if GAZELLE_ENABLE 195- if (pos > 0) { 196- queuelen -= pbuf_clen(p); 197- break; 198- } 199-#else 200 pbuf_free(p); 201-#endif 202 goto memerr; 203 } 204 205@@ -730,12 +715,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 206 #endif 207 208 if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { 209-#if GAZELLE_ENABLE 210- if (pos > 0) { 211- queuelen -= pbuf_clen(p); 212- break; 213- } 214-#endif 215 goto memerr; 216 } 217 #if TCP_OVERSIZE_DBGCHECK 218@@ -763,9 +742,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 219 lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); 220 221 pos += seglen; 222-#if GAZELLE_ENABLE 223- do_lwip_get_from_sendring_over((struct lwip_sock*)arg); 224-#endif 225 } 226 227 /* 228@@ -855,12 +831,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 229 if (queue) { 230 pcb->last_unsent = prev_seg; 231 } 232- pcb->snd_lbb += pos; 233- pcb->snd_buf -= pos; 234-#else 235+#endif 236 pcb->snd_lbb += len; 237 pcb->snd_buf -= len; 238-#endif 239 pcb->snd_queuelen = queuelen; 240 241 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", 242@@ -880,14 +853,12 @@ memerr: 243 tcp_set_flags(pcb, TF_NAGLEMEMERR); 244 TCP_STATS_INC(tcp.memerr); 245 246-#if !GAZELLE_ENABLE 247 if (concat_p != NULL) { 248 pbuf_free(concat_p); 249 } 250 if (queue != NULL) { 251 tcp_segs_free(queue); 252 } 253-#endif 254 if (pcb->snd_queuelen != 0) { 255 LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || 256 pcb->unsent != NULL); 257@@ -896,6 +867,137 @@ memerr: 258 return ERR_MEM; 259 } 260 261+#if GAZELLE_ENABLE 262+err_t 263+tcp_write_from_stack(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 264+{ 265+ struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL; 266+ u16_t pos = 0; /* position in 'arg' data */ 267+ u16_t queuelen; 268+ u8_t optlen; 269+ u8_t optflags = 0; 270+ err_t err; 271+ u16_t mss_local; 272+ 273+ /* don't allocate segments bigger than half the maximum window we ever received */ 274+ mss_local = LWIP_MIN(pcb->mss, TCPWND_MIN16(pcb->snd_wnd_max / 2)); 275+ mss_local = mss_local ? mss_local : pcb->mss; 276+ 277+ err = tcp_write_checks(pcb, len); 278+ if (err != ERR_OK) { 279+ return err; 280+ } 281+ queuelen = pcb->snd_queuelen; 282+ 283+ optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); 284+ 285+ last_unsent = pcb->last_unsent; 286+ 287+ /* 288+ * get pbuf from sendring and create new segments. 289+ */ 290+ while (pos < len) { 291+ struct pbuf *p; 292+ u16_t left = len - pos; 293+ u16_t max_len = mss_local - optlen; 294+ u16_t seglen = LWIP_MIN(left, max_len); 295+ 296+ p = do_lwip_get_from_sendring((struct lwip_sock *)arg, len - pos, &apiflags); 297+ if (p == NULL) { 298+ break; 299+ } 300+ seglen = p->tot_len; 301+ 302+ queuelen += pbuf_clen(p); 303+ 304+ /* Now that there are more segments queued, we check again if the 305+ * length of the queue exceeds the configured maximum or 306+ * overflows. */ 307+ if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) { 308+ LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", 309+ queuelen, (int)TCP_SND_QUEUELEN)); 310+ if (pos > 0) { 311+ queuelen -= pbuf_clen(p); 312+ break; 313+ } 314+ goto memerr; 315+ } 316+ 317+ lstack_calculate_aggregate(2, p->tot_len); 318+ 319+ if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { 320+ if (pos > 0) { 321+ queuelen -= pbuf_clen(p); 322+ break; 323+ } 324+ goto memerr; 325+ } 326+ 327+ /* first segment of to-be-queued data? */ 328+ if (queue == NULL) { 329+ queue = seg; 330+ } else { 331+ /* Attach the segment to the end of the queued segments */ 332+ LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL); 333+ prev_seg->next = seg; 334+ } 335+ /* remember last segment of to-be-queued data for next iteration */ 336+ prev_seg = seg; 337+ 338+ LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n", 339+ lwip_ntohl(seg->tcphdr->seqno), 340+ lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); 341+ 342+ pos += seglen; 343+ do_lwip_get_from_sendring_over((struct lwip_sock*)arg); 344+ } 345+ 346+ /* 347+ * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that 348+ * is harmless 349+ */ 350+ if (last_unsent == NULL) { 351+ pcb->unsent = queue; 352+ } else { 353+ last_unsent->next = queue; 354+ } 355+ 356+ /* 357+ * Finally update the pcb state. 358+ */ 359+ if (queue) { 360+ pcb->last_unsent = prev_seg; 361+ } 362+ pcb->snd_lbb += pos; 363+ pcb->snd_buf -= pos; 364+ pcb->snd_queuelen = queuelen; 365+ 366+ LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", 367+ pcb->snd_queuelen)); 368+ if (pcb->snd_queuelen != 0) { 369+ LWIP_ASSERT("tcp_write: valid queue length", 370+ pcb->unacked != NULL || pcb->unsent != NULL); 371+ } 372+ 373+ /* Set the PSH flag in the last segment that we enqueued. */ 374+ if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE) == 0)) { 375+ TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); 376+ } 377+ 378+ return ERR_OK; 379+memerr: 380+ tcp_set_flags(pcb, TF_NAGLEMEMERR); 381+ TCP_STATS_INC(tcp.memerr); 382+ 383+ if (pcb->snd_queuelen != 0) { 384+ LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || 385+ pcb->unsent != NULL); 386+ } 387+ LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); 388+ return ERR_MEM; 389+} 390+#endif 391+ 392 /** 393 * Split segment on the head of the unsent queue. If return is not 394 * ERR_OK, existing head remains intact 395@@ -2095,6 +2197,7 @@ tcp_rexmit(struct tcp_pcb *pcb) 396 397 /* Don't take any rtt measurements after retransmitting. */ 398 pcb->rttest = 0; 399+ pcb->need_tso_send = 1; 400 401 /* Do the actual retransmission. */ 402 MIB2_STATS_INC(mib2.tcpretranssegs); 403diff --git a/src/core/udp.c b/src/core/udp.c 404index 937a045..828a489 100644 405--- a/src/core/udp.c 406+++ b/src/core/udp.c 407@@ -414,7 +414,7 @@ udp_input(struct pbuf *p, struct netif *inp) 408 if (udphdr->chksum != 0) { 409 #if CHECKSUM_CHECK_UDP_HW 410 u64_t ret = 0; 411- if (netif_get_txol_flags(inp) & DEV_RX_OFFLOAD_UDP_CKSUM) { 412+ if (netif_get_rxol_flags(inp) & DEV_RX_OFFLOAD_UDP_CKSUM) { 413 ret = is_cksum_bad(p); 414 } else { 415 ret = ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len, 416diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h 417index e13099c..959df3e 100644 418--- a/src/include/lwip/tcp.h 419+++ b/src/include/lwip/tcp.h 420@@ -567,6 +567,10 @@ err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); 421 422 err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, 423 u8_t apiflags); 424+#if GAZELLE_ENABLE 425+err_t tcp_write_from_stack (struct tcp_pcb *pcb, const void *dataptr, u16_t len, 426+ u8_t apiflags); 427+#endif 428 429 void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); 430 431diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h 432index baf739e..fdd4f87 100644 433--- a/src/include/lwipopts.h 434+++ b/src/include/lwipopts.h 435@@ -208,8 +208,8 @@ 436 #define TCP_LISTEN_BACKLOG 1 437 #define TCP_DEFAULT_LISTEN_BACKLOG 0xff 438 439-#define TCP_OVERSIZE 0 440-#define LWIP_NETIF_TX_SINGLE_PBUF 0 441+#define TCP_OVERSIZE TCP_MSS 442+#define LWIP_NETIF_TX_SINGLE_PBUF 1 443 444 #define TCP_MSS (FRAME_MTU - IP_HLEN - TCP_HLEN) 445 446@@ -219,7 +219,7 @@ 447 448 #define TCP_SND_QUEUELEN (8191) 449 450-#define TCP_SNDLOWAT (TCP_SND_BUF / 5) 451+#define TCP_SNDLOWAT (32768) 452 453 #define TCP_SNDQUEUELOWAT (TCP_SND_QUEUELEN / 5) 454 455-- 4562.27.0 457 458