summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-05-05 17:47:09 -0700
committerJakub Kicinski <kuba@kernel.org>2026-05-05 17:47:09 -0700
commited36fad2cdcd620130b159be383d74a59097ea50 (patch)
tree37f893d0c7c177e90760cc0a0f51cfb9804bd58a /include
parent8c699be3dad7bba87cdda485dc099226cfc2f706 (diff)
parent72d3b9a4c2b137b32fdf5342699d16229e2ac75e (diff)
Merge branch 'udp_tunnel-speed-up-udp-tunnel-device-destruction-part-i'
Kuniyuki Iwashima says: ==================== udp_tunnel: Speed up UDP tunnel device destruction (Part I) Most of the UDP tunnel devices call synchronize_rcu() twice during destruction, for example, vxlan has 1) synchronize_rcu() in udp_tunnel_sock_release() 2) synchronize_net() in vxlan_sock_release() The goal of this series is to remove the former, and another followup series removes the latter. synchronize_rcu() was added in udp_tunnel_sock_release() by commit 3cf7203ca620 ("net/tunnel: wait until all sk_user_data reader finish before releasing the sock"). This was intended to protect the fast path of a dying vxlan from dereferencing vxlan_sock->sock->sk after sock_orphan() has set sock->sk to NULL. Most of the UDP tunnel devices store struct socket to its private struct, but it is NOT needed in the fast paths; struct sock is used there, but struct socket is only used for tunnel setup / teardown. This is probably because UDP tunnel functions accept struct socket, but even such functions do not need it, except for udp_tunnel_sock_release(), which can safely access sk->sk_socket. The overview of the series: Patch 1 - 5 : Convert UDP tunnel helper to take struct sock Patch 6 : Small fix for 10-years-old bug Patch 7 - 14 : Store struct sock in tunnel devices Patch 15 : Remove synchronize_rcu() in udp_tunnel_sock_release() With this change, a script creating/upping vxlan in 4000 netns runs 10x faster. ==================== [See Link for benchmark results.] Link: https://patch.msgid.link/20260502031401.3557229-1-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
-rw-r--r--include/net/amt.h2
-rw-r--r--include/net/udp_tunnel.h14
-rw-r--r--include/net/vxlan.h5
3 files changed, 11 insertions, 10 deletions
diff --git a/include/net/amt.h b/include/net/amt.h
index c881bc8b673b..a0255491f5b0 100644
--- a/include/net/amt.h
+++ b/include/net/amt.h
@@ -331,7 +331,7 @@ struct amt_dev {
enum amt_status status;
/* Generated key */
siphash_key_t key;
- struct socket __rcu *sock;
+ struct sock __rcu *sk;
u32 max_groups;
u32 max_sources;
u32 hash_buckets;
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index 47c23d4a1740..498b7b262fa9 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -94,7 +94,7 @@ struct udp_tunnel_sock_cfg {
};
/* Setup the given (UDP) sock to receive UDP encapsulated packets */
-void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
+void setup_udp_tunnel_sock(struct net *net, struct sock *sk,
struct udp_tunnel_sock_cfg *sock_cfg);
/* -- List of parsable UDP tunnel types --
@@ -127,12 +127,12 @@ struct udp_tunnel_info {
};
/* Notify network devices of offloadable types */
-void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock,
+void udp_tunnel_push_rx_port(struct net_device *dev, struct sock *sk,
unsigned short type);
-void udp_tunnel_drop_rx_port(struct net_device *dev, struct socket *sock,
+void udp_tunnel_drop_rx_port(struct net_device *dev, struct sock *sk,
unsigned short type);
-void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type);
-void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type);
+void udp_tunnel_notify_add_rx_port(struct sock *sk, unsigned short type);
+void udp_tunnel_notify_del_rx_port(struct sock *sk, unsigned short type);
/* Transmit the skb using UDP encapsulation. */
void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
@@ -176,7 +176,7 @@ static inline void udp_tunnel_set_inner_protocol(struct sk_buff *skb,
skb_set_inner_protocol(skb, inner_proto);
}
-void udp_tunnel_sock_release(struct socket *sock);
+void udp_tunnel_sock_release(struct sock *sk);
struct rtable *udp_tunnel_dst_lookup(struct sk_buff *skb,
struct net_device *dev,
@@ -188,7 +188,7 @@ struct rtable *udp_tunnel_dst_lookup(struct sk_buff *skb,
struct dst_entry *udp_tunnel6_dst_lookup(struct sk_buff *skb,
struct net_device *dev,
struct net *net,
- struct socket *sock, int oif,
+ struct sock *sk, int oif,
struct in6_addr *saddr,
const struct ip_tunnel_key *key,
__be16 sport, __be16 dport, u8 dsfield,
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 0ee50785f4f1..dfba89695efc 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -185,7 +185,8 @@ struct vxlan_metadata {
/* per UDP socket information */
struct vxlan_sock {
struct hlist_node hlist;
- struct socket *sock;
+ struct sock *sk;
+ struct rcu_head rcu;
struct hlist_head vni_list[VNI_HASH_SIZE];
refcount_t refcnt;
u32 flags;
@@ -448,7 +449,7 @@ static inline __be32 vxlan_compute_rco(unsigned int start, unsigned int offset)
static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs)
{
- return vs->sock->sk->sk_family;
+ return vs->sk->sk_family;
}
#if IS_ENABLED(CONFIG_IPV6)