[PATCH mptcp-next v2 5/5] Squash to "bpf: Add mptcp packet scheduler struct_ops"
Gang Yan <[email protected]>
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <[email protected]> |
From: Gang Yan <[email protected]> The pernet sysctl patches in this series swap the scheduler pointer with xchg() without taking any module reference: this is fine while ops can only be registered from built-in code. This commit is what makes BPF schedulers registerable, i.e. the first one whose ops can be unloaded while a pernet still stores them. Take the reference accordingly: - mptcp_pernet_set_defaults() pins &mptcp_sched_default, mirroring tcp_sk_init() pinning &tcp_reno; - mptcp_set_scheduler() takes a reference on the new ops and releases the one held on the ops it replaces, mirroring tcp_set_default_congestion_control(); - mptcp_net_exit() releases the last reference, mirroring tcp_sk_exit(). Assisted-by: Claude:GLM5.2 Co-developed-by: Tao Cui <[email protected]> Signed-off-by: Tao Cui <[email protected]> Signed-off-by: Gang Yan <[email protected]> --- net/mptcp/ctrl.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index 32268aa26097..309bbb2a4eb0 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -123,7 +123,8 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet) pernet->stale_loss_cnt = 4; pernet->pm_type = MPTCP_PM_TYPE_KERNEL; - RCU_INIT_POINTER(pernet->scheduler, &mptcp_sched_default); + if (bpf_try_module_get(&mptcp_sched_default, mptcp_sched_default.owner)) + RCU_INIT_POINTER(pernet->scheduler, &mptcp_sched_default); if (bpf_try_module_get(&mptcp_pm_kernel, mptcp_pm_kernel.owner)) RCU_INIT_POINTER(pernet->path_manager, &mptcp_pm_kernel); @@ -134,15 +135,22 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet) #ifdef CONFIG_SYSCTL static int mptcp_set_scheduler(struct mptcp_pernet *pernet, const char *name) { - struct mptcp_sched_ops *sched; + struct mptcp_sched_ops *sched, *prev; int ret = 0; rcu_read_lock(); sched = mptcp_sched_find(name); - if (sched) - xchg(&pernet->scheduler, sched); - else + if (sched) { + if (bpf_try_module_get(sched, sched->owner)) { + prev = xchg(&pernet->scheduler, sched); + if (prev) + bpf_module_put(prev, prev->owner); + } else { + ret = -EBUSY; + } + } else { ret = -ENOENT; + } rcu_read_unlock(); return ret; @@ -603,10 +611,15 @@ static int __net_init mptcp_net_init(struct net *net) static void __net_exit mptcp_net_exit(struct net *net) { struct mptcp_pernet *pernet = mptcp_get_pernet(net); + struct mptcp_sched_ops *sched; struct mptcp_pm_ops *pm; mptcp_pernet_del_table(pernet); + sched = rcu_dereference_protected(pernet->scheduler, true); + if (sched) + bpf_module_put(sched, sched->owner); + pm = rcu_dereference_protected(pernet->path_manager, true); if (pm) bpf_module_put(pm, pm->owner); -- 2.43.0