diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index b781498e69b4a474a73824dcffe031249d52c7fb..70f20c8eddbdf5f9a19fa1ae9aa2ec18ee68b154 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -201,12 +201,39 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk, return done; } -void mptcp_data_ready(struct sock *sk) +/* In most cases we will be able to lock the mptcp socket. If its already + * owned, we need to defer to the work queue to avoid ABBA deadlock. + */ +static bool move_skbs_to_msk(struct mptcp_sock *msk, struct sock *ssk) +{ + struct sock *sk = (struct sock *)msk; + unsigned int moved = 0; + + if (READ_ONCE(sk->sk_lock.owned)) + return false; + + if (unlikely(!spin_trylock_bh(&sk->sk_lock.slock))) + return false; + + /* must re-check after taking the lock */ + if (!READ_ONCE(sk->sk_lock.owned)) + __mptcp_move_skbs_from_subflow(msk, ssk, &moved); + + spin_unlock_bh(&sk->sk_lock.slock); + + return moved > 0; +} + +void mptcp_data_ready(struct sock *sk, struct sock *ssk) { struct mptcp_sock *msk = mptcp_sk(sk); set_bit(MPTCP_DATA_READY, &msk->flags); + if (atomic_read(&sk->sk_rmem_alloc) < READ_ONCE(sk->sk_rcvbuf) && + move_skbs_to_msk(msk, ssk)) + goto wake; + /* don't schedule if mptcp sk is (still) over limit */ if (atomic_read(&sk->sk_rmem_alloc) > READ_ONCE(sk->sk_rcvbuf)) goto wake; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index d06170c5f1914a74609da1f41ef26b99189dfb15..6c0b2c8ab674509bc73d1707e8f5ccccb5083c90 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -195,7 +195,7 @@ void mptcp_get_options(const struct sk_buff *skb, struct tcp_options_received *opt_rx); void mptcp_finish_connect(struct sock *sk); -void mptcp_data_ready(struct sock *sk); +void mptcp_data_ready(struct sock *sk, struct sock *ssk); int mptcp_token_new_request(struct request_sock *req); void mptcp_token_destroy_request(u32 token); diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 37a4767db4414e8de4fe746125c76a66098727ff..0de2a44bdaa0aa82e84a800665c7d58e4e193040 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -563,7 +563,7 @@ static void subflow_data_ready(struct sock *sk) } if (mptcp_subflow_data_available(sk)) - mptcp_data_ready(parent); + mptcp_data_ready(parent, sk); } static void subflow_write_space(struct sock *sk) @@ -696,7 +696,7 @@ static void subflow_state_change(struct sock *sk) * the data available machinery here. */ if (parent && subflow->mp_capable && mptcp_subflow_data_available(sk)) - mptcp_data_ready(parent); + mptcp_data_ready(parent, sk); if (parent && !(parent->sk_shutdown & RCV_SHUTDOWN) && !subflow->rx_eof && subflow_is_done(sk)) {