MPTCP Linux Development
 help / color / mirror / Atom feed
From: gang.yan@linux.dev
To: "Paolo Abeni" <pabeni@redhat.com>, mptcp@lists.linux.dev
Cc: "Shardul Bankar" <shardul.b@mpiricsoftware.com>
Subject: Re: [PATCH mptcp-next v5 06/12] mptcp: remove CB offset field
Date: Wed, 27 May 2026 08:28:11 +0000	[thread overview]
Message-ID: <f5c9f4f37aaa1c80e4cee213afdeb483ca9d957d@linux.dev> (raw)
In-Reply-To: <ec9e2e3d5004c3fc86353fc9a419529c956f8e44.1778446731.git.pabeni@redhat.com>

May 11, 2026 at 5:03 AM, "Paolo Abeni" <pabeni@redhat.com mailto:pabeni@redhat.com?to=%22Paolo%20Abeni%22%20%3Cpabeni%40redhat.com%3E > wrote:


> 
> Instead, use a new msk-level field to track the bytes already consumed
> inside each skb, carrying the amount of bytes already copied to
> user-space, alike what TCP is already doing.
> 
> The newly introduce `copied_seq` field is always accessed under the msk
> socket lock, delegating the synchronization with IASN to the msk release
> CB, when the socket is owned by the user-space at remote key reception
> time. Such synchronization preserves any partial progress (copy) made on
> the TFO packet.
> 
> Note that the explicit synchronization in __mptcp_move_skb() is needed to
> ensure that the TFO skb in the receive queue got its map_seq synched
> before the next skb lands into the receive queue when spooling the backlog
> at mptcp_release_cb() time, as the release CB synchronization will happen
> later.
> 
> Prior to this patch, the TFO skb dummy mapping was always ignored, now it
> affects the `copied_seq` initial update: be sure to extends the sign
> correctly of such mapping initialization time.
> 
> Overall this simplify a bit the __mptcp_recvmsg_mskq(), mptcp_inq_hint()
> and the __mptcp_move_skb() code and will also make possible the next
> patch.
> 
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
> v4 -> v5:
>  - fix transient build issue, restoring a __mptcp_move_skb() chunk that
>  leaked in the next patch.
> 
> v3 -> v4:
>  - fix peek seq race
> 
> v2 -> v3:
>  - do not use msk->first in release_cb to deal with MPTCP_SYNC_SEQ:
>  subflow->iasn access is (data) racy and msk->first can be null, instead
>  recompute iasn from msk bytes_received and TFO skb len
>  - when updating copied_seq after remote key reception, add iasn to it
>  instead of overwriting, to avoid deleting any partial progress.
> 
> v1 -> v2:
>  - deal correctly with peek, as usally "inspired" from the correspondent
>  tcp code
>  - update mptcp_inq_hint(), too
> 
> Notes:
> - this explicitly relays on "mptcp: do not drop partial packets" to
> avoid dropping partially consumed packets
> - sashiko may confuse the 'offset' in mptcp_init_skb for an MPTCP-level
>  one, but it refers to the TCP sequence space. Conclusion out of the
>  that assumptions are wrong.
> - the data race in mptcp_inq_hint() is real, but pre-existing and can
>  impact only sockopt() output - the other call-sites are race free, as
>  ack_seq updates are serialized by the RX path.
>  Fixing the race for good without sashiko tripping on other similar
>  minor races would require another largish series. Postponed.
> - sashiko may see a race with `copied_seq` in mptcp_recv_skb(), that is
>  not real: subflow_set_remote_key()/__mptcp_sync_rcv_sequence() has seen
>  the msk owned; if mptcp_data_ready() has seen again the msk owend, the
>  only skb in the receive queue can be the (unsynched) TFO one, with dummy
>  sequence. If mptcp_data_ready() observed msk not owned and queued more
>  skbs, the release_cb() has run and synched `copied_seq` and TFO skb
>  map_seq.
> ---
>  net/mptcp/fastopen.c | 15 +++--
>  net/mptcp/protocol.c | 129 ++++++++++++++++++-------------------------
>  net/mptcp/protocol.h | 8 ++-
>  net/mptcp/subflow.c | 7 ++-
>  4 files changed, 77 insertions(+), 82 deletions(-)
> 
> diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
> index c7d5bee8088e..03e605b050f8 100644
> --- a/net/mptcp/fastopen.c
> +++ b/net/mptcp/fastopen.c
> @@ -9,6 +9,7 @@
>  void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow,
>  struct request_sock *req)
>  {
> + struct mptcp_sock *msk;
>  struct sock *sk, *ssk;
>  struct sk_buff *skb;
>  struct tcp_sock *tp;
> @@ -43,20 +44,24 @@ void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subf
>  subflow->ssn_offset += skb->len;
>  has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
>  
> - /* Only the sequence delta is relevant */
> - MPTCP_SKB_CB(skb)->map_seq = -skb->len;
> + /* The TFO segment data sits before the IASN; before receiving
> + * the remote key, IASN is assumed being 0.
> + */
> + MPTCP_SKB_CB(skb)->map_seq = -(u64)skb->len;
>  MPTCP_SKB_CB(skb)->end_seq = 0;
> - MPTCP_SKB_CB(skb)->offset = 0;
>  MPTCP_SKB_CB(skb)->has_rxtstamp = has_rxtstamp;
>  
>  mptcp_data_lock(sk);
>  DEBUG_NET_WARN_ON_ONCE(sock_owned_by_user_nocheck(sk));
>  
> - mptcp_sk(sk)->rcvd_dummy_seq = true;
> + msk = mptcp_sk(sk);
> + msk->rcvd_dummy_seq = true;
> + msk->copied_seq = MPTCP_SKB_CB(skb)->map_seq;
> + msk->tfo_skb_len = skb->len;
>  mptcp_borrow_fwdmem(sk, skb);
>  skb_set_owner_r(skb, sk);
>  __skb_queue_tail(&sk->sk_receive_queue, skb);
> - mptcp_sk(sk)->bytes_received += skb->len;
> + msk->bytes_received += skb->len;
>  
>  sk->sk_data_ready(sk);
>  
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 6909586a3090..47df6d4a26a7 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -28,7 +28,7 @@
>  #include "protocol.h"
>  #include "mib.h"
>  
> -static unsigned int mptcp_inq_hint(const struct sock *sk);
> +static unsigned int mptcp_inq_hint(struct sock *sk);
>  
>  #define CREATE_TRACE_POINTS
>  #include <trace/events/mptcp.h>
> @@ -160,7 +160,6 @@ static bool __mptcp_try_coalesce(struct sock *sk, struct sk_buff *to,
>  int limit = READ_ONCE(sk->sk_rcvbuf);
>  
>  if (MPTCP_SKB_CB(from)->map_seq != MPTCP_SKB_CB(to)->end_seq ||
> - MPTCP_SKB_CB(from)->offset ||
>  ((to->len + from->len) > (limit >> 3)) ||
>  !skb_try_coalesce(to, from, fragstolen, delta))
>  return false;
> @@ -342,8 +341,7 @@ static void mptcp_data_queue_ofo(struct mptcp_sock *msk, struct sk_buff *skb)
>  skb_set_owner_r(skb, sk);
>  }
>  
> -static void mptcp_init_skb(struct sock *ssk, struct sk_buff *skb, int offset,
> - int copy_len)
> +static void mptcp_init_skb(struct sock *ssk, struct sk_buff *skb, int offset)
>  {
>  struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
>  bool has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
> @@ -352,9 +350,9 @@ static void mptcp_init_skb(struct sock *ssk, struct sk_buff *skb, int offset,
>  * mptcp_subflow_get_mapped_dsn() is based on the current tp->copied_seq
>  * value
>  */
> - MPTCP_SKB_CB(skb)->map_seq = mptcp_subflow_get_mapped_dsn(subflow);
> - MPTCP_SKB_CB(skb)->end_seq = MPTCP_SKB_CB(skb)->map_seq + copy_len;
> - MPTCP_SKB_CB(skb)->offset = offset;
Hi Paolo:

Sorry for digging up this old thread.

Do you still plan to remove the offset field?

I've left some comments on Geliang's TLS patches [1], and the workaround patch needs
the offset field. Geliang and I would like to know whether you intend to drop it,
address it in the short term, or have no near-term plan for it.


[1] https://patchwork.kernel.org/project/mptcp/patch/6557d95ab11416b3e798781cf95811bd6dd60d9e.1779788090.git.tanggeliang@kylinos.cn/

Thanks
Gang

> + MPTCP_SKB_CB(skb)->map_seq = mptcp_subflow_get_mapped_dsn(subflow) -
> + offset;
> + MPTCP_SKB_CB(skb)->end_seq = MPTCP_SKB_CB(skb)->map_seq + skb->len;
>  MPTCP_SKB_CB(skb)->has_rxtstamp = has_rxtstamp;
>  
>  __skb_unlink(skb, &ssk->sk_receive_queue);
> @@ -377,8 +375,8 @@ void __mptcp_sync_rcv_sequence(struct sock *sk)
>  if (!skb)
>  return;
>  
> - MPTCP_SKB_CB(skb)->map_seq = msk->ack_seq - skb->len;
> - MPTCP_SKB_CB(skb)->end_seq = msk->ack_seq;
> + MPTCP_SKB_CB(skb)->map_seq = mptcp_iasn(msk) - skb->len;
> + MPTCP_SKB_CB(skb)->end_seq = MPTCP_SKB_CB(skb)->map_seq + skb->len;
>  }
>  
>  static bool __mptcp_move_skb(struct sock *sk, struct sk_buff *skb)
> @@ -405,6 +403,7 @@ static bool __mptcp_move_skb(struct sock *sk, struct sk_buff *skb)
>  }
>  
>  if (MPTCP_SKB_CB(skb)->map_seq == msk->ack_seq) {
> +add_queue:
>  /* in sequence */
>  msk->bytes_received += copy_len;
>  WRITE_ONCE(msk->ack_seq, msk->ack_seq + copy_len);
> @@ -418,28 +417,16 @@ static bool __mptcp_move_skb(struct sock *sk, struct sk_buff *skb)
>  } else if (after64(MPTCP_SKB_CB(skb)->map_seq, msk->ack_seq)) {
>  mptcp_data_queue_ofo(msk, skb);
>  return false;
> + } else if (after64(MPTCP_SKB_CB(skb)->end_seq, msk->ack_seq)) {
> + /* Partial packet: map_seq < ack_seq < end_seq.*/
> + copy_len -= msk->ack_seq - MPTCP_SKB_CB(skb)->map_seq;
> + goto add_queue;
>  }
>  
> - /* Completely old data? */
> - if (!after64(MPTCP_SKB_CB(skb)->end_seq, msk->ack_seq)) {
> - MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
> - mptcp_drop(sk, skb);
> - return false;
> - }
> -
> - /* Partial packet: map_seq < ack_seq < end_seq.
> - * Skip the already-acked bytes and enqueue the new data.
> - */
> - copy_len = MPTCP_SKB_CB(skb)->end_seq - msk->ack_seq;
> - MPTCP_SKB_CB(skb)->offset += msk->ack_seq - MPTCP_SKB_CB(skb)->map_seq;
> - MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq -
> - MPTCP_SKB_CB(skb)->map_seq;
> - msk->bytes_received += copy_len;
> - WRITE_ONCE(msk->ack_seq, msk->ack_seq + copy_len);
> -
> - skb_set_owner_r(skb, sk);
> - __skb_queue_tail(&sk->sk_receive_queue, skb);
> - return true;
> + /* Completely old data. */
> + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
> + mptcp_drop(sk, skb);
> + return false;
>  }
>  
>  static void mptcp_stop_rtx_timer(struct sock *sk)
> @@ -783,7 +770,7 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
>  if (offset < skb->len) {
>  size_t len = skb->len - offset;
>  
> - mptcp_init_skb(ssk, skb, offset, len);
> + mptcp_init_skb(ssk, skb, offset);
>  
>  if (own_msk) {
>  mptcp_subflow_lend_fwdmem(subflow, skb);
> @@ -850,8 +837,6 @@ static bool __mptcp_ofo_queue(struct mptcp_sock *msk)
>  pr_debug("uncoalesced seq=%llx ack seq=%llx delta=%d\n",
>  MPTCP_SKB_CB(skb)->map_seq, msk->ack_seq,
>  delta);
> - MPTCP_SKB_CB(skb)->offset += delta;
> - MPTCP_SKB_CB(skb)->map_seq += delta;
>  __skb_queue_tail(&sk->sk_receive_queue, skb);
>  }
>  msk->bytes_received += end_seq - msk->ack_seq;
> @@ -2095,34 +2080,22 @@ static void mptcp_eat_recv_skb(struct sock *sk, struct sk_buff *skb)
>  }
>  
>  static int __mptcp_recvmsg_mskq(struct sock *sk, struct msghdr *msg,
> - size_t len, int flags, int copied_total,
> + size_t len, int flags, u64 *seq,
>  struct scm_timestamping_internal *tss,
>  int *cmsg_flags, struct sk_buff **last)
>  {
>  struct mptcp_sock *msk = mptcp_sk(sk);
>  struct sk_buff *skb, *tmp;
> - int total_data_len = 0;
>  int copied = 0;
>  
>  skb_queue_walk_safe(&sk->sk_receive_queue, skb, tmp) {
> - u32 delta, offset = MPTCP_SKB_CB(skb)->offset;
> - u32 data_len = skb->len - offset;
> - u32 count;
> + u64 offset = *seq - MPTCP_SKB_CB(skb)->map_seq;
> + u32 count, data_len = skb->len - offset;
>  int err;
>  
> - if (flags & MSG_PEEK) {
> - /* skip already peeked skbs */
> - if (total_data_len + data_len <= copied_total) {
> - total_data_len += data_len;
> - *last = skb;
> - continue;
> - }
> -
> - /* skip the already peeked data in the current skb */
> - delta = copied_total - total_data_len;
> - offset += delta;
> - data_len -= delta;
> - }
> + /* Skip the already peeked data. */
> + if (offset >= skb->len)
> + continue;
>  
>  count = min_t(size_t, len - copied, data_len);
>  if (!(flags & MSG_TRUNC)) {
> @@ -2140,14 +2113,12 @@ static int __mptcp_recvmsg_mskq(struct sock *sk, struct msghdr *msg,
>  }
>  
>  copied += count;
> + *seq += count;
>  
>  if (!(flags & MSG_PEEK)) {
>  msk->bytes_consumed += count;
> - if (count < data_len) {
> - MPTCP_SKB_CB(skb)->offset += count;
> - MPTCP_SKB_CB(skb)->map_seq += count;
> + if (count < data_len)
>  break;
> - }
>  
>  mptcp_eat_recv_skb(sk, skb);
>  } else {
> @@ -2296,25 +2267,23 @@ static bool mptcp_move_skbs(struct sock *sk)
>  return enqueued;
>  }
>  
> -static unsigned int mptcp_inq_hint(const struct sock *sk)
> +static unsigned int mptcp_inq_hint(struct sock *sk)
>  {
>  const struct mptcp_sock *msk = mptcp_sk(sk);
> - const struct sk_buff *skb;
> -
> - skb = skb_peek(&sk->sk_receive_queue);
> - if (skb) {
> - u64 hint_val = READ_ONCE(msk->ack_seq) - MPTCP_SKB_CB(skb)->map_seq;
> + u64 hint_val;
>  
> - if (hint_val >= INT_MAX)
> - return INT_MAX;
> -
> - return (unsigned int)hint_val;
> - }
> + /* Avoid races vs ack_seq updates. */
> + mptcp_data_lock(sk);
> + hint_val = msk->ack_seq - msk->copied_seq;
> + mptcp_data_unlock(sk);
> + if (hint_val >= INT_MAX)
> + return INT_MAX;
>  
> - if (sk->sk_state == TCP_CLOSE || (sk->sk_shutdown & RCV_SHUTDOWN))
> + if (!hint_val &&
> + (sk->sk_state == TCP_CLOSE || (sk->sk_shutdown & RCV_SHUTDOWN)))
>  return 1;
>  
> - return 0;
> + return (unsigned int)hint_val;
>  }
>  
>  static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
> @@ -2323,6 +2292,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>  struct mptcp_sock *msk = mptcp_sk(sk);
>  struct scm_timestamping_internal tss;
>  int copied = 0, cmsg_flags = 0;
> + u64 peek_seq, *seq;
>  int target;
>  long timeo;
>  
> @@ -2342,6 +2312,11 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>  
>  len = min_t(size_t, len, INT_MAX);
>  target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
> + seq = &msk->copied_seq;
> + if (flags & MSG_PEEK) {
> + peek_seq = msk->copied_seq;
> + seq = &peek_seq;
> + }
>  
>  if (unlikely(msk->recvmsg_inq))
>  cmsg_flags = MPTCP_CMSG_INQ;
> @@ -2351,7 +2326,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>  int err, bytes_read;
>  
>  bytes_read = __mptcp_recvmsg_mskq(sk, msg, len - copied, flags,
> - copied, &tss, &cmsg_flags,
> + seq, &tss, &cmsg_flags,
>  &last);
>  if (unlikely(bytes_read < 0)) {
>  if (!copied)
> @@ -2406,6 +2381,10 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>  err = copied ? : err;
>  goto out_err;
>  }
> +
> + /* Recompute peek offset after eventual seq resync. */
> + if (flags & MSG_PEEK)
> + peek_seq = msk->copied_seq + copied;
>  }
>  
>  mptcp_cleanup_rbuf(msk, copied);
> @@ -3500,11 +3479,13 @@ static int mptcp_disconnect(struct sock *sk, int flags)
>  msk->bytes_retrans = 0;
>  msk->rcvspace_init = 0;
>  msk->fastclosing = 0;
> + msk->tfo_skb_len = 0;
>  mptcp_init_rtt_est(msk);
>  
>  /* for fallback's sake */
>  WRITE_ONCE(msk->ack_seq, 0);
>  atomic64_set(&msk->rcv_wnd_sent, 0);
> + msk->copied_seq = 0;
>  
>  WRITE_ONCE(sk->sk_shutdown, 0);
>  sk_error_report(sk);
> @@ -3729,8 +3710,10 @@ static void mptcp_release_cb(struct sock *sk)
>  __mptcp_error_report(sk);
>  if (__test_and_clear_bit(MPTCP_SYNC_SNDBUF, &msk->cb_flags))
>  __mptcp_sync_sndbuf(sk);
> - if (__test_and_clear_bit(MPTCP_SYNC_SEQ, &msk->cb_flags))
> + if (__test_and_clear_bit(MPTCP_SYNC_SEQ, &msk->cb_flags)) {
> + msk->copied_seq += mptcp_iasn(msk);
>  __mptcp_sync_rcv_sequence(sk);
> + }
>  }
>  }
>  
> @@ -4390,7 +4373,7 @@ static struct sk_buff *mptcp_recv_skb(struct sock *sk, u32 *off)
>  mptcp_move_skbs(sk);
>  
>  while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) {
> - offset = MPTCP_SKB_CB(skb)->offset;
> + offset = msk->copied_seq - MPTCP_SKB_CB(skb)->map_seq;
>  if (offset < skb->len) {
>  *off = offset;
>  return skb;
> @@ -4432,11 +4415,9 @@ static int __mptcp_read_sock(struct sock *sk, read_descriptor_t *desc,
>  copied += count;
>  
>  msk->bytes_consumed += count;
> - if (count < data_len) {
> - MPTCP_SKB_CB(skb)->offset += count;
> - MPTCP_SKB_CB(skb)->map_seq += count;
> + msk->copied_seq += count;
> + if (count < data_len)
>  break;
> - }
>  
>  mptcp_eat_recv_skb(sk, skb);
>  }
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 16a1f4531dad..f3d852e52982 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -129,7 +129,6 @@
>  struct mptcp_skb_cb {
>  u64 map_seq;
>  u64 end_seq;
> - u32 offset;
>  u8 has_rxtstamp;
>  };
>  
> @@ -289,6 +288,7 @@ struct mptcp_sock {
>  u64 bytes_sent;
>  u64 snd_nxt;
>  u64 bytes_received;
> + u64 copied_seq;
>  u64 ack_seq;
>  atomic64_t rcv_wnd_sent;
>  u64 rcv_data_fin_seq;
> @@ -308,6 +308,7 @@ struct mptcp_sock {
>  u32 last_ack_recv;
>  unsigned long timer_ival;
>  u32 token;
> + u32 tfo_skb_len;
>  unsigned long flags;
>  unsigned long cb_flags;
>  bool rcvd_dummy_seq;
> @@ -859,6 +860,11 @@ struct sock *mptcp_subflow_get_retrans(struct mptcp_sock *msk);
>  int mptcp_sched_get_send(struct mptcp_sock *msk);
>  int mptcp_sched_get_retrans(struct mptcp_sock *msk);
>  
> +static inline u64 mptcp_iasn(const struct mptcp_sock *msk)
> +{
> + return msk->ack_seq - msk->bytes_received + msk->tfo_skb_len;
> +}
> +
>  static inline u64 mptcp_data_avail(const struct mptcp_sock *msk)
>  {
>  return READ_ONCE(msk->bytes_received) - READ_ONCE(msk->bytes_consumed);
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index 5f371bf773f8..c8ea876bdd03 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -499,10 +499,13 @@ static void subflow_set_remote_key(struct mptcp_sock *msk,
>  WRITE_ONCE(msk->can_ack, true);
>  atomic64_set(&msk->rcv_wnd_sent, subflow->iasn);
>  
> - if (!sock_owned_by_user(sk))
> + if (!sock_owned_by_user(sk)) {
> + /* User space could have already read partially the TFO skb */
> + msk->copied_seq += subflow->iasn;
>  __mptcp_sync_rcv_sequence(sk);
> - else
> + } else {
>  __set_bit(MPTCP_SYNC_SEQ, &msk->cb_flags);
> + }
>  }
>  
>  static void mptcp_propagate_state(struct sock *sk, struct sock *ssk,
> -- 
> 2.54.0
>

  reply	other threads:[~2026-05-27  8:28 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-10 21:03 [PATCH mptcp-next v5 00/12] mptcp: address stall under memory pressure Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 01/12] mptcp: do not drop partial packets Paolo Abeni
2026-05-11 10:14   ` Matthieu Baerts
2026-05-11 10:29     ` Matthieu Baerts
2026-05-11 10:52       ` Matthieu Baerts
2026-05-10 21:03 ` [PATCH mptcp-next v5 02/12] mptcp: explicitly drop over memory limits Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 03/12] mptcp: enforce hard limit on backlog flushing Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 04/12] mptcp: drop the mptcp_ooo_try_coalesce() helper Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 05/12] mptcp: drop the cant_coalesce CB field Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 06/12] mptcp: remove CB offset field Paolo Abeni
2026-05-27  8:28   ` gang.yan [this message]
2026-05-10 21:03 ` [PATCH mptcp-next v5 07/12] mptcp: sync mptcp skb cb layout with tcp one Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 08/12] tcp: expose the tcp_collapse_ofo_queue() helper to mptcp usage, too Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 09/12] mptcp: implemented OoO queue pruning Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 10/12] mptcp: track prune recovery status Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 11/12] mptcp: move the retrans loop to a separate helper Paolo Abeni
2026-05-10 21:03 ` [PATCH mptcp-next v5 12/12] mptcp: let the retrans scheduler do its job Paolo Abeni
2026-05-10 22:16 ` [PATCH mptcp-next v5 00/12] mptcp: address stall under memory pressure MPTCP CI

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f5c9f4f37aaa1c80e4cee213afdeb483ca9d957d@linux.dev \
    --to=gang.yan@linux.dev \
    --cc=mptcp@lists.linux.dev \
    --cc=pabeni@redhat.com \
    --cc=shardul.b@mpiricsoftware.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox