Skip to content

Commit

Permalink
mptcp: Avoid acquiring PM lock for subflow priority changes
Browse files Browse the repository at this point in the history
The in-kernel path manager code for changing subflow flags acquired both
the msk socket lock and the PM lock when possibly changing the "backup"
and "fullmesh" flags. mptcp_pm_nl_mp_prio_send_ack() does not access
anything protected by the PM lock, and it must release and reacquire
the PM lock.

By pushing the PM lock to where it is needed in mptcp_pm_nl_fullmesh(),
the lock is only acquired when the fullmesh flag is changed and the
backup flag code no longer has to release and reacquire the PM lock. The
change in locking context requires the MIB update to be modified - move
that to a better location instead.

This change also makes it possible to call
mptcp_pm_nl_mp_prio_send_ack() for the userspace PM commands without
manipulating the in-kernel PM lock.

Fixes: 0f9f696 ("mptcp: add set_flags command in PM netlink")
Acked-by: Paolo Abeni <[email protected]>
Signed-off-by: Mat Martineau <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
mjmartineau authored and davem330 committed Jul 6, 2022
1 parent 5ccecae commit c21b50d
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 6 deletions.
3 changes: 3 additions & 0 deletions net/mptcp/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -1584,6 +1584,9 @@ void mptcp_write_options(struct tcphdr *th, __be32 *ptr, struct tcp_sock *tp,
*ptr++ = mptcp_option(MPTCPOPT_MP_PRIO,
TCPOLEN_MPTCP_PRIO,
opts->backup, TCPOPT_NOP);

MPTCP_INC_STATS(sock_net((const struct sock *)tp),
MPTCP_MIB_MPPRIOTX);
}

mp_capable_done:
Expand Down
8 changes: 2 additions & 6 deletions net/mptcp/pm_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,6 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,

mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
struct sock *sk = (struct sock *)msk;
struct mptcp_addr_info local;

local_address((struct sock_common *)ssk, &local);
Expand All @@ -739,12 +738,9 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
subflow->backup = bkup;
subflow->send_mp_prio = 1;
subflow->request_bkup = bkup;
__MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPPRIOTX);

spin_unlock_bh(&msk->pm.lock);
pr_debug("send ack for mp_prio");
mptcp_subflow_send_ack(ssk);
spin_lock_bh(&msk->pm.lock);

return 0;
}
Expand Down Expand Up @@ -1816,8 +1812,10 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,

list.ids[list.nr++] = addr->id;

spin_lock_bh(&msk->pm.lock);
mptcp_pm_nl_rm_subflow_received(msk, &list);
mptcp_pm_create_subflow_or_signal_addr(msk);
spin_unlock_bh(&msk->pm.lock);
}

static int mptcp_nl_set_flags(struct net *net,
Expand All @@ -1835,12 +1833,10 @@ static int mptcp_nl_set_flags(struct net *net,
goto next;

lock_sock(sk);
spin_lock_bh(&msk->pm.lock);
if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup);
if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
mptcp_pm_nl_fullmesh(msk, addr);
spin_unlock_bh(&msk->pm.lock);
release_sock(sk);

next:
Expand Down

0 comments on commit c21b50d

Please sign in to comment.