From: Kuniyuki Iwashima <kuniyu@google.com>
To: "David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>,
Andrew Lunn <andrew+netdev@lunn.ch>
Cc: Simon Horman <horms@kernel.org>,
Kuniyuki Iwashima <kuniyu@google.com>,
Kuniyuki Iwashima <kuni1840@gmail.com>,
netdev@vger.kernel.org
Subject: [PATCH v1 net-next 07/15] vxlan: Store struct sock in struct vxlan_sock.
Date: Sat, 2 May 2026 03:13:00 +0000 [thread overview]
Message-ID: <20260502031401.3557229-8-kuniyu@google.com> (raw)
In-Reply-To: <20260502031401.3557229-1-kuniyu@google.com>
Commit 3cf7203ca620 ("net/tunnel: wait until all sk_user_data
reader finish before releasing the sock") added synchronize_rcu()
in udp_tunnel_sock_release().
This was intended to protect the fast path of a dying vxlan device
from dereferencing vxlan_sock->sock->sk after sock_orphan() has set
sock->sk to NULL.
However, vxlan does not need to access struct socket itself in the
fast path; it only reads struct sock, and struct socket is only
used for tunnel setup and teardown.
Let's store struct sock directly in struct vxlan_sock.
In the next patch, we will free vxlan_sock with kfree_rcu(), then
vxlan no longer needs synchronize_rcu() in udp_tunnel_sock_release().
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
drivers/net/vxlan/vxlan_core.c | 48 ++++++++++++++---------------
drivers/net/vxlan/vxlan_multicast.c | 8 ++---
include/net/vxlan.h | 4 +--
3 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index abf3ae04d75b..ce99da44ea7d 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -88,10 +88,10 @@ static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
flags &= VXLAN_F_RCV_FLAGS;
hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
- if (inet_sk(vs->sock->sk)->inet_sport == port &&
+ if (inet_sk(vs->sk)->inet_sport == port &&
vxlan_get_sk_family(vs) == family &&
vs->flags == flags &&
- vs->sock->sk->sk_bound_dev_if == ifindex)
+ vs->sk->sk_bound_dev_if == ifindex)
return vs;
}
return NULL;
@@ -1497,7 +1497,7 @@ static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
return false;
hlist_del_rcu(&vs->hlist);
- udp_tunnel_notify_del_rx_port(vs->sock->sk,
+ udp_tunnel_notify_del_rx_port(vs->sk,
(vs->flags & VXLAN_F_GPE) ?
UDP_TUNNEL_TYPE_VXLAN_GPE :
UDP_TUNNEL_TYPE_VXLAN);
@@ -1523,13 +1523,13 @@ static void vxlan_sock_release(struct vxlan_dev *vxlan)
vxlan_vs_del_dev(vxlan);
if (__vxlan_sock_release_prep(sock4)) {
- udp_tunnel_sock_release(sock4->sock->sk);
+ udp_tunnel_sock_release(sock4->sk);
kfree(sock4);
}
#if IS_ENABLED(CONFIG_IPV6)
if (__vxlan_sock_release_prep(sock6)) {
- udp_tunnel_sock_release(sock6->sock->sk);
+ udp_tunnel_sock_release(sock6->sk);
kfree(sock6);
}
#endif
@@ -2477,7 +2477,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
}
if (!ifindex)
- ifindex = sock4->sock->sk->sk_bound_dev_if;
+ ifindex = sock4->sk->sk_bound_dev_if;
rt = udp_tunnel_dst_lookup(skb, dev, vxlan->net, ifindex,
&saddr, pkey, src_port, dst_port,
@@ -2544,7 +2544,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
goto tx_error;
}
- udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, saddr,
+ udp_tunnel_xmit_skb(rt, sock4->sk, skb, saddr,
pkey->u.ipv4.dst, tos, ttl, df,
src_port, dst_port, xnet, !udp_sum,
ipcb_flags);
@@ -2561,9 +2561,9 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
}
if (!ifindex)
- ifindex = sock6->sock->sk->sk_bound_dev_if;
+ ifindex = sock6->sk->sk_bound_dev_if;
- ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sock->sk,
+ ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sk,
ifindex, &saddr, pkey,
src_port, dst_port, tos,
use_cache ? dst_cache : NULL);
@@ -2619,7 +2619,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
goto tx_error;
}
- udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev,
+ udp_tunnel6_xmit_skb(ndst, sock6->sk, skb, dev,
&saddr, &pkey->u.ipv6.dst, tos, ttl,
pkey->label, src_port, dst_port, !udp_sum,
ip6cb_flags);
@@ -3258,7 +3258,7 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
if (!sock6)
return -EIO;
- ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sock->sk,
+ ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sk,
0, &info->key.u.ipv6.src,
&info->key,
sport, dport, info->key.tos,
@@ -3336,9 +3336,9 @@ static void vxlan_offload_rx_ports(struct net_device *dev, bool push)
type = UDP_TUNNEL_TYPE_VXLAN;
if (push)
- udp_tunnel_push_rx_port(dev, vs->sock->sk, type);
+ udp_tunnel_push_rx_port(dev, vs->sk, type);
else
- udp_tunnel_drop_rx_port(dev, vs->sock->sk, type);
+ udp_tunnel_drop_rx_port(dev, vs->sk, type);
}
}
}
@@ -3544,8 +3544,8 @@ static const struct ethtool_ops vxlan_ethtool_ops = {
.get_link_ksettings = vxlan_get_link_ksettings,
};
-static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
- __be16 port, u32 flags, int ifindex)
+static struct sock *vxlan_create_sock(struct net *net, bool ipv6,
+ __be16 port, u32 flags, int ifindex)
{
struct socket *sock;
struct udp_port_cfg udp_conf;
@@ -3571,7 +3571,7 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
return ERR_PTR(err);
udp_allow_gso(sock->sk);
- return sock;
+ return sock->sk;
}
/* Create new listen socket if needed */
@@ -3579,10 +3579,10 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
__be16 port, u32 flags,
int ifindex)
{
+ struct udp_tunnel_sock_cfg tunnel_cfg;
struct vxlan_sock *vs;
- struct socket *sock;
+ struct sock *sk;
unsigned int h;
- struct udp_tunnel_sock_cfg tunnel_cfg;
ASSERT_RTNL();
@@ -3593,18 +3593,18 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
for (h = 0; h < VNI_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vs->vni_list[h]);
- sock = vxlan_create_sock(net, ipv6, port, flags, ifindex);
- if (IS_ERR(sock)) {
+ sk = vxlan_create_sock(net, ipv6, port, flags, ifindex);
+ if (IS_ERR(sk)) {
kfree(vs);
- return ERR_CAST(sock);
+ return ERR_CAST(sk);
}
- vs->sock = sock;
+ vs->sk = sk;
refcount_set(&vs->refcnt, 1);
vs->flags = (flags & VXLAN_F_RCV_FLAGS);
hlist_add_head_rcu(&vs->hlist, vs_head(net, port));
- udp_tunnel_notify_add_rx_port(sock->sk,
+ udp_tunnel_notify_add_rx_port(sk,
(vs->flags & VXLAN_F_GPE) ?
UDP_TUNNEL_TYPE_VXLAN_GPE :
UDP_TUNNEL_TYPE_VXLAN);
@@ -3624,7 +3624,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
tunnel_cfg.gro_complete = vxlan_gro_complete;
}
- setup_udp_tunnel_sock(net, sock->sk, &tunnel_cfg);
+ setup_udp_tunnel_sock(net, sk, &tunnel_cfg);
return vs;
}
diff --git a/drivers/net/vxlan/vxlan_multicast.c b/drivers/net/vxlan/vxlan_multicast.c
index b0e80bca855c..3b75b48dc726 100644
--- a/drivers/net/vxlan/vxlan_multicast.c
+++ b/drivers/net/vxlan/vxlan_multicast.c
@@ -29,7 +29,7 @@ int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
.imr_ifindex = ifindex,
};
- sk = sock4->sock->sk;
+ sk = sock4->sk;
lock_sock(sk);
ret = ip_mc_join_group(sk, &mreq);
release_sock(sk);
@@ -37,7 +37,7 @@ int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
} else {
struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
- sk = sock6->sock->sk;
+ sk = sock6->sk;
lock_sock(sk);
ret = ipv6_sock_mc_join(sk, ifindex, &ip->sin6.sin6_addr);
release_sock(sk);
@@ -62,7 +62,7 @@ int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
.imr_ifindex = ifindex,
};
- sk = sock4->sock->sk;
+ sk = sock4->sk;
lock_sock(sk);
ret = ip_mc_leave_group(sk, &mreq);
release_sock(sk);
@@ -70,7 +70,7 @@ int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
} else {
struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
- sk = sock6->sock->sk;
+ sk = sock6->sk;
lock_sock(sk);
ret = ipv6_sock_mc_drop(sk, ifindex, &ip->sin6.sin6_addr);
release_sock(sk);
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 0ee50785f4f1..8b52294b2902 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -185,7 +185,7 @@ struct vxlan_metadata {
/* per UDP socket information */
struct vxlan_sock {
struct hlist_node hlist;
- struct socket *sock;
+ struct sock *sk;
struct hlist_head vni_list[VNI_HASH_SIZE];
refcount_t refcnt;
u32 flags;
@@ -448,7 +448,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)
--
2.54.0.545.g6539524ca2-goog
next prev parent reply other threads:[~2026-05-02 3:14 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-02 3:12 [PATCH v1 net-next 00/15] udp_tunnel: Speed up UDP tunnel device destruction (Part I) Kuniyuki Iwashima
2026-05-02 3:12 ` [PATCH v1 net-next 01/15] udp_tunnel: Pass struct sock to udp_tunnel_sock_release() Kuniyuki Iwashima
2026-05-03 18:43 ` Kuniyuki Iwashima
2026-05-02 3:12 ` [PATCH v1 net-next 02/15] udp_tunnel: Pass struct sock to setup_udp_tunnel_sock() Kuniyuki Iwashima
2026-05-02 3:12 ` [PATCH v1 net-next 03/15] udp_tunnel: Pass struct sock to udp_tunnel6_dst_lookup() Kuniyuki Iwashima
2026-05-02 3:12 ` [PATCH v1 net-next 04/15] udp_tunnel: Pass struct sock to udp_tunnel_{push,drop}_rx_port() Kuniyuki Iwashima
2026-05-02 3:12 ` [PATCH v1 net-next 05/15] udp_tunnel: Pass struct sock to udp_tunnel_notify_{add,del}_rx_port() Kuniyuki Iwashima
2026-05-02 3:12 ` [PATCH v1 net-next 06/15] vxlan: Fix potential null-ptr-deref in vxlan_gro_prepare_receive() Kuniyuki Iwashima
2026-05-02 3:13 ` Kuniyuki Iwashima [this message]
2026-05-02 3:13 ` [PATCH v1 net-next 08/15] vxlan: Free vxlan_sock with kfree_rcu() Kuniyuki Iwashima
2026-05-02 3:13 ` [PATCH v1 net-next 09/15] geneve: Store struct sock in struct geneve_sock Kuniyuki Iwashima
2026-05-02 3:13 ` [PATCH v1 net-next 10/15] bareudp: Store struct sock in struct bareudp_dev Kuniyuki Iwashima
2026-05-03 18:47 ` Kuniyuki Iwashima
2026-05-02 3:13 ` [PATCH v1 net-next 11/15] fou: Store struct sock in struct fou Kuniyuki Iwashima
2026-05-03 18:52 ` Kuniyuki Iwashima
2026-05-02 3:13 ` [PATCH v1 net-next 12/15] amt: Store struct sock in struct amt_dev Kuniyuki Iwashima
2026-05-03 18:55 ` Kuniyuki Iwashima
2026-05-02 3:13 ` [PATCH v1 net-next 13/15] pfcp: Store struct sock in struct pfcp_dev Kuniyuki Iwashima
2026-05-03 19:00 ` Kuniyuki Iwashima
2026-05-02 3:13 ` [PATCH v1 net-next 14/15] tipc: Store struct sock in struct udp_bearer Kuniyuki Iwashima
2026-05-03 19:05 ` Kuniyuki Iwashima
2026-05-02 3:13 ` [PATCH v1 net-next 15/15] udp_tunnel: Remove synchronize_rcu() in udp_tunnel_sock_release() Kuniyuki Iwashima
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260502031401.3557229-8-kuniyu@google.com \
--to=kuniyu@google.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kuni1840@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox