Message ID | 20241004221031.77743-4-kuniyu@amazon.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 844e5e7e656d3a7a904fd5607f8491d6fd01db8e |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | rtnetlink: Per-netns RTNL. | expand |
Hi, On 10/5/24 00:10, Kuniyuki Iwashima wrote: > Once an RTNL scope is converted with rtnl_net_lock(), we will replace > RTNL helper functions inside the scope with the following per-netns > alternatives: > > ASSERT_RTNL() -> ASSERT_RTNL_NET(net) > rcu_dereference_rtnl(p) -> rcu_dereference_rtnl_net(net, p) > > Note that the per-netns helpers are equivalent to the conventional > helpers unless CONFIG_DEBUG_NET_SMALL_RTNL is enabled. > > Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> I guess Kuniyuki stripped the ack received on v2 due to the edit here. @Kuniyuki: in the next iterations, please include a per patch changelog to simplify the review. @Eric: would you mind acking it again? Thanks! Paolo
On Tue, Oct 8, 2024 at 1:39 PM Paolo Abeni <pabeni@redhat.com> wrote: > > Hi, > > On 10/5/24 00:10, Kuniyuki Iwashima wrote: > > Once an RTNL scope is converted with rtnl_net_lock(), we will replace > > RTNL helper functions inside the scope with the following per-netns > > alternatives: > > > > ASSERT_RTNL() -> ASSERT_RTNL_NET(net) > > rcu_dereference_rtnl(p) -> rcu_dereference_rtnl_net(net, p) > > > > Note that the per-netns helpers are equivalent to the conventional > > helpers unless CONFIG_DEBUG_NET_SMALL_RTNL is enabled. > > > > Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> > > I guess Kuniyuki stripped the ack received on v2 due to the edit here. > > @Kuniyuki: in the next iterations, please include a per patch changelog > to simplify the review. > > @Eric: would you mind acking it again? Thanks! Let me check this new version :)
On Sat, Oct 5, 2024 at 12:12 AM Kuniyuki Iwashima <kuniyu@amazon.com> wrote: > > Once an RTNL scope is converted with rtnl_net_lock(), we will replace > RTNL helper functions inside the scope with the following per-netns > alternatives: > > ASSERT_RTNL() -> ASSERT_RTNL_NET(net) > rcu_dereference_rtnl(p) -> rcu_dereference_rtnl_net(net, p) > > Note that the per-netns helpers are equivalent to the conventional > helpers unless CONFIG_DEBUG_NET_SMALL_RTNL is enabled. > > Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Reviewed-by: Eric Dumazet <edumazet@google.com>
From: Paolo Abeni <pabeni@redhat.com> Date: Tue, 8 Oct 2024 13:39:24 +0200 > On 10/5/24 00:10, Kuniyuki Iwashima wrote: > > Once an RTNL scope is converted with rtnl_net_lock(), we will replace > > RTNL helper functions inside the scope with the following per-netns > > alternatives: > > > > ASSERT_RTNL() -> ASSERT_RTNL_NET(net) > > rcu_dereference_rtnl(p) -> rcu_dereference_rtnl_net(net, p) > > > > Note that the per-netns helpers are equivalent to the conventional > > helpers unless CONFIG_DEBUG_NET_SMALL_RTNL is enabled. > > > > Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> > > I guess Kuniyuki stripped the ack received on v2 due to the edit here. > > @Kuniyuki: in the next iterations, please include a per patch changelog > to simplify the review. Sure, will include changelog per-patch basis for future submission. Thanks!
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index edd840a49989..8468a4ce8510 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -51,6 +51,10 @@ extern atomic_t dev_unreg_count; extern struct rw_semaphore pernet_ops_rwsem; extern struct rw_semaphore net_rwsem; +#define ASSERT_RTNL() \ + WARN_ONCE(!rtnl_is_locked(), \ + "RTNL: assertion failed at %s (%d)\n", __FILE__, __LINE__) + #ifdef CONFIG_PROVE_LOCKING extern bool lockdep_rtnl_is_held(void); #else @@ -98,6 +102,22 @@ void __rtnl_net_unlock(struct net *net); void rtnl_net_lock(struct net *net); void rtnl_net_unlock(struct net *net); int rtnl_net_lock_cmp_fn(const struct lockdep_map *a, const struct lockdep_map *b); + +bool rtnl_net_is_locked(struct net *net); + +#define ASSERT_RTNL_NET(net) \ + WARN_ONCE(!rtnl_net_is_locked(net), \ + "RTNL_NET: assertion failed at %s (%d)\n", \ + __FILE__, __LINE__) + +bool lockdep_rtnl_net_is_held(struct net *net); + +#define rcu_dereference_rtnl_net(net, p) \ + rcu_dereference_check(p, lockdep_rtnl_net_is_held(net)) +#define rtnl_net_dereference(net, p) \ + rcu_dereference_protected(p, lockdep_rtnl_net_is_held(net)) +#define rcu_replace_pointer_rtnl_net(net, rp, p) \ + rcu_replace_pointer(rp, p, lockdep_rtnl_net_is_held(net)) #else static inline void __rtnl_net_lock(struct net *net) {} static inline void __rtnl_net_unlock(struct net *net) {} @@ -111,6 +131,27 @@ static inline void rtnl_net_unlock(struct net *net) { rtnl_unlock(); } + +static inline void ASSERT_RTNL_NET(struct net *net) +{ + ASSERT_RTNL(); +} + +static inline void *rcu_dereference_rtnl_net(struct net *net, void *p) +{ + return rcu_dereference_rtnl(p); +} + +static inline void *rtnl_net_dereference(struct net *net, void *p) +{ + return rtnl_dereference(p); +} + +static inline void *rcu_replace_pointer_rtnl_net(struct net *net, + void *rp, void *p) +{ + return rcu_replace_pointer_rtnl(rp, p); +} #endif static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev) @@ -140,10 +181,6 @@ void rtnetlink_init(void); void __rtnl_unlock(void); void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail); -#define ASSERT_RTNL() \ - WARN_ONCE(!rtnl_is_locked(), \ - "RTNL: assertion failed at %s (%d)\n", __FILE__, __LINE__) - extern int ndo_dflt_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *dev, diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index edf530441b65..2b44ec690780 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -235,6 +235,18 @@ int rtnl_net_lock_cmp_fn(const struct lockdep_map *a, const struct lockdep_map * return rtnl_net_cmp_locks(net_a, net_b); } + +bool rtnl_net_is_locked(struct net *net) +{ + return rtnl_is_locked() && mutex_is_locked(&net->rtnl_mutex); +} +EXPORT_SYMBOL(rtnl_net_is_locked); + +bool lockdep_rtnl_net_is_held(struct net *net) +{ + return lockdep_rtnl_is_held() && lockdep_is_held(&net->rtnl_mutex); +} +EXPORT_SYMBOL(lockdep_rtnl_net_is_held); #endif static struct rtnl_link __rcu *__rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];
Once an RTNL scope is converted with rtnl_net_lock(), we will replace RTNL helper functions inside the scope with the following per-netns alternatives: ASSERT_RTNL() -> ASSERT_RTNL_NET(net) rcu_dereference_rtnl(p) -> rcu_dereference_rtnl_net(net, p) Note that the per-netns helpers are equivalent to the conventional helpers unless CONFIG_DEBUG_NET_SMALL_RTNL is enabled. Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> --- include/linux/rtnetlink.h | 45 +++++++++++++++++++++++++++++++++++---- net/core/rtnetlink.c | 12 +++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-)