summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKuniyuki Iwashima <kuniyu@google.com>2026-05-02 06:13:06 +0300
committerJakub Kicinski <kuba@kernel.org>2026-05-06 03:47:05 +0300
commitfe57adbe0dacd00905f40db78468ac05f14cc419 (patch)
tree88da725ff8c45e72cae09df9ed5e3935954d5365
parent65c6e06d5abad33ff2ad43daad472efb90deafc2 (diff)
downloadlinux-fe57adbe0dacd00905f40db78468ac05f14cc419.tar.xz
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>
-rw-r--r--drivers/net/pfcp.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/net/pfcp.c b/drivers/net/pfcp.c
index 870137695e8a..5f1c9d2c0b49 100644
--- a/drivers/net/pfcp.c
+++ b/drivers/net/pfcp.c
@@ -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 @@ drop:
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;