mptcp: cleanup accept and poll
After the previous patch, msk->subflow will never be deleted during the whole msk lifetime. We don't need anymore to acquire references to it in mptcp_stream_accept() and we can use the listener subflow accept queue to simplify mptcp_poll() for listener socket. Overall this removes a lock pair and 4 more atomic operations per accept(). Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b29fcfb54c
commit
71ba088ce0
3 changed files with 7 additions and 20 deletions
|
@ -3493,17 +3493,9 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
|
||||||
|
|
||||||
pr_debug("msk=%p", msk);
|
pr_debug("msk=%p", msk);
|
||||||
|
|
||||||
lock_sock(sock->sk);
|
|
||||||
if (sock->sk->sk_state != TCP_LISTEN)
|
|
||||||
goto unlock_fail;
|
|
||||||
|
|
||||||
ssock = __mptcp_nmpc_socket(msk);
|
ssock = __mptcp_nmpc_socket(msk);
|
||||||
if (!ssock)
|
if (!ssock)
|
||||||
goto unlock_fail;
|
return -EINVAL;
|
||||||
|
|
||||||
clear_bit(MPTCP_DATA_READY, &msk->flags);
|
|
||||||
sock_hold(ssock->sk);
|
|
||||||
release_sock(sock->sk);
|
|
||||||
|
|
||||||
err = ssock->ops->accept(sock, newsock, flags, kern);
|
err = ssock->ops->accept(sock, newsock, flags, kern);
|
||||||
if (err == 0 && !mptcp_is_tcpsk(newsock->sk)) {
|
if (err == 0 && !mptcp_is_tcpsk(newsock->sk)) {
|
||||||
|
@ -3543,14 +3535,7 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
|
||||||
release_sock(newsk);
|
release_sock(newsk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inet_csk_listen_poll(ssock->sk))
|
|
||||||
set_bit(MPTCP_DATA_READY, &msk->flags);
|
|
||||||
sock_put(ssock->sk);
|
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
unlock_fail:
|
|
||||||
release_sock(sock->sk);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __poll_t mptcp_check_readable(struct mptcp_sock *msk)
|
static __poll_t mptcp_check_readable(struct mptcp_sock *msk)
|
||||||
|
@ -3596,8 +3581,12 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
|
||||||
|
|
||||||
state = inet_sk_state_load(sk);
|
state = inet_sk_state_load(sk);
|
||||||
pr_debug("msk=%p state=%d flags=%lx", msk, state, msk->flags);
|
pr_debug("msk=%p state=%d flags=%lx", msk, state, msk->flags);
|
||||||
if (state == TCP_LISTEN)
|
if (state == TCP_LISTEN) {
|
||||||
return test_bit(MPTCP_DATA_READY, &msk->flags) ? EPOLLIN | EPOLLRDNORM : 0;
|
if (WARN_ON_ONCE(!msk->subflow || !msk->subflow->sk))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return inet_csk_listen_poll(msk->subflow->sk);
|
||||||
|
}
|
||||||
|
|
||||||
if (state != TCP_SYN_SENT && state != TCP_SYN_RECV) {
|
if (state != TCP_SYN_SENT && state != TCP_SYN_RECV) {
|
||||||
mask |= mptcp_check_readable(msk);
|
mask |= mptcp_check_readable(msk);
|
||||||
|
|
|
@ -111,7 +111,6 @@
|
||||||
#define MPTCP_RST_TRANSIENT BIT(0)
|
#define MPTCP_RST_TRANSIENT BIT(0)
|
||||||
|
|
||||||
/* MPTCP socket flags */
|
/* MPTCP socket flags */
|
||||||
#define MPTCP_DATA_READY 0
|
|
||||||
#define MPTCP_NOSPACE 1
|
#define MPTCP_NOSPACE 1
|
||||||
#define MPTCP_WORK_RTX 2
|
#define MPTCP_WORK_RTX 2
|
||||||
#define MPTCP_WORK_EOF 3
|
#define MPTCP_WORK_EOF 3
|
||||||
|
|
|
@ -1293,7 +1293,6 @@ static void subflow_data_ready(struct sock *sk)
|
||||||
if (reqsk_queue_empty(&inet_csk(sk)->icsk_accept_queue))
|
if (reqsk_queue_empty(&inet_csk(sk)->icsk_accept_queue))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
set_bit(MPTCP_DATA_READY, &msk->flags);
|
|
||||||
parent->sk_data_ready(parent);
|
parent->sk_data_ready(parent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue