netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 net-next] dev: Pass netdevice_tracker to dev_get_by_flags_rcu().
@ 2025-07-09 19:01 Kuniyuki Iwashima
  2025-07-10  0:16 ` Jakub Kicinski
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Kuniyuki Iwashima @ 2025-07-09 19:01 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, David Ahern
  Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

This is a follow-up for commit eb1ac9ff6c4a5 ("ipv6: anycast: Don't
hold RTNL for IPV6_JOIN_ANYCAST.").

We should not add a new device lookup API without netdevice_tracker.

Let's pass netdevice_tracker to dev_get_by_flags_rcu() and rename it
with netdev_ prefix to match other newer APIs.

Note that we always use GFP_ATOMIC for netdev_hold() as it's expected
to be called under RCU.

Suggested-by: Jakub Kicinski <kuba@kernel.org>
Link: https://lore.kernel.org/netdev/20250708184053.102109f6@kernel.org/
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
 include/linux/netdevice.h | 4 ++--
 net/core/dev.c            | 8 ++++----
 net/ipv6/anycast.c        | 7 ++++---
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index a80d21a146123..ec23cee5245d7 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3332,8 +3332,6 @@ int dev_get_iflink(const struct net_device *dev);
 int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb);
 int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
 			  struct net_device_path_stack *stack);
-struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short flags,
-					unsigned short mask);
 struct net_device *dev_get_by_name(struct net *net, const char *name);
 struct net_device *dev_get_by_name_rcu(struct net *net, const char *name);
 struct net_device *__dev_get_by_name(struct net *net, const char *name);
@@ -3396,6 +3394,8 @@ struct net_device *netdev_get_by_index(struct net *net, int ifindex,
 				       netdevice_tracker *tracker, gfp_t gfp);
 struct net_device *netdev_get_by_name(struct net *net, const char *name,
 				      netdevice_tracker *tracker, gfp_t gfp);
+struct net_device *netdev_get_by_flags_rcu(struct net *net, netdevice_tracker *tracker,
+					   unsigned short flags, unsigned short mask);
 struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
 void netdev_copy_name(struct net_device *dev, char *name);
 
diff --git a/net/core/dev.c b/net/core/dev.c
index e365b099484ec..48fa8b9836016 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1267,7 +1267,7 @@ struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
 EXPORT_SYMBOL(dev_getfirstbyhwtype);
 
 /**
- * dev_get_by_flags_rcu - find any device with given flags
+ * netdev_get_by_flags_rcu - find any device with given flags
  * @net: the applicable net namespace
  * @if_flags: IFF_* values
  * @mask: bitmask of bits in if_flags to check
@@ -1277,14 +1277,14 @@ EXPORT_SYMBOL(dev_getfirstbyhwtype);
  * Context: rcu_read_lock() must be held.
  * Returns: NULL if a device is not found or a pointer to the device.
  */
-struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short if_flags,
-					unsigned short mask)
+struct net_device *netdev_get_by_flags_rcu(struct net *net, netdevice_tracker *tracker,
+					   unsigned short if_flags, unsigned short mask)
 {
 	struct net_device *dev;
 
 	for_each_netdev_rcu(net, dev) {
 		if (((READ_ONCE(dev->flags) ^ if_flags) & mask) == 0) {
-			dev_hold(dev);
+			netdev_hold(dev, tracker, GFP_ATOMIC);
 			return dev;
 		}
 	}
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 53cf68e0242bf..fa7f0c22167b4 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -69,6 +69,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct ipv6_ac_socklist *pac = NULL;
 	struct net *net = sock_net(sk);
+	netdevice_tracker dev_tracker;
 	struct net_device *dev = NULL;
 	struct inet6_dev *idev;
 	int err = 0, ishost;
@@ -112,8 +113,8 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 			goto error;
 		} else {
 			/* router, no matching interface: just pick one */
-			dev = dev_get_by_flags_rcu(net, IFF_UP,
-						   IFF_UP | IFF_LOOPBACK);
+			dev = netdev_get_by_flags_rcu(net, &dev_tracker, IFF_UP,
+						      IFF_UP | IFF_LOOPBACK);
 		}
 		rcu_read_unlock();
 	}
@@ -159,7 +160,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 error_idev:
 	in6_dev_put(idev);
 error:
-	dev_put(dev);
+	netdev_put(dev, &dev_tracker);
 
 	if (pac)
 		sock_kfree_s(sk, pac, sizeof(*pac));
-- 
2.50.0.727.gbf7dc18ff4-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-07-10 23:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-09 19:01 [PATCH v1 net-next] dev: Pass netdevice_tracker to dev_get_by_flags_rcu() Kuniyuki Iwashima
2025-07-10  0:16 ` Jakub Kicinski
2025-07-10  1:38   ` Kuniyuki Iwashima
2025-07-10 21:51 ` kernel test robot
2025-07-10 23:05 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).