]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
mptcp: always graft subflow socket to parent
authorPaolo Abeni <pabeni@redhat.com>
Wed, 20 Jan 2021 14:39:10 +0000 (15:39 +0100)
committerSeth Forshee <seth.forshee@canonical.com>
Wed, 17 Mar 2021 18:39:50 +0000 (13:39 -0500)
BugLink: https://bugs.launchpad.net/bugs/1919492
[ Upstream commit 866f26f2a9c33bc70eb0f07ffc37fd9424ffe501 ]

Currently, incoming subflows link to the parent socket,
while outgoing ones link to a per subflow socket. The latter
is not really needed, except at the initial connect() time and
for the first subflow.

Always graft the outgoing subflow to the parent socket and
free the unneeded ones early.

This allows some code cleanup, reduces the amount of memory
used and will simplify the next patch

Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/subflow.c

index b51872b9dd619b7eaa421be46aa59359772e78a2..3cc7be259396c66aae304a9785adbd435c6a3d8e 100644 (file)
@@ -114,11 +114,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk)
        list_add(&subflow->node, &msk->conn_list);
        sock_hold(ssock->sk);
        subflow->request_mptcp = 1;
-
-       /* accept() will wait on first subflow sk_wq, and we always wakes up
-        * via msk->sk_socket
-        */
-       RCU_INIT_POINTER(msk->first->sk_wq, &sk->sk_socket->wq);
+       mptcp_sock_graft(msk->first, sk->sk_socket);
 
        return 0;
 }
@@ -2114,9 +2110,6 @@ static struct sock *mptcp_subflow_get_retrans(const struct mptcp_sock *msk)
 void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
                       struct mptcp_subflow_context *subflow)
 {
-       bool dispose_socket = false;
-       struct socket *sock;
-
        list_del(&subflow->node);
 
        lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
@@ -2124,11 +2117,8 @@ void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
        /* if we are invoked by the msk cleanup code, the subflow is
         * already orphaned
         */
-       sock = ssk->sk_socket;
-       if (sock) {
-               dispose_socket = sock != sk->sk_socket;
+       if (ssk->sk_socket)
                sock_orphan(ssk);
-       }
 
        subflow->disposable = 1;
 
@@ -2146,8 +2136,6 @@ void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
                __sock_put(ssk);
        }
        release_sock(ssk);
-       if (dispose_socket)
-               iput(SOCK_INODE(sock));
 
        sock_put(ssk);
 }
@@ -2535,6 +2523,12 @@ static void __mptcp_destroy_sock(struct sock *sk)
 
        pr_debug("msk=%p", msk);
 
+       /* dispose the ancillatory tcp socket, if any */
+       if (msk->subflow) {
+               iput(SOCK_INODE(msk->subflow));
+               msk->subflow = NULL;
+       }
+
        /* be sure to always acquire the join list lock, to sync vs
         * mptcp_finish_join().
         */
@@ -2585,20 +2579,10 @@ cleanup:
        inet_csk(sk)->icsk_mtup.probe_timestamp = tcp_jiffies32;
        list_for_each_entry(subflow, &mptcp_sk(sk)->conn_list, node) {
                struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
-               bool slow, dispose_socket;
-               struct socket *sock;
+               bool slow = lock_sock_fast(ssk);
 
-               slow = lock_sock_fast(ssk);
-               sock = ssk->sk_socket;
-               dispose_socket = sock && sock != sk->sk_socket;
                sock_orphan(ssk);
                unlock_sock_fast(ssk, slow);
-
-               /* for the outgoing subflows we additionally need to free
-                * the associated socket
-                */
-               if (dispose_socket)
-                       iput(SOCK_INODE(sock));
        }
        sock_orphan(sk);
 
@@ -3040,7 +3024,7 @@ void mptcp_finish_connect(struct sock *ssk)
        mptcp_rcv_space_init(msk, ssk);
 }
 
-static void mptcp_sock_graft(struct sock *sk, struct socket *parent)
+void mptcp_sock_graft(struct sock *sk, struct socket *parent)
 {
        write_lock_bh(&sk->sk_callback_lock);
        rcu_assign_pointer(sk->sk_wq, &parent->wq);
index dbf62e74fcc1adcda2e1dbf9c83de0442d928770..18fef4273bdc63482dddcffd4b790bb17c6faa40 100644 (file)
@@ -460,6 +460,7 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
 void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
                       struct mptcp_subflow_context *subflow);
 void mptcp_subflow_reset(struct sock *ssk);
+void mptcp_sock_graft(struct sock *sk, struct socket *parent);
 
 /* called with sk socket lock held */
 int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
index 9d28f6e3dc49a44013b787d3c5c84f4639fa0292..81b7be67d288aa9a7dd2fbbc59ffe8f461b42ca0 100644 (file)
@@ -1165,6 +1165,9 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
        if (err && err != -EINPROGRESS)
                goto failed_unlink;
 
+       /* discard the subflow socket */
+       mptcp_sock_graft(ssk, sk->sk_socket);
+       iput(SOCK_INODE(sf));
        return err;
 
 failed_unlink: