Skip to content

Commit f796fea

Browse files
Paolo Abenikuba-moo
authored andcommitted
udp: add local "peek offset enabled" flag
We want to re-organize the struct sock layout. The sk_peek_off field location is problematic, as most protocols want it in the RX read area, while UDP wants it on a cacheline different from sk_receive_queue. Create a local (inside udp_sock) copy of the 'peek offset is enabled' flag and place it inside the same cacheline of reader_queue. Check such flag before reading sk_peek_off. This will save potential false sharing and cache misses in the fast-path. Tested under UDP flood with small packets. The struct sock layout update causes a 4% performance drop, and this patch restores completely the original tput. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://lore.kernel.org/r/67ab679c15fbf49fa05b3ffe05d91c47ab84f147.1708426665.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 26b2a26 commit f796fea

File tree

4 files changed

+13
-3
lines changed

4 files changed

+13
-3
lines changed

include/linux/udp.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ struct udp_sock {
9292

9393
/* This fields follows rcvbuf value, and is touched by udp_recvmsg */
9494
int forward_threshold;
95+
96+
/* Cache friendly copy of sk->sk_peek_off >= 0 */
97+
bool peeking_with_offset;
9598
};
9699

97100
#define udp_test_bit(nr, sk) \
@@ -109,6 +112,13 @@ struct udp_sock {
109112

110113
#define udp_sk(ptr) container_of_const(ptr, struct udp_sock, inet.sk)
111114

115+
static inline int udp_set_peek_off(struct sock *sk, int val)
116+
{
117+
sk_set_peek_off(sk, val);
118+
WRITE_ONCE(udp_sk(sk)->peeking_with_offset, val >= 0);
119+
return 0;
120+
}
121+
112122
static inline void udp_set_no_check6_tx(struct sock *sk, bool val)
113123
{
114124
udp_assign_bit(NO_CHECK6_TX, sk, val);

net/ipv4/af_inet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ const struct proto_ops inet_dgram_ops = {
11031103
.recvmsg = inet_recvmsg,
11041104
.mmap = sock_no_mmap,
11051105
.splice_eof = inet_splice_eof,
1106-
.set_peek_off = sk_set_peek_off,
1106+
.set_peek_off = udp_set_peek_off,
11071107
#ifdef CONFIG_COMPAT
11081108
.compat_ioctl = inet_compat_ioctl,
11091109
#endif

net/ipv4/udp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1589,7 +1589,7 @@ int udp_init_sock(struct sock *sk)
15891589

15901590
void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
15911591
{
1592-
if (unlikely(READ_ONCE(sk->sk_peek_off) >= 0)) {
1592+
if (unlikely(READ_ONCE(udp_sk(sk)->peeking_with_offset))) {
15931593
bool slow = lock_sock_fast(sk);
15941594

15951595
sk_peek_offset_bwd(sk, len);

net/ipv6/af_inet6.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ const struct proto_ops inet6_dgram_ops = {
736736
.recvmsg = inet6_recvmsg, /* retpoline's sake */
737737
.read_skb = udp_read_skb,
738738
.mmap = sock_no_mmap,
739-
.set_peek_off = sk_set_peek_off,
739+
.set_peek_off = udp_set_peek_off,
740740
#ifdef CONFIG_COMPAT
741741
.compat_ioctl = inet6_compat_ioctl,
742742
#endif

0 commit comments

Comments
 (0)