Message ID | e14151bf63b9ae2fa6f75061e1d0d2de069ec6b1.1742521397.git.tanggeliang@kylinos.cn (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Matthieu Baerts |
Headers | show |
Series | BPF path manager, part 6 | expand |
Context | Check | Description |
---|---|---|
matttbe/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 70 lines checked |
matttbe/shellcheck | success | MPTCP selftests files have not been modified |
matttbe/build | success | Build and static analysis OK |
matttbe/KVM_Validation__normal | success | Success! ✅ |
matttbe/KVM_Validation__debug | success | Success! ✅ |
matttbe/KVM_Validation__btf-normal__only_bpftest_all_ | success | Success! ✅ |
matttbe/KVM_Validation__btf-debug__only_bpftest_all_ | success | Success! ✅ |
On 21/03/2025 02:45, Geliang Tang wrote: > From: Geliang Tang <tanggeliang@kylinos.cn> > > This patch adds an optional .rm_addr_received interface for struct > mptcp_pm_ops and invokes it in mptcp_pm_worker() without PM lock. > Since mptcp_subflow_shutdown() and mptcp_close_ssk() are sleepable > kfuncs, .rm_addr_received interface of BPF PM should be invoked by > __bpf_prog_enter_sleepable(), which can't be invoked under a lock. > This patch unlocks the pm lock before invoking this interface in > mptcp_pm_worker(), while holding this lock in mptcp_pm_rm_addr_recv(). > > Export mptcp_pm_rm_addr_recv() is to allow the MPTCP_PM_RM_ADDR_RECEIVED > worker can be invoke from the in-kernel PM. > > With this, mptcp_pm_is_kernel() in mptcp_pm_rm_addr_or_subflow() can be > dropped. From what I understand, you are changing the behaviour for the userspace PM, no? When a RM_ADDR is received, for the moment, both the in-kernel and userspace PM removes the corresponding subflow(s). Now it is only the case with the in-kernel PM. Technically, it would be fine to let the userspace daemon reacting to the RM_ADDR event, but that's changing the behaviour. (...) > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c > index 7b34a59977cf..bb456e203665 100644 > --- a/net/mptcp/pm.c > +++ b/net/mptcp/pm.c > @@ -677,15 +677,17 @@ static void mptcp_pm_rm_addr_or_subflow(struct mptcp_sock *msk, > > if (rm_type == MPTCP_MIB_RMADDR) { > __MPTCP_INC_STATS(sock_net(sk), rm_type); > - if (removed && mptcp_pm_is_kernel(msk)) > + if (removed) > mptcp_pm_nl_rm_addr(msk, rm_id); As an alternative not to break the behaviour, you could add the hook here: if (removed && pm->ops->rm_addr_received) pm->ops->rm_addr_received(msk, rm_id); Cheers, Matt
diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 90fda6d1468c..bd8a20b9d02b 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -137,6 +137,7 @@ struct mptcp_pm_ops { /* optional */ int (*add_addr_received)(struct mptcp_sock *msk, const struct mptcp_addr_info *addr); + void (*rm_addr_received)(struct mptcp_sock *msk); char name[MPTCP_PM_NAME_MAX]; struct module *owner; diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 7b34a59977cf..bb456e203665 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -677,15 +677,17 @@ static void mptcp_pm_rm_addr_or_subflow(struct mptcp_sock *msk, if (rm_type == MPTCP_MIB_RMADDR) { __MPTCP_INC_STATS(sock_net(sk), rm_type); - if (removed && mptcp_pm_is_kernel(msk)) + if (removed) mptcp_pm_nl_rm_addr(msk, rm_id); } } } -static void mptcp_pm_rm_addr_recv(struct mptcp_sock *msk) +void mptcp_pm_rm_addr_recv(struct mptcp_sock *msk) { + spin_lock_bh(&msk->pm.lock); mptcp_pm_rm_addr_or_subflow(msk, &msk->pm.rm_list_rx, MPTCP_MIB_RMADDR); + spin_unlock_bh(&msk->pm.lock); } void mptcp_pm_rm_subflow(struct mptcp_sock *msk, @@ -705,6 +707,9 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, for (i = 0; i < rm_list->nr; i++) mptcp_event_addr_removed(msk, rm_list->ids[i]); + if (!pm->ops->rm_addr_received) + return; + spin_lock_bh(&pm->lock); if (mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED)) pm->rm_list_rx = *rm_list; @@ -931,7 +936,9 @@ void mptcp_pm_worker(struct mptcp_sock *msk) } if (pm->status & BIT(MPTCP_PM_RM_ADDR_RECEIVED)) { pm->status &= ~BIT(MPTCP_PM_RM_ADDR_RECEIVED); - mptcp_pm_rm_addr_recv(msk); + spin_unlock_bh(&pm->lock); + pm->ops->rm_addr_received(msk); + spin_lock_bh(&pm->lock); } if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) { pm->status &= ~BIT(MPTCP_PM_ESTABLISHED); diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c index 1a434abcf862..4f7b2e0e998d 100644 --- a/net/mptcp/pm_kernel.c +++ b/net/mptcp/pm_kernel.c @@ -1446,6 +1446,11 @@ static int mptcp_pm_kernel_add_addr_received(struct mptcp_sock *msk, return ret; } +static void mptcp_pm_kernel_rm_addr_received(struct mptcp_sock *msk) +{ + mptcp_pm_rm_addr_recv(msk); +} + static void mptcp_pm_kernel_init(struct mptcp_sock *msk) { bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); @@ -1475,6 +1480,7 @@ struct mptcp_pm_ops mptcp_pm_kernel = { .accept_new_subflow = mptcp_pm_kernel_accept_new_subflow, .add_addr_echo = mptcp_pm_kernel_add_addr_echo, .add_addr_received = mptcp_pm_kernel_add_addr_received, + .rm_addr_received = mptcp_pm_kernel_rm_addr_received, .init = mptcp_pm_kernel_init, .name = "kernel", .owner = THIS_MODULE, diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 784e787cf667..4883f786e8ea 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1031,6 +1031,7 @@ void mptcp_pm_rm_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list); void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list); +void mptcp_pm_rm_addr_recv(struct mptcp_sock *msk); void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup); void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq); int mptcp_pm_mp_prio_send_ack(struct mptcp_sock *msk,