From patchwork Thu Mar 16 15:26:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13177812 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 058E9C6FD1F for ; Thu, 16 Mar 2023 15:27:04 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 76ADB94000F; Thu, 16 Mar 2023 11:27:01 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 71B8B94000D; Thu, 16 Mar 2023 11:27:01 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 5BBCA94000F; Thu, 16 Mar 2023 11:27:01 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 49B6A94000D for ; Thu, 16 Mar 2023 11:27:01 -0400 (EDT) Received: from smtpin24.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 0998580A6D for ; Thu, 16 Mar 2023 15:27:01 +0000 (UTC) X-FDA: 80575139442.24.E2BEE6A Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by imf02.hostedemail.com (Postfix) with ESMTP id 568C98001C for ; Thu, 16 Mar 2023 15:26:59 +0000 (UTC) Authentication-Results: imf02.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=VMk6gPea; spf=pass (imf02.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1678980419; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=0tjSspNdCEV0klTPAiqijmVmAHGr/T2RpULqY6WmgRo=; b=4ehj8d+y155O3jtdGRrIGBk9PbpyJ5pYOvsxXxEQX7lkZ4C1EitFgsBozWmAd3tY1MvrIY oLYt97Bo+gjOY/WNgdzMemZAW0eCVKdGJTvrxa0QHaxFEGiX2L4pORL+dKJ79YPrDw9mB2 X3tv3L5CffUk57At/jFJ1R+76kIUZcw= ARC-Authentication-Results: i=1; imf02.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=VMk6gPea; spf=pass (imf02.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1678980419; a=rsa-sha256; cv=none; b=284F9bqA2dUkhU1zzH0v8jV/rnpEKQ5hOOgAFFlvM/rSJFk8Z/P3J8UAA/xbyceo9nyInM qndk6KBzq6OTV8nAhxZ+o5RYpbFVTmKnfFXN/3Ak7xlUCzJayoZqa+LjUiJ+Gnin4Qamh/ 69nEDbmu9/OfbR2oPToBTID2z1pMZgo= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1678980418; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0tjSspNdCEV0klTPAiqijmVmAHGr/T2RpULqY6WmgRo=; b=VMk6gPea/tO8X2//9s1aGA5A67Nq/0LNAJBchTL8RsM+Kx1kQTWr+viQUAP1vM0Dlm6Qss YWjwp0TQu+4L7HIxhmGsw0K0W69Av69XMBO8MQmQrpNHKBlxdw2bIe783T/4pMw1zEJ2lC LvkULVtIEgyOZHU94l9IAi1BLcQiWjo= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-84-pxJorDNpMoumBCRZt3rTBA-1; Thu, 16 Mar 2023 11:26:55 -0400 X-MC-Unique: pxJorDNpMoumBCRZt3rTBA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C928228237DA; Thu, 16 Mar 2023 15:26:54 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.18]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0A22240C6F87; Thu, 16 Mar 2023 15:26:52 +0000 (UTC) From: David Howells To: Matthew Wilcox , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: David Howells , Al Viro , Christoph Hellwig , Jens Axboe , Jeff Layton , Christian Brauner , Linus Torvalds , netdev@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [RFC PATCH 12/28] af_unix: Support MSG_SPLICE_PAGES Date: Thu, 16 Mar 2023 15:26:02 +0000 Message-Id: <20230316152618.711970-13-dhowells@redhat.com> In-Reply-To: <20230316152618.711970-1-dhowells@redhat.com> References: <20230316152618.711970-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 568C98001C X-Stat-Signature: fb4t94xng54gzd94qf513bunjx1dad3r X-HE-Tag: 1678980419-218649 X-HE-Meta: U2FsdGVkX1+HDUF8S1caYOMtdkA+sPE1a8WlnpWgExfNto7t+GM5ArIeGxU1ITldU1U9UNtRSoUgTnPlMMyXVs2GeQw1alXnsF8cHLWNC0eIs9RtqhXFpAqgGiGvUJTCpAYfZ6X8PCj5N2HwQrNx4kH8c6BP6TxpWdZtp7OkmPG9gz8Oj6/sckC+5uRY2MZgLtYvOZa0vyd352YeFO0ON78KDdae1XqKSxs6KT1B4jrFD6DZycaPhU9S30qMDvZclXGnoQebdebe6g/4VtK0gAMki3i326pLBXFcm8m71whdLxIqtnM3TfC2dU5gNuSB+g29wTAgmEZBMPvv92UzdqMwKiKXWIxZD0hnP4um6F5CeY9Wy8j8brGU3tSOf2wxx3eFV3tjsCRVZ23ImRIgluuwgR8bO2aHGwtcCLoBFx7gSXfjqc8ePZcGytjlP/gW1rFlYmRmyg7RCdv8dtOVwWpxwHyZBlNHysMhKO14jZtRtErOa0zrp9n6zacGN2KZ9Obdu0dZ+z8c6S5hYdvci67I6sj0M2LUC74kLJFWkU767SVED/+LvCdhNi08s+NXOOJFEIzMdnej5qViDknC9Er3HmMOy5KV6dEttYI7mL0/GLG83b4oEXUMI0A17gpvNXgJ/rb63YiXxq7uEdO+mOjpx0yCFNH4Z8cUbA7+lSH6KaE3uWdcdq9tTxv5u2X8wrTkbca38zy0PA4FtZAZp7kg2x/vO5zijJJJsCq0U0BwLI/iXfrxEPbuIKNSj1beFJjyY994PTdG8JxfFK9hs3qZTo/HkQUGOjpSkGDDVFAK6kDyvC91N12yVnlQ85ZeJJ8ZB3PuEkkGpJ4qCbmm/Fd++DG5K24BOtGEfZdpfkPLKa/tIBYv7pKBoHcDp4nJZGIy58ncWI+pT2XMG6XDINDYrseOw2+kuAFw1hqS6atbMzy9d8p1lYBWuKDCmw3/v4IxNDGn5Z7fUSF9PQF OIJ45G9h GvYCbnwEoLg//pM4EU8MxU0Jp14ybL6RSD1dZ8K70rHj7fEYnbzNFQQTeQqMG103PVaCQCfJblQw/B7AbIUJJ2idC/m70XntxkD91BW7Ap9MvqKB303PluiP6ZZ+QewDvIb0raGRc+oQJwnQptkHlY9mDmOAp8j/8KqD1rlF5BJXlL10A77ecd6ro0ZXdjixStDV3e2dhp5ee3z2oiDvqBs81t73QvIkNK5+B7Krc4gISqHeme39QQBS95ctWlR0hM/pmVJ2dO1xFdprXTAST43sPasVX9LxTSrd7bnuJiF6PF/WcoSV/BaCibh55ZxBmf5qwH1G+1k9Ysgh+imm81U+g6hl7AmaHCYysrJjX1EoDTdfkHUM4/eTSLjy5sk0upU8vJhAyoFJwTC68QFlhfTq/oRsoiRW/vFbX2Rloh0Z3RHKE67wxJ4JJLt/4La45/N0B X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Make AF_UNIX sendmsg() support MSG_SPLICE_PAGES, splicing in pages from the source iterator if given and if ITER_BVEC and copying the data in otherwise. This allows ->sendpage() to be replaced by something that can handle multiple multipage folios in a single transaction. Signed-off-by: David Howells cc: "David S. Miller" cc: Eric Dumazet cc: Jakub Kicinski cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org --- net/unix/af_unix.c | 84 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 347122c3575e..6f3454db9c53 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2151,6 +2151,44 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other } #endif +/* + * Extract pages from a BVEC-type iterator and add them to the socket buffer. + */ +static ssize_t unix_extract_bvec_to_skb(struct sk_buff *skb, + struct iov_iter *iter, ssize_t maxsize) +{ + const struct bio_vec *bv = iter->bvec; + unsigned long start = iter->iov_offset; + unsigned int i; + ssize_t ret = 0; + + for (i = 0; i < iter->nr_segs; i++) { + size_t off, len; + + len = bv[i].bv_len; + if (start >= len) { + start -= len; + continue; + } + + len = min_t(size_t, maxsize, len - start); + off = bv[i].bv_offset + start; + + if (skb_append_pagefrags(skb, bv->bv_page, off, len) < 0) + break; + + ret += len; + maxsize -= len; + if (maxsize <= 0) + break; + start = 0; + } + + if (ret > 0) + iov_iter_advance(iter, ret); + return ret; +} + static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) { @@ -2194,19 +2232,25 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, while (sent < len) { size = len - sent; - /* Keep two messages in the pipe so it schedules better */ - size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64); + if (unlikely(msg->msg_flags & MSG_SPLICE_PAGES)) { + skb = sock_alloc_send_pskb(sk, 0, 0, + msg->msg_flags & MSG_DONTWAIT, + &err, 0); + } else { + /* Keep two messages in the pipe so it schedules better */ + size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64); - /* allow fallback to order-0 allocations */ - size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ); + /* allow fallback to order-0 allocations */ + size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ); - data_len = max_t(int, 0, size - SKB_MAX_HEAD(0)); + data_len = max_t(int, 0, size - SKB_MAX_HEAD(0)); - data_len = min_t(size_t, size, PAGE_ALIGN(data_len)); + data_len = min_t(size_t, size, PAGE_ALIGN(data_len)); - skb = sock_alloc_send_pskb(sk, size - data_len, data_len, - msg->msg_flags & MSG_DONTWAIT, &err, - get_order(UNIX_SKB_FRAGS_SZ)); + skb = sock_alloc_send_pskb(sk, size - data_len, data_len, + msg->msg_flags & MSG_DONTWAIT, &err, + get_order(UNIX_SKB_FRAGS_SZ)); + } if (!skb) goto out_err; @@ -2218,13 +2262,21 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, } fds_sent = true; - skb_put(skb, size - data_len); - skb->data_len = data_len; - skb->len = size; - err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); - if (err) { - kfree_skb(skb); - goto out_err; + if (unlikely(msg->msg_flags & MSG_SPLICE_PAGES)) { + size = unix_extract_bvec_to_skb(skb, &msg->msg_iter, size); + skb->data_len += size; + skb->len += size; + skb->truesize += size; + refcount_add(size, &sk->sk_wmem_alloc); + } else { + skb_put(skb, size - data_len); + skb->data_len = data_len; + skb->len = size; + err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); + if (err) { + kfree_skb(skb); + goto out_err; + } } unix_state_lock(other);