Commit 2e52213c79c0b94aff42ba898ad9ad57546be67d

Authored by Florian Westphal
Committed by David S. Miller
1 parent bfae9dae44

mptcp: avoid work queue scheduling if possible

We can't lock_sock() the mptcp socket from the subflow data_ready callback,
it would result in ABBA deadlock with the subflow socket lock.

We can however grab the spinlock: if that succeeds and the mptcp socket
is not owned at the moment, we can process the new skbs right away
without deferring this to the work queue.

This avoids the schedule_work and hence the small delay until the
work item is processed.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 3 changed files with 31 additions and 4 deletions Side-by-side Diff

net/mptcp/protocol.c
... ... @@ -201,11 +201,38 @@
201 201 return done;
202 202 }
203 203  
204   -void mptcp_data_ready(struct sock *sk)
  204 +/* In most cases we will be able to lock the mptcp socket. If its already
  205 + * owned, we need to defer to the work queue to avoid ABBA deadlock.
  206 + */
  207 +static bool move_skbs_to_msk(struct mptcp_sock *msk, struct sock *ssk)
205 208 {
  209 + struct sock *sk = (struct sock *)msk;
  210 + unsigned int moved = 0;
  211 +
  212 + if (READ_ONCE(sk->sk_lock.owned))
  213 + return false;
  214 +
  215 + if (unlikely(!spin_trylock_bh(&sk->sk_lock.slock)))
  216 + return false;
  217 +
  218 + /* must re-check after taking the lock */
  219 + if (!READ_ONCE(sk->sk_lock.owned))
  220 + __mptcp_move_skbs_from_subflow(msk, ssk, &moved);
  221 +
  222 + spin_unlock_bh(&sk->sk_lock.slock);
  223 +
  224 + return moved > 0;
  225 +}
  226 +
  227 +void mptcp_data_ready(struct sock *sk, struct sock *ssk)
  228 +{
206 229 struct mptcp_sock *msk = mptcp_sk(sk);
207 230  
208 231 set_bit(MPTCP_DATA_READY, &msk->flags);
  232 +
  233 + if (atomic_read(&sk->sk_rmem_alloc) < READ_ONCE(sk->sk_rcvbuf) &&
  234 + move_skbs_to_msk(msk, ssk))
  235 + goto wake;
209 236  
210 237 /* don't schedule if mptcp sk is (still) over limit */
211 238 if (atomic_read(&sk->sk_rmem_alloc) > READ_ONCE(sk->sk_rcvbuf))
net/mptcp/protocol.h
... ... @@ -195,7 +195,7 @@
195 195 struct tcp_options_received *opt_rx);
196 196  
197 197 void mptcp_finish_connect(struct sock *sk);
198   -void mptcp_data_ready(struct sock *sk);
  198 +void mptcp_data_ready(struct sock *sk, struct sock *ssk);
199 199  
200 200 int mptcp_token_new_request(struct request_sock *req);
201 201 void mptcp_token_destroy_request(u32 token);
... ... @@ -563,7 +563,7 @@
563 563 }
564 564  
565 565 if (mptcp_subflow_data_available(sk))
566   - mptcp_data_ready(parent);
  566 + mptcp_data_ready(parent, sk);
567 567 }
568 568  
569 569 static void subflow_write_space(struct sock *sk)
... ... @@ -696,7 +696,7 @@
696 696 * the data available machinery here.
697 697 */
698 698 if (parent && subflow->mp_capable && mptcp_subflow_data_available(sk))
699   - mptcp_data_ready(parent);
  699 + mptcp_data_ready(parent, sk);
700 700  
701 701 if (parent && !(parent->sk_shutdown & RCV_SHUTDOWN) &&
702 702 !subflow->rx_eof && subflow_is_done(sk)) {