Commit 866f26f2 authored by Paolo Abeni's avatar Paolo Abeni Committed by Jakub Kicinski

mptcp: always graft subflow socket to parent

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: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e26ca4b5
...@@ -114,11 +114,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk) ...@@ -114,11 +114,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk)
list_add(&subflow->node, &msk->conn_list); list_add(&subflow->node, &msk->conn_list);
sock_hold(ssock->sk); sock_hold(ssock->sk);
subflow->request_mptcp = 1; subflow->request_mptcp = 1;
mptcp_sock_graft(msk->first, sk->sk_socket);
/* 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);
return 0; return 0;
} }
...@@ -2116,9 +2112,6 @@ static struct sock *mptcp_subflow_get_retrans(const struct mptcp_sock *msk) ...@@ -2116,9 +2112,6 @@ static struct sock *mptcp_subflow_get_retrans(const struct mptcp_sock *msk)
void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
struct mptcp_subflow_context *subflow) struct mptcp_subflow_context *subflow)
{ {
bool dispose_socket = false;
struct socket *sock;
list_del(&subflow->node); list_del(&subflow->node);
lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
...@@ -2126,11 +2119,8 @@ void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, ...@@ -2126,11 +2119,8 @@ void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
/* if we are invoked by the msk cleanup code, the subflow is /* if we are invoked by the msk cleanup code, the subflow is
* already orphaned * already orphaned
*/ */
sock = ssk->sk_socket; if (ssk->sk_socket)
if (sock) {
dispose_socket = sock != sk->sk_socket;
sock_orphan(ssk); sock_orphan(ssk);
}
subflow->disposable = 1; subflow->disposable = 1;
...@@ -2148,8 +2138,6 @@ void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, ...@@ -2148,8 +2138,6 @@ void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
__sock_put(ssk); __sock_put(ssk);
} }
release_sock(ssk); release_sock(ssk);
if (dispose_socket)
iput(SOCK_INODE(sock));
sock_put(ssk); sock_put(ssk);
} }
...@@ -2536,6 +2524,12 @@ static void __mptcp_destroy_sock(struct sock *sk) ...@@ -2536,6 +2524,12 @@ static void __mptcp_destroy_sock(struct sock *sk)
pr_debug("msk=%p", msk); 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 /* be sure to always acquire the join list lock, to sync vs
* mptcp_finish_join(). * mptcp_finish_join().
*/ */
...@@ -2586,20 +2580,10 @@ static void mptcp_close(struct sock *sk, long timeout) ...@@ -2586,20 +2580,10 @@ static void mptcp_close(struct sock *sk, long timeout)
inet_csk(sk)->icsk_mtup.probe_timestamp = tcp_jiffies32; inet_csk(sk)->icsk_mtup.probe_timestamp = tcp_jiffies32;
list_for_each_entry(subflow, &mptcp_sk(sk)->conn_list, node) { list_for_each_entry(subflow, &mptcp_sk(sk)->conn_list, node) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow); struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
bool slow, dispose_socket; bool slow = lock_sock_fast(ssk);
struct socket *sock;
slow = lock_sock_fast(ssk);
sock = ssk->sk_socket;
dispose_socket = sock && sock != sk->sk_socket;
sock_orphan(ssk); sock_orphan(ssk);
unlock_sock_fast(ssk, slow); 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); sock_orphan(sk);
...@@ -3041,7 +3025,7 @@ void mptcp_finish_connect(struct sock *ssk) ...@@ -3041,7 +3025,7 @@ void mptcp_finish_connect(struct sock *ssk)
mptcp_rcv_space_init(msk, 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); write_lock_bh(&sk->sk_callback_lock);
rcu_assign_pointer(sk->sk_wq, &parent->wq); rcu_assign_pointer(sk->sk_wq, &parent->wq);
......
...@@ -473,6 +473,7 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how); ...@@ -473,6 +473,7 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
struct mptcp_subflow_context *subflow); struct mptcp_subflow_context *subflow);
void mptcp_subflow_reset(struct sock *ssk); void mptcp_subflow_reset(struct sock *ssk);
void mptcp_sock_graft(struct sock *sk, struct socket *parent);
/* called with sk socket lock held */ /* called with sk socket lock held */
int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
......
...@@ -1159,6 +1159,9 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, ...@@ -1159,6 +1159,9 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
if (err && err != -EINPROGRESS) if (err && err != -EINPROGRESS)
goto failed_unlink; goto failed_unlink;
/* discard the subflow socket */
mptcp_sock_graft(ssk, sk->sk_socket);
iput(SOCK_INODE(sf));
return err; return err;
failed_unlink: failed_unlink:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment