1195972f6Sopenharmony_ciFrom abeef0770f76cd0eff8e5c6e50de0b280079d7f0 Mon Sep 17 00:00:00 2001 2195972f6Sopenharmony_ciFrom: jiangheng <jiangheng14@huawei.com> 3195972f6Sopenharmony_ciDate: Mon, 13 Mar 2023 19:25:42 +0800 4195972f6Sopenharmony_ciSubject: [PATCH] fix tso small packet drop in kernel server 5195972f6Sopenharmony_ci 6195972f6Sopenharmony_ci--- 7195972f6Sopenharmony_ci src/core/tcp_out.c | 254 +++++++++++++++++++++-------------------- 8195972f6Sopenharmony_ci src/include/lwipopts.h | 2 + 9195972f6Sopenharmony_ci 2 files changed, 130 insertions(+), 126 deletions(-) 10195972f6Sopenharmony_ci 11195972f6Sopenharmony_cidiff --git a/src/core/tcp_out.c b/src/core/tcp_out.c 12195972f6Sopenharmony_ciindex 8a0d653..b1c317d 100644 13195972f6Sopenharmony_ci--- a/src/core/tcp_out.c 14195972f6Sopenharmony_ci+++ b/src/core/tcp_out.c 15195972f6Sopenharmony_ci@@ -1312,60 +1312,33 @@ tcp_build_wnd_scale_option(u32_t *opts) 16195972f6Sopenharmony_ci #endif 17195972f6Sopenharmony_ci 18195972f6Sopenharmony_ci #if GAZELLE_ENABLE 19195972f6Sopenharmony_ci-static struct tcp_seg *tcp_output_over(struct tcp_pcb *pcb, struct tcp_seg *seg, struct tcp_seg *useg) 20195972f6Sopenharmony_ci-{ 21195972f6Sopenharmony_ci- if (TCP_TCPLEN(seg) > 0) { 22195972f6Sopenharmony_ci- seg->next = NULL; 23195972f6Sopenharmony_ci- if (useg == NULL) { 24195972f6Sopenharmony_ci- pcb->unacked = seg; 25195972f6Sopenharmony_ci- pcb->last_unacked = seg; 26195972f6Sopenharmony_ci- useg = seg; 27195972f6Sopenharmony_ci- } else { 28195972f6Sopenharmony_ci- if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) { 29195972f6Sopenharmony_ci- /* add segment to before tail of unacked list, keeping the list sorted */ 30195972f6Sopenharmony_ci- struct tcp_seg **cur_seg = &(pcb->unacked); 31195972f6Sopenharmony_ci- while (*cur_seg && 32195972f6Sopenharmony_ci- TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) { 33195972f6Sopenharmony_ci- cur_seg = &((*cur_seg)->next ); 34195972f6Sopenharmony_ci- } 35195972f6Sopenharmony_ci- seg->next = (*cur_seg); 36195972f6Sopenharmony_ci- (*cur_seg) = seg; 37195972f6Sopenharmony_ci- } else { 38195972f6Sopenharmony_ci- /* add segment to tail of unacked list */ 39195972f6Sopenharmony_ci- useg->next = seg; 40195972f6Sopenharmony_ci- useg = seg; 41195972f6Sopenharmony_ci- pcb->last_unacked = seg; 42195972f6Sopenharmony_ci- } 43195972f6Sopenharmony_ci- } 44195972f6Sopenharmony_ci- } else { 45195972f6Sopenharmony_ci- tcp_seg_free(seg); 46195972f6Sopenharmony_ci- } 47195972f6Sopenharmony_ci- 48195972f6Sopenharmony_ci- return useg; 49195972f6Sopenharmony_ci-} 50195972f6Sopenharmony_ci-static err_t tcp_output_seg(struct tcp_pcb *pcb, struct tcp_seg *seg, struct netif *netif, u32_t snd_nxt) 51195972f6Sopenharmony_ci-{ 52195972f6Sopenharmony_ci- if (pcb->state != SYN_SENT) { 53195972f6Sopenharmony_ci- TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); 54195972f6Sopenharmony_ci- } 55195972f6Sopenharmony_ci- 56195972f6Sopenharmony_ci- err_t err = tcp_output_segment(seg, pcb, netif); 57195972f6Sopenharmony_ci- if (err != ERR_OK) { 58195972f6Sopenharmony_ci- /* segment could not be sent, for whatever reason */ 59195972f6Sopenharmony_ci- tcp_set_flags(pcb, TF_NAGLEMEMERR); 60195972f6Sopenharmony_ci- return err; 61195972f6Sopenharmony_ci- } 62195972f6Sopenharmony_ci- 63195972f6Sopenharmony_ci- if (pcb->state != SYN_SENT) { 64195972f6Sopenharmony_ci- tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); 65195972f6Sopenharmony_ci- } 66195972f6Sopenharmony_ci- 67195972f6Sopenharmony_ci- if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { 68195972f6Sopenharmony_ci- pcb->snd_nxt = snd_nxt; 69195972f6Sopenharmony_ci- } 70195972f6Sopenharmony_ci- 71195972f6Sopenharmony_ci- return ERR_OK; 72195972f6Sopenharmony_ci-} 73195972f6Sopenharmony_ci+u32_t start_seqno = 0; 74195972f6Sopenharmony_ci+#define TCP_INIT_SEGMENT(tem_seg, _pcb, _p, _hdrflags, _seqno, _optflags) \ 75195972f6Sopenharmony_ci+do { \ 76195972f6Sopenharmony_ci+ struct tcp_seg *_seg = tem_seg; \ 77195972f6Sopenharmony_ci+ u8_t _optlen; \ 78195972f6Sopenharmony_ci+ rte_prefetch2(_p); \ 79195972f6Sopenharmony_ci+ \ 80195972f6Sopenharmony_ci+ _optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(_optflags, _pcb); \ 81195972f6Sopenharmony_ci+ _seg->flags = _optflags; \ 82195972f6Sopenharmony_ci+ _seg->next = NULL; \ 83195972f6Sopenharmony_ci+ _seg->p = _p; \ 84195972f6Sopenharmony_ci+ _seg->len = _p->tot_len - _optlen; \ 85195972f6Sopenharmony_ci+ /* build TCP header */ \ 86195972f6Sopenharmony_ci+ pbuf_add_header(_p, TCP_HLEN); \ 87195972f6Sopenharmony_ci+ _seg->tcphdr = (struct tcp_hdr *)_seg->p->payload; \ 88195972f6Sopenharmony_ci+ _seg->tcphdr->src = lwip_htons(_pcb->local_port); \ 89195972f6Sopenharmony_ci+ _seg->tcphdr->dest = lwip_htons(_pcb->remote_port); \ 90195972f6Sopenharmony_ci+ /* _seg->tcphdr->src = lwip_htons(_pcb->local_port); \ */ \ 91195972f6Sopenharmony_ci+ /* _seg->tcphdr->dest = lwip_htons(_pcb->remote_port); \ */ \ 92195972f6Sopenharmony_ci+ _seg->tcphdr->seqno = lwip_htonl(_seqno); \ 93195972f6Sopenharmony_ci+ \ 94195972f6Sopenharmony_ci+ if (start_seqno == 0) {\ 95195972f6Sopenharmony_ci+ start_seqno = _seqno; \ 96195972f6Sopenharmony_ci+ } \ 97195972f6Sopenharmony_ci+ TCPH_HDRLEN_FLAGS_SET(_seg->tcphdr, (5 + _optlen / 4), _hdrflags); \ 98195972f6Sopenharmony_ci+ _seg->tcphdr->urgp = 0; \ 99195972f6Sopenharmony_ci+} while(0) 100195972f6Sopenharmony_ci #endif 101195972f6Sopenharmony_ci /** 102195972f6Sopenharmony_ci * @ingroup tcp_raw 103195972f6Sopenharmony_ci@@ -1471,97 +1444,127 @@ tcp_output(struct tcp_pcb *pcb) 104195972f6Sopenharmony_ci pcb->persist_backoff = 0; 105195972f6Sopenharmony_ci 106195972f6Sopenharmony_ci /* useg should point to last segment on unacked queue */ 107195972f6Sopenharmony_ci- useg = pcb->last_unacked; 108195972f6Sopenharmony_ci+ useg = pcb->unacked; 109195972f6Sopenharmony_ci+ if (useg != NULL) { 110195972f6Sopenharmony_ci+ for (; useg->next != NULL; useg = useg->next); 111195972f6Sopenharmony_ci+ } 112195972f6Sopenharmony_ci 113195972f6Sopenharmony_ci /* data available and window allows it to be sent? */ 114195972f6Sopenharmony_ci- 115195972f6Sopenharmony_ci- u32_t send_len = 0; 116195972f6Sopenharmony_ci #if GAZELLE_ENABLE 117195972f6Sopenharmony_ci if ((get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_TSO) && pcb->need_tso_send) { 118195972f6Sopenharmony_ci- while(seg && send_len < 0xffff) { 119195972f6Sopenharmony_ci- /** 120195972f6Sopenharmony_ci- * 1) walk unsent queue, find all seg witch wait to send. chain buf in these segs. 121195972f6Sopenharmony_ci- * 2) create new segment, send and free new segment. 122195972f6Sopenharmony_ci- * 3) update snd_nxt, unacked queue, and unsent queue 123195972f6Sopenharmony_ci- */ 124195972f6Sopenharmony_ci- struct tcp_seg *start_seg = seg; 125195972f6Sopenharmony_ci- struct pbuf *first_pbuf = NULL; 126195972f6Sopenharmony_ci- struct pbuf *pre_pbuf = NULL; 127195972f6Sopenharmony_ci- u8_t pbuf_chain_len = 0; 128195972f6Sopenharmony_ci- u32_t next_seqno = lwip_ntohl(seg->tcphdr->seqno); 129195972f6Sopenharmony_ci- while (seg != NULL && pbuf_chain_len < GAZELLE_TCP_MAX_PBUF_CHAIN_LEN) { 130195972f6Sopenharmony_ci+ uint16_t send_pkt = 0; 131195972f6Sopenharmony_ci+ 132195972f6Sopenharmony_ci+ do { 133195972f6Sopenharmony_ci+ struct tcp_seg * start_seg = seg; 134195972f6Sopenharmony_ci+ struct pbuf *new_pbuf = NULL; 135195972f6Sopenharmony_ci+ 136195972f6Sopenharmony_ci+ struct pbuf *tmp_pbuf = NULL; 137195972f6Sopenharmony_ci u32_t seg_seqno = lwip_ntohl(seg->tcphdr->seqno); 138195972f6Sopenharmony_ci- if (seg_seqno - pcb->lastack + seg->len > wnd) { 139195972f6Sopenharmony_ci- if (first_pbuf) 140195972f6Sopenharmony_ci- break; 141195972f6Sopenharmony_ci- else 142195972f6Sopenharmony_ci- goto output_done; 143195972f6Sopenharmony_ci+ u32_t last_seg_seqno = seg_seqno; 144195972f6Sopenharmony_ci+ 145195972f6Sopenharmony_ci+ struct tcp_seg *last_seg = NULL; 146195972f6Sopenharmony_ci+ u16_t last_seg_len = 0; 147195972f6Sopenharmony_ci+ u8_t pbuf_chain_len = 0; 148195972f6Sopenharmony_ci+ while (seg != NULL && seg_seqno - pcb->lastack + seg->len <= wnd && pbuf_chain_len < GAZELLE_TCP_MAX_PBUF_CHAIN_LEN) { 149195972f6Sopenharmony_ci+ if (last_seg_len != 0 && (last_seg_len + seg->len < 1460) && seg->len < GAZELLE_TCP_MIN_TSO_SEG_LEN) { 150195972f6Sopenharmony_ci+ break; 151195972f6Sopenharmony_ci+ } 152195972f6Sopenharmony_ci+ 153195972f6Sopenharmony_ci+ if ((tcp_do_output_nagle(pcb) == 0) && 154195972f6Sopenharmony_ci+ ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) { 155195972f6Sopenharmony_ci+ break; 156195972f6Sopenharmony_ci+ } 157195972f6Sopenharmony_ci+ if (last_seg_seqno + last_seg_len == seg_seqno) { 158195972f6Sopenharmony_ci+ pbuf_remove_header(seg->p, seg->p->tot_len - seg->len); 159195972f6Sopenharmony_ci+ if (new_pbuf == NULL) { 160195972f6Sopenharmony_ci+ new_pbuf = seg->p; 161195972f6Sopenharmony_ci+ tmp_pbuf = new_pbuf; 162195972f6Sopenharmony_ci+ } else { 163195972f6Sopenharmony_ci+ new_pbuf->tot_len += seg->p->len; 164195972f6Sopenharmony_ci+ tmp_pbuf->next = seg->p; 165195972f6Sopenharmony_ci+ tmp_pbuf = tmp_pbuf->next; 166195972f6Sopenharmony_ci+ } 167195972f6Sopenharmony_ci+ } else { 168195972f6Sopenharmony_ci+ break; 169195972f6Sopenharmony_ci+ } 170195972f6Sopenharmony_ci+ 171195972f6Sopenharmony_ci+ last_seg = seg; 172195972f6Sopenharmony_ci+ last_seg_len = seg->len; 173195972f6Sopenharmony_ci+ last_seg_seqno = seg_seqno; 174195972f6Sopenharmony_ci+ seg = seg->next; 175195972f6Sopenharmony_ci+ seg_seqno = (seg != NULL) ? lwip_ntohl(seg->tcphdr->seqno) : seg_seqno; 176195972f6Sopenharmony_ci+ pbuf_chain_len++; 177195972f6Sopenharmony_ci } 178195972f6Sopenharmony_ci 179195972f6Sopenharmony_ci- if ((tcp_do_output_nagle(pcb) == 0) && ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) { 180195972f6Sopenharmony_ci- if (first_pbuf) 181195972f6Sopenharmony_ci- break; 182195972f6Sopenharmony_ci- else 183195972f6Sopenharmony_ci- goto output_done; 184195972f6Sopenharmony_ci+ // tcp_do_output_nagle, break 185195972f6Sopenharmony_ci+ if (new_pbuf == NULL) { 186195972f6Sopenharmony_ci+ goto end_loop; 187195972f6Sopenharmony_ci } 188195972f6Sopenharmony_ci 189195972f6Sopenharmony_ci- if (seg->len < TCP_MSS || next_seqno != seg_seqno || pbuf_chain_len >= GAZELLE_TCP_MAX_PBUF_CHAIN_LEN) { 190195972f6Sopenharmony_ci- break; 191195972f6Sopenharmony_ci- } 192195972f6Sopenharmony_ci- if (first_pbuf == NULL && (seg->next == NULL || seg->next->len < TCP_MSS)) { 193195972f6Sopenharmony_ci- break; 194195972f6Sopenharmony_ci- } 195195972f6Sopenharmony_ci+ struct tcp_seg new_seg; 196195972f6Sopenharmony_ci+ TCP_INIT_SEGMENT(&new_seg, pcb, new_pbuf, 0, lwip_ntohl(start_seg->tcphdr->seqno), 0); 197195972f6Sopenharmony_ci 198195972f6Sopenharmony_ci- pbuf_remove_header(seg->p, seg->p->tot_len - seg->len); 199195972f6Sopenharmony_ci- if (first_pbuf == NULL) { 200195972f6Sopenharmony_ci- first_pbuf = seg->p; 201195972f6Sopenharmony_ci- } else { 202195972f6Sopenharmony_ci- first_pbuf->tot_len += seg->p->len; 203195972f6Sopenharmony_ci- pre_pbuf->next = seg->p; 204195972f6Sopenharmony_ci+ if (pcb->state != SYN_SENT) { 205195972f6Sopenharmony_ci+ TCPH_SET_FLAG(new_seg.tcphdr, TCP_ACK); 206195972f6Sopenharmony_ci } 207195972f6Sopenharmony_ci 208195972f6Sopenharmony_ci- send_len += seg->len; 209195972f6Sopenharmony_ci- pre_pbuf = seg->p; 210195972f6Sopenharmony_ci- next_seqno = seg_seqno + TCP_TCPLEN(seg); 211195972f6Sopenharmony_ci- seg = seg->next; 212195972f6Sopenharmony_ci- pcb->unsent = seg; 213195972f6Sopenharmony_ci- pbuf_chain_len++; 214195972f6Sopenharmony_ci- } 215195972f6Sopenharmony_ci- 216195972f6Sopenharmony_ci- if (first_pbuf == NULL) { 217195972f6Sopenharmony_ci- err = tcp_output_seg(pcb, seg, netif, next_seqno + seg->len); 218195972f6Sopenharmony_ci+ err = tcp_output_segment(&new_seg, pcb, netif); 219195972f6Sopenharmony_ci if (err != ERR_OK) { 220195972f6Sopenharmony_ci- if (pcb->unsent == NULL) 221195972f6Sopenharmony_ci- pcb->last_unsent = NULL; 222195972f6Sopenharmony_ci- pcb->need_tso_send = 0; 223195972f6Sopenharmony_ci- return err; 224195972f6Sopenharmony_ci+ /* segment could not be sent, for whatever reason */ 225195972f6Sopenharmony_ci+ tcp_set_flags(pcb, TF_NAGLEMEMERR); 226195972f6Sopenharmony_ci+ return err; 227195972f6Sopenharmony_ci } 228195972f6Sopenharmony_ci- pcb->unsent = seg->next; 229195972f6Sopenharmony_ci- useg = tcp_output_over(pcb, seg, useg); 230195972f6Sopenharmony_ci- seg = pcb->unsent; 231195972f6Sopenharmony_ci- continue; 232195972f6Sopenharmony_ci- } 233195972f6Sopenharmony_ci- 234195972f6Sopenharmony_ci- struct tcp_seg new_seg; 235195972f6Sopenharmony_ci- tcp_init_segment(&new_seg, pcb, first_pbuf, 0, lwip_ntohl(start_seg->tcphdr->seqno), 0); 236195972f6Sopenharmony_ci 237195972f6Sopenharmony_ci- err = tcp_output_seg(pcb, &new_seg, netif, next_seqno); 238195972f6Sopenharmony_ci+ pcb->unsent = last_seg->next; 239195972f6Sopenharmony_ci+ if (pcb->state != SYN_SENT) { 240195972f6Sopenharmony_ci+ tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); 241195972f6Sopenharmony_ci+ } 242195972f6Sopenharmony_ci 243195972f6Sopenharmony_ci- for (u32_t i = 0; i < pbuf_chain_len; i++) { 244195972f6Sopenharmony_ci- struct tcp_seg *next_seg = start_seg->next; 245195972f6Sopenharmony_ci- start_seg->p->next = NULL; 246195972f6Sopenharmony_ci- useg = tcp_output_over(pcb, start_seg, useg); 247195972f6Sopenharmony_ci- start_seg = next_seg; 248195972f6Sopenharmony_ci- } 249195972f6Sopenharmony_ci+ snd_nxt = last_seg_seqno + TCP_TCPLEN(last_seg); 250195972f6Sopenharmony_ci+ if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { 251195972f6Sopenharmony_ci+ pcb->snd_nxt = snd_nxt; 252195972f6Sopenharmony_ci+ } 253195972f6Sopenharmony_ci 254195972f6Sopenharmony_ci- pbuf_remove_header(new_seg.p, new_seg.p->tot_len - new_seg.len - TCPH_HDRLEN_BYTES(new_seg.tcphdr)); 255195972f6Sopenharmony_ci- new_seg.p->tot_len = new_seg.p->len; 256195972f6Sopenharmony_ci- } 257195972f6Sopenharmony_ci- pcb->need_tso_send = 0; 258195972f6Sopenharmony_ci+ pbuf_remove_header(new_seg.p, new_seg.p->tot_len - new_seg.len - TCP_HLEN); 259195972f6Sopenharmony_ci+ new_seg.p->tot_len = new_seg.p->len; 260195972f6Sopenharmony_ci+ 261195972f6Sopenharmony_ci+ for (int start = pbuf_chain_len; start > 0; start--) { 262195972f6Sopenharmony_ci+ struct tcp_seg *tmp_seg = start_seg; 263195972f6Sopenharmony_ci+ start_seg = start_seg->next; 264195972f6Sopenharmony_ci+ tmp_seg->p->next = NULL; 265195972f6Sopenharmony_ci+ if (TCP_TCPLEN(tmp_seg) > 0) { 266195972f6Sopenharmony_ci+ tmp_seg->next = NULL; 267195972f6Sopenharmony_ci+ if (pcb->unacked == NULL) { 268195972f6Sopenharmony_ci+ pcb->unacked = tmp_seg; 269195972f6Sopenharmony_ci+ useg = tmp_seg; 270195972f6Sopenharmony_ci+ } else { 271195972f6Sopenharmony_ci+ if (TCP_SEQ_LT(lwip_ntohl(tmp_seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) { 272195972f6Sopenharmony_ci+ /* add segment to before tail of unacked list, keeping the list sorted */ 273195972f6Sopenharmony_ci+ struct tcp_seg **cur_seg = &(pcb->unacked); 274195972f6Sopenharmony_ci+ while (*cur_seg && 275195972f6Sopenharmony_ci+ TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(tmp_seg->tcphdr->seqno))) { 276195972f6Sopenharmony_ci+ cur_seg = &((*cur_seg)->next ); 277195972f6Sopenharmony_ci+ } 278195972f6Sopenharmony_ci+ tmp_seg->next = (*cur_seg); 279195972f6Sopenharmony_ci+ (*cur_seg) = tmp_seg; 280195972f6Sopenharmony_ci+ } else { 281195972f6Sopenharmony_ci+ /* add segment to tail of unacked list */ 282195972f6Sopenharmony_ci+ useg->next = tmp_seg; 283195972f6Sopenharmony_ci+ useg = useg->next; 284195972f6Sopenharmony_ci+ } 285195972f6Sopenharmony_ci+ } 286195972f6Sopenharmony_ci+ } else { 287195972f6Sopenharmony_ci+ tcp_seg_free(tmp_seg); 288195972f6Sopenharmony_ci+ } 289195972f6Sopenharmony_ci+ } 290195972f6Sopenharmony_ci+ } while(seg != NULL && lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd && send_pkt++ < 10); 291195972f6Sopenharmony_ci+end_loop: 292195972f6Sopenharmony_ci+ pcb->need_tso_send = 0; 293195972f6Sopenharmony_ci } else 294195972f6Sopenharmony_ci #endif 295195972f6Sopenharmony_ci { 296195972f6Sopenharmony_ci- while (seg != NULL && send_len < 0xffff && 297195972f6Sopenharmony_ci+ uint16_t send_pkt = 0; 298195972f6Sopenharmony_ci+ while (seg != NULL && send_pkt++ < 10 && 299195972f6Sopenharmony_ci lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { 300195972f6Sopenharmony_ci LWIP_ASSERT("RST not expected here!", 301195972f6Sopenharmony_ci (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); 302195972f6Sopenharmony_ci@@ -1576,7 +1579,6 @@ tcp_output(struct tcp_pcb *pcb) 303195972f6Sopenharmony_ci ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) { 304195972f6Sopenharmony_ci break; 305195972f6Sopenharmony_ci } 306195972f6Sopenharmony_ci- send_len += seg->len; 307195972f6Sopenharmony_ci #if TCP_CWND_DEBUG 308195972f6Sopenharmony_ci LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", 309195972f6Sopenharmony_ci pcb->snd_wnd, pcb->cwnd, wnd, 310195972f6Sopenharmony_cidiff --git a/src/include/lwipopts.h b/src/include/lwipopts.h 311195972f6Sopenharmony_ciindex 742b4a9..0d2a6d9 100644 312195972f6Sopenharmony_ci--- a/src/include/lwipopts.h 313195972f6Sopenharmony_ci+++ b/src/include/lwipopts.h 314195972f6Sopenharmony_ci@@ -55,6 +55,8 @@ 315195972f6Sopenharmony_ci 316195972f6Sopenharmony_ci #define GAZELLE_TCP_MAX_PBUF_CHAIN_LEN 40 317195972f6Sopenharmony_ci 318195972f6Sopenharmony_ci+#define GAZELLE_TCP_MIN_TSO_SEG_LEN 256 319195972f6Sopenharmony_ci+ 320195972f6Sopenharmony_ci /* 321195972f6Sopenharmony_ci ---------------------------------- 322195972f6Sopenharmony_ci ---------- NIC offloads ---------- 323195972f6Sopenharmony_ci-- 324195972f6Sopenharmony_ci2.33.0 325195972f6Sopenharmony_ci 326