From nobody Sat Apr 27 15:20:15 2024 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B8F0D28EF for ; Wed, 19 Oct 2022 10:02:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1666173755; 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=owPDeMElgBtwxyZbMxAAYSiYM74n7F8RQNiynGcF0kw=; b=FrA1Kl4XT2+cHRjraan85ZuZwXRTyk1hp9R2ilHPxLuB/394Inv6SHhpKNnaBqG63dTfQf hGU9KWcv0lNbtzR3+KMCJ4W+ExkMzcKLqGKiszPNSrg5EeLjzXGFWM4b95ebnDcbhqz124 kMY6Kx+w+eaYlqIAxHbxYnABLJCVMfo= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-367-RdbcssAaMMGCZ6SfOW6UXQ-1; Wed, 19 Oct 2022 06:02:32 -0400 X-MC-Unique: RdbcssAaMMGCZ6SfOW6UXQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C835080280D; Wed, 19 Oct 2022 10:02:31 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.39.194.193]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4F52F2024CBF; Wed, 19 Oct 2022 10:02:30 +0000 (UTC) From: Paolo Abeni To: netdev@vger.kernel.org Cc: "David S. Miller" , Eric Dumazet , Jakub Kicinski , mptcp@lists.linux.dev, David Ahern , Mat Martineau , Matthieu Baerts Subject: [PATCH net-next 1/2] net: introduce and use custom sockopt socket flag Date: Wed, 19 Oct 2022 12:02:00 +0200 Message-Id: In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 Content-Type: text/plain; charset="utf-8" We will soon introduce custom setsockopt for UDP sockets, too. Instead of doing even more complex arbitrary checks inside sock_use_custom_sol_socket(), add a new socket flag and set it for the relevant socket types (currently only MPTCP). Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts --- include/linux/net.h | 1 + net/mptcp/protocol.c | 4 ++++ net/socket.c | 8 +------- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/linux/net.h b/include/linux/net.h index 711c3593c3b8..59350fd85823 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -41,6 +41,7 @@ struct net; #define SOCK_NOSPACE 2 #define SOCK_PASSCRED 3 #define SOCK_PASSSEC 4 +#define SOCK_CUSTOM_SOCKOPT 5 =20 #ifndef ARCH_HAS_SOCKET_TYPES /** diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index f599ad44ed24..0448a5c3da3c 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2708,6 +2708,8 @@ static int mptcp_init_sock(struct sock *sk) if (ret) return ret; =20 + set_bit(SOCK_CUSTOM_SOCKOPT, &sk->sk_socket->flags); + /* fetch the ca name; do it outside __mptcp_init_sock(), so that clone wi= ll * propagate the correct value */ @@ -3684,6 +3686,8 @@ static int mptcp_stream_accept(struct socket *sock, s= truct socket *newsock, struct mptcp_subflow_context *subflow; struct sock *newsk =3D newsock->sk; =20 + set_bit(SOCK_CUSTOM_SOCKOPT, &newsock->flags); + lock_sock(newsk); =20 /* PM/worker can now acquire the first subflow socket diff --git a/net/socket.c b/net/socket.c index 00da9ce3dba0..55c5d536e5f6 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2199,13 +2199,7 @@ SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, = size_t, size, =20 static bool sock_use_custom_sol_socket(const struct socket *sock) { - const struct sock *sk =3D sock->sk; - - /* Use sock->ops->setsockopt() for MPTCP */ - return IS_ENABLED(CONFIG_MPTCP) && - sk->sk_protocol =3D=3D IPPROTO_MPTCP && - sk->sk_type =3D=3D SOCK_STREAM && - (sk->sk_family =3D=3D AF_INET || sk->sk_family =3D=3D AF_INET6); + return test_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags); } =20 /* --=20 2.37.3 From nobody Sat Apr 27 15:20:15 2024 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4649928ED for ; Wed, 19 Oct 2022 10:02:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1666173758; 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=xODfCnegHAcY9oJAuVS/RwknTQC22dpmxvZ72mfflMc=; b=WEAnQCccefSYuaI8AmHbZ650QRiJFNZWboloG0M9yFnSuY9xcO9IPZrys0b+PQIV6geF6C ZUUxt6MyxQyZ4DdnAu6lXj/6cR31GaAMSK92M/V+4U3UGgUKJitiYSWlctFhJIfbCk4Gxm +9XFIIVkfeTH9DEP02ltTaFedmkNKlg= 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-28-nyfhg_36NkqpmdwZJ86PmQ-1; Wed, 19 Oct 2022 06:02:34 -0400 X-MC-Unique: nyfhg_36NkqpmdwZJ86PmQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A34B21C0A58F; Wed, 19 Oct 2022 10:02:33 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.39.194.193]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1B0712028DC1; Wed, 19 Oct 2022 10:02:31 +0000 (UTC) From: Paolo Abeni To: netdev@vger.kernel.org Cc: "David S. Miller" , Eric Dumazet , Jakub Kicinski , mptcp@lists.linux.dev, David Ahern , Mat Martineau , Matthieu Baerts Subject: [PATCH net-next 2/2] udp: track the forward memory release threshold in an hot cacheline Date: Wed, 19 Oct 2022 12:02:01 +0200 Message-Id: In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 Content-Type: text/plain; charset="utf-8" When the receiver process and the BH runs on different cores, udp_rmem_release() experience a cache miss while accessing sk_rcvbuf, as the latter shares the same cacheline with sk_forward_alloc, written by the BH. With this patch, UDP tracks the rcvbuf value and its update via custom SOL_SOCKET socket options, and copies the forward memory threshold value used by udp_rmem_release() in a different cacheline, already accessed by the above function and uncontended. Overall the above give a 10% peek throughput increase under UDP flood. Signed-off-by: Paolo Abeni --- include/linux/udp.h | 3 +++ net/ipv4/udp.c | 22 +++++++++++++++++++--- net/ipv6/udp.c | 8 ++++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/include/linux/udp.h b/include/linux/udp.h index e96da4157d04..5cdba00a904a 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h @@ -87,6 +87,9 @@ struct udp_sock { =20 /* This field is dirtied by udp_recvmsg() */ int forward_deficit; + + /* This fields follows rcvbuf value, and is touched by udp_recvmsg */ + int forward_threshold; }; =20 #define UDP_MAX_SEGMENTS (1 << 6UL) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 8126f67d18b3..915f573587fa 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1448,7 +1448,7 @@ static void udp_rmem_release(struct sock *sk, int siz= e, int partial, if (likely(partial)) { up->forward_deficit +=3D size; size =3D up->forward_deficit; - if (size < (sk->sk_rcvbuf >> 2) && + if (size < READ_ONCE(up->forward_threshold) && !skb_queue_empty(&up->reader_queue)) return; } else { @@ -1622,8 +1622,12 @@ static void udp_destruct_sock(struct sock *sk) =20 int udp_init_sock(struct sock *sk) { - skb_queue_head_init(&udp_sk(sk)->reader_queue); + struct udp_sock *up =3D udp_sk(sk); + + skb_queue_head_init(&up->reader_queue); + up->forward_threshold =3D sk->sk_rcvbuf >> 2; sk->sk_destruct =3D udp_destruct_sock; + set_bit(SOCK_CUSTOM_SOCKOPT, &sk->sk_socket->flags); return 0; } =20 @@ -2671,6 +2675,18 @@ int udp_lib_setsockopt(struct sock *sk, int level, i= nt optname, int err =3D 0; int is_udplite =3D IS_UDPLITE(sk); =20 + if (level =3D=3D SOL_SOCKET) { + err =3D sk_setsockopt(sk, level, optname, optval, optlen); + + if (optname =3D=3D SO_RCVBUF || optname =3D=3D SO_RCVBUFFORCE) { + sockopt_lock_sock(sk); + /* paired with READ_ONCE in udp_rmem_release() */ + WRITE_ONCE(up->forward_threshold, sk->sk_rcvbuf >> 2); + sockopt_release_sock(sk); + } + return err; + } + if (optlen < sizeof(int)) return -EINVAL; =20 @@ -2784,7 +2800,7 @@ EXPORT_SYMBOL(udp_lib_setsockopt); int udp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optv= al, unsigned int optlen) { - if (level =3D=3D SOL_UDP || level =3D=3D SOL_UDPLITE) + if (level =3D=3D SOL_UDP || level =3D=3D SOL_UDPLITE || level =3D=3D SO= L_SOCKET) return udp_lib_setsockopt(sk, level, optname, optval, optlen, udp_push_pending_frames); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 8d09f0ea5b8c..1ed20bcfd7a0 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -64,8 +64,12 @@ static void udpv6_destruct_sock(struct sock *sk) =20 int udpv6_init_sock(struct sock *sk) { - skb_queue_head_init(&udp_sk(sk)->reader_queue); + struct udp_sock *up =3D udp_sk(sk); + + skb_queue_head_init(&up->reader_queue); + up->forward_threshold =3D sk->sk_rcvbuf >> 2; sk->sk_destruct =3D udpv6_destruct_sock; + set_bit(SOCK_CUSTOM_SOCKOPT, &sk->sk_socket->flags); return 0; } =20 @@ -1671,7 +1675,7 @@ void udpv6_destroy_sock(struct sock *sk) int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t op= tval, unsigned int optlen) { - if (level =3D=3D SOL_UDP || level =3D=3D SOL_UDPLITE) + if (level =3D=3D SOL_UDP || level =3D=3D SOL_UDPLITE || level =3D=3D SO= L_SOCKET) return udp_lib_setsockopt(sk, level, optname, optval, optlen, udp_v6_push_pending_frames); --=20 2.37.3