From 96f86bacb34254ac75cce04aa29045daf8dfca1b Mon Sep 17 00:00:00 2001 From: jiangheng Date: Fri, 27 Sep 2024 15:29:20 +0800 Subject: [PATCH] add pingpong mode support --- 0167-lwip-add-pingpong-mode-support.patch | 201 ++++++++++++++++++++++ lwip.spec | 6 +- 2 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 0167-lwip-add-pingpong-mode-support.patch diff --git a/0167-lwip-add-pingpong-mode-support.patch b/0167-lwip-add-pingpong-mode-support.patch new file mode 100644 index 0000000..ea92618 --- /dev/null +++ b/0167-lwip-add-pingpong-mode-support.patch @@ -0,0 +1,201 @@ +From 33a6e9435222151446c54a93696ed2c417dc15be Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Fri, 27 Sep 2024 15:26:16 +0800 +Subject: [PATCH] lwip: add pingpong mode support + +--- + src/core/tcp.c | 10 +++++++++- + src/core/tcp_in.c | 16 ++++++++++++++++ + src/core/tcp_out.c | 14 +++++++++++++- + src/include/lwip/tcp.h | 7 +++++++ + src/include/lwipgz_tcp_priv.h | 19 ++++++++++++++++++- + src/include/lwipopts.h | 1 + + 6 files changed, 64 insertions(+), 3 deletions(-) + +diff --git a/src/core/tcp.c b/src/core/tcp.c +index c25f961..4a3c031 100644 +--- a/src/core/tcp.c ++++ b/src/core/tcp.c +@@ -1702,8 +1702,13 @@ tcp_fasttmr_start: + if (pcb->last_timer != tcp_timer_ctr) { + struct tcp_pcb *next; + pcb->last_timer = tcp_timer_ctr; ++#if !GAZELLE_TCP_PINGPONG_MODE + /* send delayed ACKs */ + if (pcb->flags & TF_ACK_DELAY) { ++#else ++ if (!tcp_in_pingpong(pcb) || TIME_BEFORE(pcb->lrcvtime + TCP_ATO_MS, sys_now())) { ++ tcp_exit_pingpong(pcb); ++#endif + LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); + MIB2_STATS_INC(mib2.tcpdelayackcnt); + tcp_ack_now(pcb); +@@ -2154,6 +2159,10 @@ tcp_alloc(u8_t prio) + pcb->client_rx_ring = NULL; + pcb->client_tx_ring = NULL; + pcb->free_ring = 0; ++#endif ++#if GAZELLE_TCP_PINGPONG_MODE ++ pcb->lrcvtime = 0; ++ pcb->pingpong = 0; + #endif + pcb_tci_init(pcb); + } +@@ -2319,7 +2328,6 @@ tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) + } + #endif /* LWIP_CALLBACK_API */ + +- + /** + * @ingroup tcp_raw + * Specifies the polling interval and the callback function that should +diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c +index d9db957..1751561 100644 +--- a/src/core/tcp_in.c ++++ b/src/core/tcp_in.c +@@ -1765,7 +1765,17 @@ tcp_receive(struct tcp_pcb *pcb) + + + /* Acknowledge the segment(s). */ ++#if GAZELLE_TCP_PINGPONG_MODE ++ if (tcp_in_pingpong(pcb)) { ++ tcp_clear_flags(pcb, TF_ACK_NOW); ++ tcp_set_flags(pcb, TF_ACK_DELAY); ++ } else { ++ tcp_ack(pcb); ++ } ++ pcb->lrcvtime = sys_now(); ++#else + tcp_ack(pcb); ++#endif + + #if LWIP_TCP_SACK_OUT + if (LWIP_TCP_SACK_VALID(pcb, 0)) { +@@ -2012,12 +2022,18 @@ tcp_receive(struct tcp_pcb *pcb) + #endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */ + #endif /* TCP_QUEUE_OOSEQ */ + ++#if GAZELLE_TCP_PINGONG_MODE ++ tcp_exit_pingpong(pcb); /* ooseq */ ++#endif + /* We send the ACK packet after we've (potentially) dealt with SACKs, + so they can be included in the acknowledgment. */ + MIB2_STATS_INC(mib2.tcpinemptyacks); + tcp_send_empty_ack(pcb); + } + } else { ++#if GAZELLE_TCP_PINGONG_MODE ++ tcp_exit_pingpong(pcb); /* out of window */ ++#endif + /* The incoming segment is not within the window. */ + MIB2_STATS_INC(mib2.tcpinemptyacks); + tcp_send_empty_ack(pcb); +diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c +index 4cf1a62..1a55748 100644 +--- a/src/core/tcp_out.c ++++ b/src/core/tcp_out.c +@@ -1499,6 +1499,9 @@ tcp_output(struct tcp_pcb *pcb) + /* If the TF_ACK_NOW flag is set and the ->unsent queue is empty, construct + * an empty ACK segment and send it. */ + if (pcb->flags & TF_ACK_NOW) { ++#if GAZELLE_TCP_PINGPONG_MODE ++ MIB2_STATS_INC(mib2.tcpinemptyacks); ++#endif + return tcp_send_empty_ack(pcb); + } + /* nothing to send: shortcut out of here */ +@@ -1546,6 +1549,9 @@ tcp_output(struct tcp_pcb *pcb) + } + /* We need an ACK, but can't send data now, so send an empty ACK */ + if (pcb->flags & TF_ACK_NOW) { ++#if GAZELLE_TCP_PINGPONG_MODE ++ MIB2_STATS_INC(mib2.tcpinemptyacks); ++#endif + return tcp_send_empty_ack(pcb); + } + goto output_done; +@@ -1826,6 +1832,13 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif + int seg_chksum_was_swapped = 0; + #endif + ++#if GAZELLE_TCP_PINGPONG_MODE ++ if (!tcp_in_pingpong(pcb)) { ++ if (TIME_BEFORE(sys_now(), pcb->lrcvtime + TCP_ATO_MS)) { ++ tcp_enter_pingpong(pcb); ++ } ++ } ++#endif + #if GAZELLE_ENABLE + lstack_calculate_aggregate(1, seg->len); + #endif +@@ -2218,7 +2231,6 @@ tcp_rexmit(struct tcp_pcb *pcb) + return ERR_OK; + } + +- + /** + * Handle retransmission after three dupacks received + * +diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h +index 72fd166..a332e80 100644 +--- a/src/include/lwip/tcp.h ++++ b/src/include/lwip/tcp.h +@@ -300,6 +300,13 @@ struct tcp_pcb { + tcpwnd_size_t rcv_wnd; /* receiver window available */ + tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */ + u32_t rcv_ann_right_edge; /* announced right edge of window */ ++#if GAZELLE_TCP_PINGPONG_MODE ++#define TIME_BEFORE(t, compare_to) ((((u32_t)((t)-(compare_to))) > 0x7fffffff) ? 1 : 0) ++#define TCP_ATO_MS 200 ++ u32_t lrcvtime; ++#define TCP_PINGPONG_THRESH 3 ++ u8_t pingpong; ++#endif + + #if LWIP_TCP_SACK_OUT + /* SACK ranges to include in ACK packets (entry is invalid if left==right) */ +diff --git a/src/include/lwipgz_tcp_priv.h b/src/include/lwipgz_tcp_priv.h +index c6d0d00..e55eda2 100644 +--- a/src/include/lwipgz_tcp_priv.h ++++ b/src/include/lwipgz_tcp_priv.h +@@ -207,6 +207,23 @@ static inline void vdev_unreg_done(const struct tcp_pcb *pcb) + vdev_reg_done(REG_RING_TCP_CONNECT_CLOSE, pcb); + } + } ++ ++#if GAZELLE_TCP_PINGPONG_MODE ++static inline bool tcp_in_pingpong(const struct tcp_pcb *pcb) ++{ ++ return (pcb->pingpong >= TCP_PINGPONG_THRESH); ++} ++static inline void tcp_enter_pingpong(struct tcp_pcb *pcb) ++{ ++ if (pcb->pingpong < TCP_PINGPONG_THRESH) { ++ pcb->pingpong++; ++ } ++} ++static inline void tcp_exit_pingpong(struct tcp_pcb *pcb) ++{ ++ pcb->pingpong = 0; ++} ++#endif /* GAZELLE_TCP_PINGPONG_MODE */ + #endif /* GAZELLE_ENABLE */ + +-#endif /* __GAZELLE_TCP_PRIV_H__ */ +\ No newline at end of file ++#endif /* __GAZELLE_TCP_PRIV_H__ */ +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index b32e372..c3ecb21 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -243,6 +243,7 @@ + + #define GAZELLE_TCP_MAX_CONN_PER_THREAD 65535 + #define GAZELLE_TCP_REUSE_IPPORT 1 ++#define GAZELLE_TCP_PINGPONG_MODE 1 + + /* + ------------------------------------ +-- +2.33.0 + diff --git a/lwip.spec b/lwip.spec index 4daef17..49cffd1 100644 --- a/lwip.spec +++ b/lwip.spec @@ -4,7 +4,7 @@ Summary: lwip is a small independent implementation of the TCP/IP protocol suite Name: lwip Version: 2.2.0 -Release: 56 +Release: 57 License: BSD URL: http://savannah.nongnu.org/projects/lwip/ Source0: http://download.savannah.nongnu.org/releases/lwip/%{name}-%{version}.zip @@ -178,6 +178,7 @@ Patch9162: 0163-LWIPOPTS-support-setsockopt-SO_SNDTIMEO.patch Patch9163: 0164-LWIPOPTS-support-setsockopt-SO_SNDBUF.patch Patch9164: 0165-LOG-modified-gazelle-log-level-and-add-item-in-mib2.patch Patch9165: 0166-cleancode-rename-log-level.patch +Patch9166: 0167-lwip-add-pingpong-mode-support.patch BuildRequires: gcc-c++ dos2unix dpdk-devel @@ -207,6 +208,9 @@ cd %{_builddir}/%{name}-%{version}/src %{_libdir}/liblwip.a %changelog +* Fri Sep 27 2024 jiangheng - 2.2.0-57 +- add pingpong mode support + * Tue Sep 24 2024 LemmyHuang - 2.2.0-56 - cleancode: rename log level -- Gitee