From patchwork Fri Jan 25 16:17:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 1031175 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="WBc2hKsb"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43mPLd4Hjxz9s4s for ; Sat, 26 Jan 2019 03:17:29 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726682AbfAYQR2 (ORCPT ); Fri, 25 Jan 2019 11:17:28 -0500 Received: from mail-qt1-f194.google.com ([209.85.160.194]:43709 "EHLO mail-qt1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726122AbfAYQR2 (ORCPT ); Fri, 25 Jan 2019 11:17:28 -0500 Received: by mail-qt1-f194.google.com with SMTP id i7so11225975qtj.10 for ; Fri, 25 Jan 2019 08:17:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=iUJFLBe0XErxnsubxoPy0XnGq5AzzA0ZnJLCHfnAmYM=; b=WBc2hKsbEHS6zSkl5OGPl8GYfWTLsh8mC2vQumhwxCdnBPUx7XmkGrAtO4R5rfk3Kp S3uQ7zwlaneWrMsiXlO8ebBJhMMnF4LuPHv0WvcJ/1y90gMkafAt012105uKwCgO3GAD cxrow+clkjFBkciE7W/eDjnjqAgF2nvHzNeWZ9BRzjIsUbGDVcn1PXR6QUkQj4RDiw5s oQ9yOwwuPviGQCRx9CqdoVVvv1Vn6F8HqUTnKJT5ldzkJd9Y+uXhIWVjLbssfExvpXCc GL4upJnoQkQbUSVBqx/DDi2H45wledc4UiRIxalPoFUjYRgWxxV40Te55m6vVtXwu+y4 LlUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=iUJFLBe0XErxnsubxoPy0XnGq5AzzA0ZnJLCHfnAmYM=; b=P8fYscH9IzKz44bzrx/HEaORWd/u6Qda2jnykbnwWx63ZWBZ2HjnkxC03hGF2Hp0MV QlvpHbfnnzYpv6gwgvJcuScfvk5dq3+KupZ+w3K3wXvu43qbCIuv34cSI1RMXYcsLi1+ YC2esjaqLiAx77LvfUcqEN7DPb6cNNybQPpy7W5ZLbF8VShZPMmqZTwixy2fwSP0kbjF DDKG73tbSqfZhvT6OOsT7HhavvatnDqsf+6TtdajXsPv1M8Bm9MSpY7A2M8Whvx4icAQ 798BRbHiw/sLUbNgZ+fxKyjxGXd6+VHFTNanFeDsqRtSEujutuwrRknA5nP7UsC+FQ8P zRqw== X-Gm-Message-State: AJcUukc8m7M0qxqBJAm8KNMyPH1fBfaa8B9pxd/U9H1u0oULS5Hr45Nr lbFor/wA/ZCnHyv58hD/v4G/t89x X-Google-Smtp-Source: ALg8bN7HbA3eMRd+eTGWmY3w7YmUdrveEMMMzZ7D8oqZ902QZiVX7VJnYzC/y3unNtl1iMkghuwV/A== X-Received: by 2002:a0c:99d9:: with SMTP id y25mr10898743qve.133.1548433046342; Fri, 25 Jan 2019 08:17:26 -0800 (PST) Received: from willemb1.nyc.corp.google.com ([2620:0:1003:315:3fa1:a34c:1128:1d39]) by smtp.gmail.com with ESMTPSA id 18sm43775914qki.35.2019.01.25.08.17.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 25 Jan 2019 08:17:25 -0800 (PST) From: Willem de Bruijn To: netdev@vger.kernel.org Cc: davem@davemloft.net, ycheng@google.com, edumazet@google.com, alexey.kodanev@oracle.com, Willem de Bruijn Subject: [PATCH net-next] tcp: allow zerocopy with fastopen Date: Fri, 25 Jan 2019 11:17:23 -0500 Message-Id: <20190125161723.75429-1-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.20.1.495.gaa96b0ce6b-goog MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Willem de Bruijn Accept MSG_ZEROCOPY in all the TCP states that allow sendmsg. Remove the explicit check for ESTABLISHED and CLOSE_WAIT states. This requires correctly handling zerocopy state (uarg, sk_zckey) in all paths reachable from other TCP states. Such as the EPIPE case in sk_stream_wait_connect, which a sendmsg() in incorrect state will now hit. Most paths are already safe. Only extension needed is for TCP Fastopen active open. This can build an skb with data in tcp_send_syn_data. Pass the uarg along with other fastopen state, so that this skb also generates a zerocopy notification on release. Tested with active and passive tcp fastopen packetdrill scripts at https://github.com/wdebruij/packetdrill/commit/1747eef03d25a2404e8132817d0f1244fd6f129d Signed-off-by: Willem de Bruijn Signed-off-by: Eric Dumazet --- include/net/tcp.h | 1 + net/ipv4/tcp.c | 11 ++++------- net/ipv4/tcp_output.c | 1 + 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 5c950180d61be..a6e0355921e1d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1608,6 +1608,7 @@ struct tcp_fastopen_request { struct msghdr *data; /* data in MSG_FASTOPEN */ size_t size; int copied; /* queued in tcp_connect() */ + struct ubuf_info *uarg; }; void tcp_free_fastopen_req(struct tcp_sock *tp); void tcp_fastopen_destroy_cipher(struct sock *sk); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 5f099c9d04e5d..12ba21433dd00 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1127,7 +1127,8 @@ void tcp_free_fastopen_req(struct tcp_sock *tp) } static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, - int *copied, size_t size) + int *copied, size_t size, + struct ubuf_info *uarg) { struct tcp_sock *tp = tcp_sk(sk); struct inet_sock *inet = inet_sk(sk); @@ -1147,6 +1148,7 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, return -ENOBUFS; tp->fastopen_req->data = msg; tp->fastopen_req->size = size; + tp->fastopen_req->uarg = uarg; if (inet->defer_connect) { err = tcp_connect(sk); @@ -1186,11 +1188,6 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) flags = msg->msg_flags; if (flags & MSG_ZEROCOPY && size && sock_flag(sk, SOCK_ZEROCOPY)) { - if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) { - err = -EINVAL; - goto out_err; - } - skb = tcp_write_queue_tail(sk); uarg = sock_zerocopy_realloc(sk, size, skb_zcopy(skb)); if (!uarg) { @@ -1205,7 +1202,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) if (unlikely(flags & MSG_FASTOPEN || inet_sk(sk)->defer_connect) && !tp->repair) { - err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size); + err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size, uarg); if (err == -EINPROGRESS && copied_syn > 0) goto out; else if (err) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 6527f61f59ff1..26a2948dca954 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3455,6 +3455,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) skb_trim(syn_data, copied); space = copied; } + skb_zcopy_set(syn_data, fo->uarg, NULL); } /* No more data pending in inet_wait_for_connect() */ if (space == fo->size)