Skip to content

Commit 60fb956

Browse files
Paolo Abenidavem330
authored andcommitted
udp: implement complete book-keeping for encap_needed
The *encap_needed static keys are enabled by UDP tunnels and several UDP encapsulations type, but they are never turned off. This can cause unneeded overall performance degradation for systems where such features are used transiently. This patch introduces complete book-keeping for such keys, decreasing the usage at socket destruction time, if needed, and avoiding that the same socket could increase the key usage multiple times. rfc v3 -> v1: - add socket lock around udp_tunnel_encap_enable() rfc v2 -> rfc v3: - use udp_tunnel_encap_enable() in setsockopt() Signed-off-by: Paolo Abeni <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7e22561 commit 60fb956

File tree

4 files changed

+34
-12
lines changed

4 files changed

+34
-12
lines changed

include/linux/udp.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,12 @@ struct udp_sock {
4949
unsigned int corkflag; /* Cork is required */
5050
__u8 encap_type; /* Is this an Encapsulation socket? */
5151
unsigned char no_check6_tx:1,/* Send zero UDP6 checksums on TX? */
52-
no_check6_rx:1;/* Allow zero UDP6 checksums on RX? */
52+
no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */
53+
encap_enabled:1; /* This socket enabled encap
54+
* processing; UDP tunnels and
55+
* different encapsulation layer set
56+
* this
57+
*/
5358
/*
5459
* Following member retains the information to create a UDP header
5560
* when the socket is uncorked.

include/net/udp_tunnel.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,12 @@ static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum)
165165

166166
static inline void udp_tunnel_encap_enable(struct socket *sock)
167167
{
168+
struct udp_sock *up = udp_sk(sock->sk);
169+
170+
if (up->encap_enabled)
171+
return;
172+
173+
up->encap_enabled = 1;
168174
#if IS_ENABLED(CONFIG_IPV6)
169175
if (sock->sk->sk_family == PF_INET6)
170176
ipv6_stub->udpv6_encap_enable();

net/ipv4/udp.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
#include "udp_impl.h"
116116
#include <net/sock_reuseport.h>
117117
#include <net/addrconf.h>
118+
#include <net/udp_tunnel.h>
118119

119120
struct udp_table udp_table __read_mostly;
120121
EXPORT_SYMBOL(udp_table);
@@ -2395,11 +2396,15 @@ void udp_destroy_sock(struct sock *sk)
23952396
bool slow = lock_sock_fast(sk);
23962397
udp_flush_pending_frames(sk);
23972398
unlock_sock_fast(sk, slow);
2398-
if (static_branch_unlikely(&udp_encap_needed_key) && up->encap_type) {
2399-
void (*encap_destroy)(struct sock *sk);
2400-
encap_destroy = READ_ONCE(up->encap_destroy);
2401-
if (encap_destroy)
2402-
encap_destroy(sk);
2399+
if (static_branch_unlikely(&udp_encap_needed_key)) {
2400+
if (up->encap_type) {
2401+
void (*encap_destroy)(struct sock *sk);
2402+
encap_destroy = READ_ONCE(up->encap_destroy);
2403+
if (encap_destroy)
2404+
encap_destroy(sk);
2405+
}
2406+
if (up->encap_enabled)
2407+
static_branch_disable(&udp_encap_needed_key);
24032408
}
24042409
}
24052410

@@ -2444,7 +2449,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
24442449
/* FALLTHROUGH */
24452450
case UDP_ENCAP_L2TPINUDP:
24462451
up->encap_type = val;
2447-
udp_encap_enable();
2452+
lock_sock(sk);
2453+
udp_tunnel_encap_enable(sk->sk_socket);
2454+
release_sock(sk);
24482455
break;
24492456
default:
24502457
err = -ENOPROTOOPT;

net/ipv6/udp.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,11 +1456,15 @@ void udpv6_destroy_sock(struct sock *sk)
14561456
udp_v6_flush_pending_frames(sk);
14571457
release_sock(sk);
14581458

1459-
if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) {
1460-
void (*encap_destroy)(struct sock *sk);
1461-
encap_destroy = READ_ONCE(up->encap_destroy);
1462-
if (encap_destroy)
1463-
encap_destroy(sk);
1459+
if (static_branch_unlikely(&udpv6_encap_needed_key)) {
1460+
if (up->encap_type) {
1461+
void (*encap_destroy)(struct sock *sk);
1462+
encap_destroy = READ_ONCE(up->encap_destroy);
1463+
if (encap_destroy)
1464+
encap_destroy(sk);
1465+
}
1466+
if (up->encap_enabled)
1467+
static_branch_disable(&udpv6_encap_needed_key);
14641468
}
14651469

14661470
inet6_destroy_sock(sk);

0 commit comments

Comments
 (0)