458 lines
14 KiB
Diff
458 lines
14 KiB
Diff
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 3e982ab..d8b99ee 100644
|
|
--- a/src/api/api_msg.c
|
|
+++ b/src/api/api_msg.c
|
|
@@ -1753,11 +1753,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 8d573aa..e374f96 100644
|
|
--- a/src/api/sockets.c
|
|
+++ b/src/api/sockets.c
|
|
@@ -1087,7 +1087,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;
|
|
@@ -1166,15 +1174,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 */
|
|
+#endif
|
|
+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 7b6214f..60e1c68 100644
|
|
--- a/src/core/init.c
|
|
+++ b/src/core/init.c
|
|
@@ -306,7 +306,7 @@ PACK_STRUCT_END
|
|
#if TCP_SNDLOWAT >= TCP_SND_BUF
|
|
#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."
|
|
#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 975e240..61690ff 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 e2c9d63..073d989 100644
|
|
--- a/src/core/tcp_out.c
|
|
+++ b/src/core/tcp_out.c
|
|
@@ -515,15 +515,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);
|
|
@@ -631,9 +634,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.
|
|
@@ -651,7 +651,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 */
|
|
@@ -698,13 +697,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);
|
|
|
|
@@ -714,14 +706,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;
|
|
}
|
|
|
|
@@ -730,12 +715,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
|
|
@@ -763,9 +742,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
|
|
}
|
|
|
|
/*
|
|
@@ -855,12 +831,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",
|
|
@@ -880,14 +853,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);
|
|
@@ -896,6 +867,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
|
|
@@ -2095,6 +2197,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 937a045..828a489 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 e13099c..959df3e 100644
|
|
--- a/src/include/lwip/tcp.h
|
|
+++ b/src/include/lwip/tcp.h
|
|
@@ -567,6 +567,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 baf739e..fdd4f87 100644
|
|
--- a/src/include/lwipopts.h
|
|
+++ b/src/include/lwipopts.h
|
|
@@ -208,8 +208,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)
|
|
|
|
@@ -219,7 +219,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
|
|
|