Skip to content

Commit cf45860

Browse files
Paolo Abenimehmetb0
authored andcommitted
mptcp: don't always assume copied data in mptcp_cleanup_rbuf()
BugLink: https://bugs.launchpad.net/bugs/2098441 commit 551844f upstream. Under some corner cases the MPTCP protocol can end-up invoking mptcp_cleanup_rbuf() when no data has been copied, but such helper assumes the opposite condition. Explicitly drop such assumption and performs the costly call only when strictly needed - before releasing the msk socket lock. Fixes: fd89767 ("mptcp: be careful on MPTCP-level ack.") Cc: [email protected] Signed-off-by: Paolo Abeni <[email protected]> Reviewed-by: Mat Martineau <[email protected]> Signed-off-by: Matthieu Baerts (NGI0) <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> [ Conflicts in this version, because commit 5813022 ("mptcp: error out earlier on disconnect") has not been backported to this version, and there was no need to do so. The only conflict was in protocol.c, and easy to resolve: the context was different, but the same addition can still be made at the same spot in mptcp_recvmsg(). ] Signed-off-by: Matthieu Baerts (NGI0) <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Noah Wager <[email protected]> Signed-off-by: Koichiro Den <[email protected]>
1 parent fc247ea commit cf45860

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

net/mptcp/protocol.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,13 @@ static void mptcp_send_ack(struct mptcp_sock *msk)
462462
mptcp_subflow_send_ack(mptcp_subflow_tcp_sock(subflow));
463463
}
464464

465-
static void mptcp_subflow_cleanup_rbuf(struct sock *ssk)
465+
static void mptcp_subflow_cleanup_rbuf(struct sock *ssk, int copied)
466466
{
467467
bool slow;
468468

469469
slow = lock_sock_fast(ssk);
470470
if (tcp_can_send_ack(ssk))
471-
tcp_cleanup_rbuf(ssk, 1);
471+
tcp_cleanup_rbuf(ssk, copied);
472472
unlock_sock_fast(ssk, slow);
473473
}
474474

@@ -485,22 +485,22 @@ static bool mptcp_subflow_could_cleanup(const struct sock *ssk, bool rx_empty)
485485
(ICSK_ACK_PUSHED2 | ICSK_ACK_PUSHED)));
486486
}
487487

488-
static void mptcp_cleanup_rbuf(struct mptcp_sock *msk)
488+
static void mptcp_cleanup_rbuf(struct mptcp_sock *msk, int copied)
489489
{
490490
int old_space = READ_ONCE(msk->old_wspace);
491491
struct mptcp_subflow_context *subflow;
492492
struct sock *sk = (struct sock *)msk;
493493
int space = __mptcp_space(sk);
494494
bool cleanup, rx_empty;
495495

496-
cleanup = (space > 0) && (space >= (old_space << 1));
497-
rx_empty = !__mptcp_rmem(sk);
496+
cleanup = (space > 0) && (space >= (old_space << 1)) && copied;
497+
rx_empty = !__mptcp_rmem(sk) && copied;
498498

499499
mptcp_for_each_subflow(msk, subflow) {
500500
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
501501

502502
if (cleanup || mptcp_subflow_could_cleanup(ssk, rx_empty))
503-
mptcp_subflow_cleanup_rbuf(ssk);
503+
mptcp_subflow_cleanup_rbuf(ssk, copied);
504504
}
505505
}
506506

@@ -2098,9 +2098,6 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
20982098

20992099
copied += bytes_read;
21002100

2101-
/* be sure to advertise window change */
2102-
mptcp_cleanup_rbuf(msk);
2103-
21042101
if (skb_queue_empty(&msk->receive_queue) && __mptcp_move_skbs(msk))
21052102
continue;
21062103

@@ -2152,9 +2149,12 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
21522149
}
21532150

21542151
pr_debug("block timeout %ld\n", timeo);
2152+
mptcp_cleanup_rbuf(msk, copied);
21552153
sk_wait_data(sk, &timeo, NULL);
21562154
}
21572155

2156+
mptcp_cleanup_rbuf(msk, copied);
2157+
21582158
out_err:
21592159
if (cmsg_flags && copied >= 0) {
21602160
if (cmsg_flags & MPTCP_CMSG_TS)

0 commit comments

Comments
 (0)