mptcp: add sched in mptcp_sock
authorGeliang Tang <geliang.tang@suse.com>
Mon, 21 Aug 2023 22:25:16 +0000 (15:25 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 23 Aug 2023 00:31:19 +0000 (17:31 -0700)
This patch adds a new struct member sched in struct mptcp_sock.
And two helpers mptcp_init_sched() and mptcp_release_sched() to
init and release it.

Init it with the sysctl scheduler in mptcp_init_sock(), copy the
scheduler from the parent in mptcp_sk_clone(), and release it in
__mptcp_destroy_sock().

Acked-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
Signed-off-by: Mat Martineau <martineau@kernel.org>
Link: https://lore.kernel.org/r/20230821-upstream-net-next-20230818-v1-5-0c860fb256a8@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/sched.c

index f15ff80..54a3ecc 100644 (file)
@@ -2697,6 +2697,7 @@ static void mptcp_ca_reset(struct sock *sk)
 static int mptcp_init_sock(struct sock *sk)
 {
        struct net *net = sock_net(sk);
+       int ret;
 
        __mptcp_init_sock(sk);
 
@@ -2706,6 +2707,11 @@ static int mptcp_init_sock(struct sock *sk)
        if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net))
                return -ENOMEM;
 
+       ret = mptcp_init_sched(mptcp_sk(sk),
+                              mptcp_sched_find(mptcp_get_scheduler(net)));
+       if (ret)
+               return ret;
+
        set_bit(SOCK_CUSTOM_SOCKOPT, &sk->sk_socket->flags);
 
        /* fetch the ca name; do it outside __mptcp_init_sock(), so that clone will
@@ -2851,6 +2857,7 @@ static void __mptcp_destroy_sock(struct sock *sk)
        mptcp_stop_timer(sk);
        sk_stop_timer(sk, &sk->sk_timer);
        msk->pm.status = 0;
+       mptcp_release_sched(msk);
 
        sk->sk_prot->destroy(sk);
 
@@ -3105,6 +3112,7 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk,
        msk->snd_una = msk->write_seq;
        msk->wnd_end = msk->snd_nxt + req->rsk_rcv_wnd;
        msk->setsockopt_seq = mptcp_sk(sk)->setsockopt_seq;
+       mptcp_init_sched(msk, mptcp_sk(sk)->sched);
 
        /* passive msk is created after the first/MPC subflow */
        msk->subflow_id = 2;
index bfa13a5..548c302 100644 (file)
@@ -312,6 +312,7 @@ struct mptcp_sock {
                                 * lock as such sock is freed after close().
                                 */
        struct mptcp_pm_data    pm;
+       struct mptcp_sched_ops  *sched;
        struct {
                u32     space;  /* bytes copied in last measurement window */
                u32     copied; /* bytes copied in this measurement window */
@@ -659,6 +660,9 @@ void mptcp_info2sockaddr(const struct mptcp_addr_info *info,
 struct mptcp_sched_ops *mptcp_sched_find(const char *name);
 int mptcp_register_scheduler(struct mptcp_sched_ops *sched);
 void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched);
+int mptcp_init_sched(struct mptcp_sock *msk,
+                    struct mptcp_sched_ops *sched);
+void mptcp_release_sched(struct mptcp_sock *msk);
 
 static inline bool __tcp_can_send(const struct sock *ssk)
 {
index c5d3bba..5377366 100644 (file)
@@ -54,3 +54,36 @@ void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched)
        list_del_rcu(&sched->list);
        spin_unlock(&mptcp_sched_list_lock);
 }
+
+int mptcp_init_sched(struct mptcp_sock *msk,
+                    struct mptcp_sched_ops *sched)
+{
+       if (!sched)
+               goto out;
+
+       if (!bpf_try_module_get(sched, sched->owner))
+               return -EBUSY;
+
+       msk->sched = sched;
+       if (msk->sched->init)
+               msk->sched->init(msk);
+
+       pr_debug("sched=%s", msk->sched->name);
+
+out:
+       return 0;
+}
+
+void mptcp_release_sched(struct mptcp_sock *msk)
+{
+       struct mptcp_sched_ops *sched = msk->sched;
+
+       if (!sched)
+               return;
+
+       msk->sched = NULL;
+       if (sched->release)
+               sched->release(msk);
+
+       bpf_module_put(sched, sched->owner);
+}