aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2020-11-16 10:48:03 +0100
committerJakub Kicinski <kuba@kernel.org>2020-11-16 10:46:06 -0800
commite2223995a2872c0e23ed44e1dbb493817b567666 (patch)
tree9765e93da93161677e90f10c7c72027b397fa362
parenttcp: factor out tcp_build_frag() (diff)
downloadlinux-dev-e2223995a2872c0e23ed44e1dbb493817b567666.tar.xz
linux-dev-e2223995a2872c0e23ed44e1dbb493817b567666.zip
mptcp: use tcp_build_frag()
mptcp_push_pending() is called even on orphaned msk (and orphaned subflows), if there is outstanding data at close() time. To cope with the above MPTCP needs to handle explicitly the allocation failure on xmit. The newly introduced do_tcp_sendfrag() allows that, just plug it. We can additionally drop a couple of sanity checks, duplicate in the TCP code. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--net/mptcp/protocol.c25
1 files changed, 8 insertions, 17 deletions
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index eaa61e227492..3c68cf912fb8 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -992,17 +992,13 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
psize = min_t(size_t, dfrag->data_len, avail_size);
}
- /* tell the TCP stack to delay the push so that we can safely
- * access the skb after the sendpages call
- */
- ret = do_tcp_sendpages(ssk, page, offset, psize,
- msg->msg_flags | MSG_SENDPAGE_NOTLAST | MSG_DONTWAIT);
- if (ret <= 0) {
- if (!retransmission)
- iov_iter_revert(&msg->msg_iter, psize);
- return ret;
+ tail = tcp_build_frag(ssk, psize, msg->msg_flags, page, offset, &psize);
+ if (!tail) {
+ tcp_remove_empty_skb(sk, tcp_write_queue_tail(ssk));
+ return -ENOMEM;
}
+ ret = psize;
frag_truesize += ret;
if (!retransmission) {
if (unlikely(ret < psize))
@@ -1026,20 +1022,15 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
sk->sk_forward_alloc -= frag_truesize;
}
- /* if the tail skb extension is still the cached one, collapsing
- * really happened. Note: we can't check for 'same skb' as the sk_buff
- * hdr on tail can be transmitted, freed and re-allocated by the
- * do_tcp_sendpages() call
+ /* if the tail skb is still the cached one, collapsing really happened.
*/
- tail = tcp_write_queue_tail(ssk);
- if (mpext && tail && mpext == skb_ext_find(tail, SKB_EXT_MPTCP)) {
+ if (skb == tail) {
WARN_ON_ONCE(!can_collapse);
mpext->data_len += ret;
goto out;
}
- skb = tcp_write_queue_tail(ssk);
- mpext = __skb_ext_set(skb, SKB_EXT_MPTCP, msk->cached_ext);
+ mpext = __skb_ext_set(tail, SKB_EXT_MPTCP, msk->cached_ext);
msk->cached_ext = NULL;
memset(mpext, 0, sizeof(*mpext));