Skip to content

Commit 7955fc7

Browse files
Paolo Abeniintel-lab-lkp
authored andcommitted
mptcp: don't always assume copied data in mptcp_cleanup_rbuf()
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.") Signed-off-by: Paolo Abeni <[email protected]>
1 parent ab44d3b commit 7955fc7

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
@@ -529,13 +529,13 @@ static void mptcp_send_ack(struct mptcp_sock *msk)
529529
mptcp_subflow_send_ack(mptcp_subflow_tcp_sock(subflow));
530530
}
531531

532-
static void mptcp_subflow_cleanup_rbuf(struct sock *ssk)
532+
static void mptcp_subflow_cleanup_rbuf(struct sock *ssk, int copied)
533533
{
534534
bool slow;
535535

536536
slow = lock_sock_fast(ssk);
537537
if (tcp_can_send_ack(ssk))
538-
tcp_cleanup_rbuf(ssk, 1);
538+
tcp_cleanup_rbuf(ssk, copied);
539539
unlock_sock_fast(ssk, slow);
540540
}
541541

@@ -552,22 +552,22 @@ static bool mptcp_subflow_could_cleanup(const struct sock *ssk, bool rx_empty)
552552
(ICSK_ACK_PUSHED2 | ICSK_ACK_PUSHED)));
553553
}
554554

555-
static void mptcp_cleanup_rbuf(struct mptcp_sock *msk)
555+
static void mptcp_cleanup_rbuf(struct mptcp_sock *msk, int copied)
556556
{
557557
int old_space = READ_ONCE(msk->old_wspace);
558558
struct mptcp_subflow_context *subflow;
559559
struct sock *sk = (struct sock *)msk;
560560
int space = __mptcp_space(sk);
561561
bool cleanup, rx_empty;
562562

563-
cleanup = (space > 0) && (space >= (old_space << 1));
564-
rx_empty = !__mptcp_rmem(sk);
563+
cleanup = (space > 0) && (space >= (old_space << 1)) && copied;
564+
rx_empty = !__mptcp_rmem(sk) && copied;
565565

566566
mptcp_for_each_subflow(msk, subflow) {
567567
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
568568

569569
if (cleanup || mptcp_subflow_could_cleanup(ssk, rx_empty))
570-
mptcp_subflow_cleanup_rbuf(ssk);
570+
mptcp_subflow_cleanup_rbuf(ssk, copied);
571571
}
572572
}
573573

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

22222222
copied += bytes_read;
22232223

2224-
/* be sure to advertise window change */
2225-
mptcp_cleanup_rbuf(msk);
2226-
22272224
if (skb_queue_empty(&msk->receive_queue) && __mptcp_move_skbs(msk))
22282225
continue;
22292226

@@ -2272,13 +2269,16 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
22722269
}
22732270

22742271
pr_debug("block timeout %ld\n", timeo);
2272+
mptcp_cleanup_rbuf(msk, copied);
22752273
err = sk_wait_data(sk, &timeo, NULL);
22762274
if (err < 0) {
22772275
err = copied ? : err;
22782276
goto out_err;
22792277
}
22802278
}
22812279

2280+
mptcp_cleanup_rbuf(msk, copied);
2281+
22822282
out_err:
22832283
if (cmsg_flags && copied >= 0) {
22842284
if (cmsg_flags & MPTCP_CMSG_TS)

0 commit comments

Comments
 (0)