Skip to content

Commit c2e6048

Browse files
Paolo Abenidavem330
authored andcommitted
mptcp: fix race in release_cb
If we receive a MPTCP_PUSH_PENDING even from a subflow when mptcp_release_cb() is serving the previous one, the latter will be delayed up to the next release_sock(msk). Address the issue implementing a test/serve loop for such event. Additionally rename the push helper to __mptcp_push_pending() to be more consistent with the existing code. Fixes: 6e628cd ("mptcp: use mptcp release_cb for delayed tasks") Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2948d0a commit c2e6048

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

net/mptcp/protocol.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,7 @@ static void mptcp_push_release(struct sock *sk, struct sock *ssk,
14451445
release_sock(ssk);
14461446
}
14471447

1448-
static void mptcp_push_pending(struct sock *sk, unsigned int flags)
1448+
static void __mptcp_push_pending(struct sock *sk, unsigned int flags)
14491449
{
14501450
struct sock *prev_ssk = NULL, *ssk = NULL;
14511451
struct mptcp_sock *msk = mptcp_sk(sk);
@@ -1697,14 +1697,14 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
16971697

16981698
wait_for_memory:
16991699
mptcp_set_nospace(sk);
1700-
mptcp_push_pending(sk, msg->msg_flags);
1700+
__mptcp_push_pending(sk, msg->msg_flags);
17011701
ret = sk_stream_wait_memory(sk, &timeo);
17021702
if (ret)
17031703
goto out;
17041704
}
17051705

17061706
if (copied)
1707-
mptcp_push_pending(sk, msg->msg_flags);
1707+
__mptcp_push_pending(sk, msg->msg_flags);
17081708

17091709
out:
17101710
release_sock(sk);
@@ -2959,13 +2959,14 @@ static void mptcp_release_cb(struct sock *sk)
29592959
{
29602960
unsigned long flags, nflags;
29612961

2962-
/* push_pending may touch wmem_reserved, do it before the later
2963-
* cleanup
2964-
*/
2965-
if (test_and_clear_bit(MPTCP_CLEAN_UNA, &mptcp_sk(sk)->flags))
2966-
__mptcp_clean_una(sk);
2967-
if (test_and_clear_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags)) {
2968-
/* mptcp_push_pending() acquires the subflow socket lock
2962+
for (;;) {
2963+
flags = 0;
2964+
if (test_and_clear_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags))
2965+
flags |= MPTCP_PUSH_PENDING;
2966+
if (!flags)
2967+
break;
2968+
2969+
/* the following actions acquire the subflow socket lock
29692970
*
29702971
* 1) can't be invoked in atomic scope
29712972
* 2) must avoid ABBA deadlock with msk socket spinlock: the RX
@@ -2974,13 +2975,21 @@ static void mptcp_release_cb(struct sock *sk)
29742975
*/
29752976

29762977
spin_unlock_bh(&sk->sk_lock.slock);
2977-
mptcp_push_pending(sk, 0);
2978+
if (flags & MPTCP_PUSH_PENDING)
2979+
__mptcp_push_pending(sk, 0);
2980+
2981+
cond_resched();
29782982
spin_lock_bh(&sk->sk_lock.slock);
29792983
}
2984+
2985+
if (test_and_clear_bit(MPTCP_CLEAN_UNA, &mptcp_sk(sk)->flags))
2986+
__mptcp_clean_una(sk);
29802987
if (test_and_clear_bit(MPTCP_ERROR_REPORT, &mptcp_sk(sk)->flags))
29812988
__mptcp_error_report(sk);
29822989

2983-
/* clear any wmem reservation and errors */
2990+
/* push_pending may touch wmem_reserved, ensure we do the cleanup
2991+
* later
2992+
*/
29842993
__mptcp_update_wmem(sk);
29852994
__mptcp_update_rmem(sk);
29862995

0 commit comments

Comments
 (0)