Projects
Eulaceura:Mainline
lwip
_service:obs_scm:0075-adapt-read-write-for-rtc-...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:0075-adapt-read-write-for-rtc-mode.patch of Package lwip
From be56e9eed8acf82a862d19ef4f890f309018ddde Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng14@huawei.com> Date: Sat, 28 Oct 2023 17:21:46 +0800 Subject: [PATCH] adapt read/write for rtc mode --- src/api/api_msg.c | 14 ++-- src/api/sockets.c | 21 ++--- src/core/init.c | 2 +- src/core/pbuf.c | 7 ++ src/core/tcp_out.c | 171 +++++++++++++++++++++++++++++++++-------- src/core/udp.c | 2 +- src/include/lwip/tcp.h | 4 + src/include/lwipopts.h | 6 +- 8 files changed, 174 insertions(+), 53 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 0f26119..2556901 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -1754,11 +1754,15 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) write_more = 0; } #if GAZELLE_ENABLE - /* vector->ptr is private arg sock */ - LWIP_UNUSED_ARG(dataptr); - write_more = 0; - err = tcp_write(conn->pcb.tcp, conn->current_msg->msg.w.vector->ptr, len, apiflags); - conn->current_msg->msg.w.len = len; + if (netif_is_rtc_mode(netif_default)) { + err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); + } else { + /* vector->ptr is private arg sock */ + LWIP_UNUSED_ARG(dataptr); + write_more = 0; + err = tcp_write_from_stack(conn->pcb.tcp, conn->current_msg->msg.w.vector->ptr, len, apiflags); + conn->current_msg->msg.w.len = len; + } conn->pcb.tcp->need_tso_send = 1; #else err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); diff --git a/src/api/sockets.c b/src/api/sockets.c index 833b27f..a07fb59 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -1124,7 +1124,15 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) apiflags |= NETCONN_DONTBLOCK; } -#if !GAZELLE_ENABLE +#if GAZELLE_ENABLE + if (!netif_is_rtc_mode(netif_default)) { + LWIP_UNUSED_ARG(recv_left); + recvd = do_lwip_read_from_lwip(sock, flags, apiflags); + if (recvd <= 0) { + return recvd; + } + } else { +#endif do { struct pbuf *p; err_t err; @@ -1203,14 +1211,10 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN; /* @todo: do we need to support peeking more than one pbuf? */ } while ((recv_left > 0) && !(flags & MSG_PEEK)); -lwip_recv_tcp_done: -#else /* GAZELLE_ENABLE */ - LWIP_UNUSED_ARG(recv_left); - recvd = do_lwip_read_from_lwip(sock, flags, apiflags); - if (recvd <= 0) { - return recvd; +#if GAZELLE_ENABLE } #endif /* GAZELLE_ENABLE */ +lwip_recv_tcp_done: if (apiflags & NETCONN_NOAUTORCVD) { if ((recvd > 0) && !(flags & MSG_PEEK)) { /* ensure window update after copying all data */ diff --git a/src/core/init.c b/src/core/init.c index 6841857..5b60ed8 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -312,7 +312,7 @@ PACK_STRUCT_END #if TCP_MSS >= ((16 * 1024) - 1) #error "lwip_sanity_check: WARNING: TCP_MSS must be <= 16382 to prevent u16_t underflow in TCP_SNDLOWAT calculation!" #endif -#if TCP_SNDLOWAT >= (0xFFFFFFFF - (4 * TCP_MSS)) +#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS)) #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!" #endif #if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN diff --git a/src/core/pbuf.c b/src/core/pbuf.c index 3c04281..8386c90 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -117,6 +117,7 @@ pbuf_skip_const(const struct pbuf *in, u16_t in_offset, u16_t *out_offset); volatile u8_t pbuf_free_ooseq_pending; #define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() +#if !GAZELLE_ENABLE /** * Attempt to reclaim some memory from queued out-of-sequence TCP segments * if we run out of pool pbufs. It's better to give priority to new packets @@ -176,6 +177,7 @@ pbuf_pool_is_empty(void) } #endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ } +#endif /* GAZELLE_ENABLE */ #endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ /* Initialize members of struct pbuf after allocation */ @@ -238,6 +240,10 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) p = pbuf_alloc_reference(NULL, length, type); break; case PBUF_POOL: { +#if GAZELLE_ENABLE + // alloc from pktmbuf pool, one pbuf is enough + p = do_lwip_alloc_pbuf(layer, length, type); +#else struct pbuf *q, *last; u16_t rem_len; /* remaining length */ p = NULL; @@ -273,6 +279,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) rem_len = (u16_t)(rem_len - qlen); offset = 0; } while (rem_len > 0); +#endif /* GAZELLE_ENABLE */ break; } case PBUF_RAM: { diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index 4bf3bfd..4e7aac0 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -518,15 +518,18 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) * pos records progress as data is segmented. */ -#if !GAZELLE_ENABLE /* Find the tail of the unsent queue. */ if (pcb->unsent != NULL) { u16_t space; u16_t unsent_optlen; +#if GAZELLE_ENABLE + last_unsent = pcb->last_unsent; +#else /* @todo: this could be sped up by keeping last_unsent in the pcb */ for (last_unsent = pcb->unsent; last_unsent->next != NULL; last_unsent = last_unsent->next); +#endif /* Usable space at the end of the last unsent segment */ unsent_optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(last_unsent->flags, pcb); @@ -634,9 +637,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) pcb->unsent_oversize == 0); #endif /* TCP_OVERSIZE */ } -#else /* GAZELLE_ENABLE */ - last_unsent = pcb->last_unsent; -#endif /* GAZELLE_ENABLE */ /* * Phase 3: Create new segments. @@ -654,7 +654,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) u8_t chksum_swapped = 0; #endif /* TCP_CHECKSUM_ON_COPY */ -#if !GAZELLE_ENABLE if (apiflags & TCP_WRITE_FLAG_COPY) { /* If copy is set, memory should be allocated and data copied * into pbuf */ @@ -701,13 +700,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) /* Concatenate the headers and data pbufs together. */ pbuf_cat(p/*header*/, p2/*data*/); } -#else /* GAZELLE_ENABLE */ - p = do_lwip_get_from_sendring((struct lwip_sock *)arg, len - pos, &apiflags); - if (p == NULL) { - break; - } - seglen = p->tot_len; -#endif /* GAZELLE_ENABLE */ queuelen += pbuf_clen(p); @@ -717,14 +709,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", queuelen, (int)TCP_SND_QUEUELEN)); -#if GAZELLE_ENABLE - if (pos > 0) { - queuelen -= pbuf_clen(p); - break; - } -#else pbuf_free(p); -#endif goto memerr; } @@ -733,12 +718,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) #endif if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { -#if GAZELLE_ENABLE - if (pos > 0) { - queuelen -= pbuf_clen(p); - break; - } -#endif goto memerr; } #if TCP_OVERSIZE_DBGCHECK @@ -766,9 +745,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); pos += seglen; -#if GAZELLE_ENABLE - do_lwip_get_from_sendring_over((struct lwip_sock*)arg); -#endif } /* @@ -858,12 +834,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) if (queue) { pcb->last_unsent = prev_seg; } - pcb->snd_lbb += pos; - pcb->snd_buf -= pos; -#else +#endif pcb->snd_lbb += len; pcb->snd_buf -= len; -#endif pcb->snd_queuelen = queuelen; LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", @@ -883,14 +856,12 @@ memerr: tcp_set_flags(pcb, TF_NAGLEMEMERR); TCP_STATS_INC(tcp.memerr); -#if !GAZELLE_ENABLE if (concat_p != NULL) { pbuf_free(concat_p); } if (queue != NULL) { tcp_segs_free(queue); } -#endif if (pcb->snd_queuelen != 0) { LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || pcb->unsent != NULL); @@ -899,6 +870,137 @@ memerr: return ERR_MEM; } +#if GAZELLE_ENABLE +err_t +tcp_write_from_stack(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +{ + struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL; + u16_t pos = 0; /* position in 'arg' data */ + u16_t queuelen; + u8_t optlen; + u8_t optflags = 0; + err_t err; + u16_t mss_local; + + /* don't allocate segments bigger than half the maximum window we ever received */ + mss_local = LWIP_MIN(pcb->mss, TCPWND_MIN16(pcb->snd_wnd_max / 2)); + mss_local = mss_local ? mss_local : pcb->mss; + + err = tcp_write_checks(pcb, len); + if (err != ERR_OK) { + return err; + } + queuelen = pcb->snd_queuelen; + + optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); + + last_unsent = pcb->last_unsent; + + /* + * get pbuf from sendring and create new segments. + */ + while (pos < len) { + struct pbuf *p; + u16_t left = len - pos; + u16_t max_len = mss_local - optlen; + u16_t seglen = LWIP_MIN(left, max_len); + + p = do_lwip_get_from_sendring((struct lwip_sock *)arg, len - pos, &apiflags); + if (p == NULL) { + break; + } + seglen = p->tot_len; + + queuelen += pbuf_clen(p); + + /* Now that there are more segments queued, we check again if the + * length of the queue exceeds the configured maximum or + * overflows. */ + if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", + queuelen, (int)TCP_SND_QUEUELEN)); + if (pos > 0) { + queuelen -= pbuf_clen(p); + break; + } + goto memerr; + } + + lstack_calculate_aggregate(2, p->tot_len); + + if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { + if (pos > 0) { + queuelen -= pbuf_clen(p); + break; + } + goto memerr; + } + + /* first segment of to-be-queued data? */ + if (queue == NULL) { + queue = seg; + } else { + /* Attach the segment to the end of the queued segments */ + LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL); + prev_seg->next = seg; + } + /* remember last segment of to-be-queued data for next iteration */ + prev_seg = seg; + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n", + lwip_ntohl(seg->tcphdr->seqno), + lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); + + pos += seglen; + do_lwip_get_from_sendring_over((struct lwip_sock*)arg); + } + + /* + * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that + * is harmless + */ + if (last_unsent == NULL) { + pcb->unsent = queue; + } else { + last_unsent->next = queue; + } + + /* + * Finally update the pcb state. + */ + if (queue) { + pcb->last_unsent = prev_seg; + } + pcb->snd_lbb += pos; + pcb->snd_buf -= pos; + pcb->snd_queuelen = queuelen; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", + pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: valid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + /* Set the PSH flag in the last segment that we enqueued. */ + if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE) == 0)) { + TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); + } + + return ERR_OK; +memerr: + tcp_set_flags(pcb, TF_NAGLEMEMERR); + TCP_STATS_INC(tcp.memerr); + + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || + pcb->unsent != NULL); + } + LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); + return ERR_MEM; +} +#endif + /** * Split segment on the head of the unsent queue. If return is not * ERR_OK, existing head remains intact @@ -2098,6 +2200,7 @@ tcp_rexmit(struct tcp_pcb *pcb) /* Don't take any rtt measurements after retransmitting. */ pcb->rttest = 0; + pcb->need_tso_send = 1; /* Do the actual retransmission. */ MIB2_STATS_INC(mib2.tcpretranssegs); diff --git a/src/core/udp.c b/src/core/udp.c index ff20ced..f38619b 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -414,7 +414,7 @@ udp_input(struct pbuf *p, struct netif *inp) if (udphdr->chksum != 0) { #if CHECKSUM_CHECK_UDP_HW u64_t ret = 0; - if (netif_get_txol_flags(inp) & DEV_RX_OFFLOAD_UDP_CKSUM) { + if (netif_get_rxol_flags(inp) & DEV_RX_OFFLOAD_UDP_CKSUM) { ret = is_cksum_bad(p); } else { ret = ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len, diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h index f968441..460df21 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -566,6 +566,10 @@ err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, u8_t apiflags); +#if GAZELLE_ENABLE +err_t tcp_write_from_stack (struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags); +#endif void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h index fbdcbf4..4ae37f5 100644 --- a/src/include/lwipopts.h +++ b/src/include/lwipopts.h @@ -201,8 +201,8 @@ #define TCP_LISTEN_BACKLOG 1 #define TCP_DEFAULT_LISTEN_BACKLOG 0xff -#define TCP_OVERSIZE 0 -#define LWIP_NETIF_TX_SINGLE_PBUF 0 +#define TCP_OVERSIZE TCP_MSS +#define LWIP_NETIF_TX_SINGLE_PBUF 1 #define TCP_MSS (FRAME_MTU - IP_HLEN - TCP_HLEN) @@ -212,7 +212,7 @@ #define TCP_SND_QUEUELEN (8191) -#define TCP_SNDLOWAT (TCP_SND_BUF / 5) +#define TCP_SNDLOWAT (32768) #define TCP_SNDQUEUELOWAT (TCP_SND_QUEUELEN / 5) -- 2.27.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2