tcp: factor out a couple of helpers
Subsystems (4)
Paolo Abeni
maintainercover tcp: factor out a couple of helpers
Upcoming improvement in MPTCP subflows management will require to keep write data enqueued at the MPTCP level. As a side effect, such data could be sent via orphaned TCP subflows after close().
To implement the above MPTCP needs to cope directly with memory allocation failures in do_tcp_sendpages(). The solution proposed in patch 1/2 is to factor-out the relevant slice of do_tcp_sendpages().
Other possible alternatives could be:
- duplicating the relevant code inside MPTCP (will require exposing a few additional TCP helpers)
or
- add an explicit check for orphaned socket in do_tcp_sendpages()
Additionally, due to the above, we will need to dispose of already orphaned TCP subflows, avoiding racing with tcp_done(). We need to check the subflow status and destroy it atomically. The solution proposed in patch 2/2 is to factor-out the unlocked body of tcp_close().
These changes are part of a quite larger MPTCP series, with all the other patches touching only MPTCP code. To hopefully simplify the review, such patches are not included here. Please advice if you prefer otherwise
- e.g. the whole series as RFC.
Paolo Abeni (2):
tcp: factor out tcp_build_frag()
tcp: factor out __tcp_close() helper
include/net/tcp.h | 4 ++ net/ipv4/tcp.c | 128 +++++++++++++++++++++++++++------------------- 2 files changed, 78 insertions(+), 54 deletions(-)
Signature · 1 line
2.26.2
Paolo Abeni
maintainerRFC PATCH 1/2 tcp: factor out tcp_build_frag()
Will be needed by the next patch, as MPTCP needs to handle directly the error/memory-allocation-needed path.
No functional changes intended.
Additionally let MPTCP code access the tcp_remove_empty_skb() helper.
--- include/net/tcp.h | 3 ++ net/ipv4/tcp.c | 119 ++++++++++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 52 deletions(-)
include/net/tcp.h +3 -0
@@ -322,6 +322,7 @@ void tcp_shutdown(struct sock *sk, int how);int tcp_v4_early_demux (struct sk_buff *skb);int tcp_v4_rcv (struct sk_buff *skb); +void tcp_remove_empty_skb (struct sock *sk,struct sk_buff *skb);int tcp_v4_tw_remember_stamp (struct inet_timewait_sock *tw);int tcp_sendmsg (struct sock *sk,struct msghdr *msg,size_t size);int tcp_sendmsg_locked (struct sock *sk,struct msghdr *msg,size_t size);
@@ -329,6 +330,8 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset, size_t size, int flags);int tcp_sendpage_locked (struct sock *sk,struct page *page,int offset,size_t size,int flags); +struct sk_buff *tcp_build_frag (struct sock *sk,int size_goal,int flags, +struct page *page,int offset,size_t *size);ssize_t do_tcp_sendpages (struct sock *sk,struct page *page,int offset,size_t size,int flags);int tcp_send_mss (struct sock *sk,int *size_goal,int flags);
net/ipv4/tcp.c +67 -52
140 lines not on this page · raw message
Signature · 1 line
2.26.2
Paolo Abeni
maintainerRFC PATCH 2/2 tcp: factor out __tcp_close() helper
In reply to Paolo Abeniunlocked version of protocol level close, will be used by MPTCP to allow decouple orphaning and subflow level close.
--- include/net/tcp.h | 1 + net/ipv4/tcp.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
include/net/tcp.h +1 -0
@@ -395,6 +395,7 @@ void tcp_update_metrics(struct sock *sk);void tcp_init_metrics (struct sock *sk);void tcp_metrics_init (void );bool tcp_peer_is_proven (struct request_sock *req,struct dst_entry *dst); +void __tcp_close (struct sock *sk,long timeout);void tcp_close (struct sock *sk,long timeout);void tcp_init_sock (struct sock *sk);void tcp_init_transfer (struct sock *sk,int bpf_op,struct sk_buff *skb);
net/ipv4/tcp.c +7 -2
@@ -2418,13 +2418,12 @@ bool tcp_check_oom(struct sock *sk, int shift)return too_many_orphans || out_of_socket_memory; } -void tcp_close (struct sock *sk,long timeout) +void __tcp_close (struct sock *sk,long timeout) {struct sk_buff *skb;int data_was_unread =0 ;int state; -lock_sock (sk); sk->sk_shutdown =SHUTDOWN_MASK ;if (sk->sk_state ==TCP_LISTEN ) {
@@ -2588,6 +2587,12 @@ void tcp_close(struct sock *sk, long timeout) out:bh_unlock_sock (sk);local_bh_enable (); +} + +void tcp_close (struct sock *sk,long timeout) +{ +lock_sock (sk); +__tcp_close (sk, timeout);release_sock (sk);sock_put (sk); }
Signature · 1 line
2.26.2