pfcp: Store struct sock in struct pfcp_dev.

pfcp 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 pfcp_dev.

pfcp_del_sock() is called from dev->netdev_ops->ndo_uninit().
The 2nd synchronize_net() in unregister_netdevice_many_notify()
ensures that inflight pfcp RX fast paths finish before pfcp_dev
is freed.

Note that synchronize_rcu() is added in the error path of
pfcp_newlink() since free_netdev() will free pfcp_dev immediately
once we remove synchronize_rcu() in udp_tunnel_sock_release().

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260502031401.3557229-14-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Kuniyuki Iwashima 2026-05-02 03:13:06 +00:00 committed by Jakub Kicinski
parent 65c6e06d5a
commit fe57adbe0d

View File

@ -18,7 +18,7 @@
struct pfcp_dev {
struct list_head list;
struct socket *sock;
struct sock *sk;
struct net_device *dev;
struct net *net;
@ -104,8 +104,8 @@ static int pfcp_encap_recv(struct sock *sk, struct sk_buff *skb)
static void pfcp_del_sock(struct pfcp_dev *pfcp)
{
udp_tunnel_sock_release(pfcp->sock->sk);
pfcp->sock = NULL;
udp_tunnel_sock_release(pfcp->sk);
pfcp->sk = NULL;
}
static void pfcp_dev_uninit(struct net_device *dev)
@ -151,7 +151,7 @@ static void pfcp_link_setup(struct net_device *dev)
netif_keep_dst(dev);
}
static struct socket *pfcp_create_sock(struct pfcp_dev *pfcp)
static struct sock *pfcp_create_sock(struct pfcp_dev *pfcp)
{
struct udp_tunnel_sock_cfg tuncfg = {};
struct udp_port_cfg udp_conf = {
@ -174,14 +174,14 @@ static struct socket *pfcp_create_sock(struct pfcp_dev *pfcp)
setup_udp_tunnel_sock(net, sock->sk, &tuncfg);
return sock;
return sock->sk;
}
static int pfcp_add_sock(struct pfcp_dev *pfcp)
{
pfcp->sock = pfcp_create_sock(pfcp);
pfcp->sk = pfcp_create_sock(pfcp);
return PTR_ERR_OR_ZERO(pfcp->sock);
return PTR_ERR_OR_ZERO(pfcp->sk);
}
static int pfcp_newlink(struct net_device *dev,
@ -216,6 +216,7 @@ static int pfcp_newlink(struct net_device *dev,
exit_del_pfcp_sock:
pfcp_del_sock(pfcp);
synchronize_rcu();
exit_err:
pfcp->net = NULL;
return err;