* [PATCH v3 net-next 1/4] Revert "rtnetlink: add guard for RTNL"
2024-10-04 22:10 [PATCH v3 net-next 0/4] rtnetlink: Per-netns RTNL Kuniyuki Iwashima
@ 2024-10-04 22:10 ` Kuniyuki Iwashima
2024-10-04 22:10 ` [PATCH v3 net-next 2/4] rtnetlink: Add per-netns RTNL Kuniyuki Iwashima
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Kuniyuki Iwashima @ 2024-10-04 22:10 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
This reverts commit 464eb03c4a7cfb32cb3324249193cf6bb5b35152.
Once we have a per-netns RTNL, we won't use guard(rtnl).
Also, there's no users for now.
$ grep -rnI "guard(rtnl" || true
$
Suggested-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/netdev/CANn89i+KoYzUH+VPLdGmLABYf5y4TW0hrM4UAeQQJ9AREty0iw@mail.gmail.com/
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
---
include/linux/rtnetlink.h | 3 ---
1 file changed, 3 deletions(-)
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index a7da7dfc06a2..cdfc897f1e3c 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -7,7 +7,6 @@
#include <linux/netdevice.h>
#include <linux/wait.h>
#include <linux/refcount.h>
-#include <linux/cleanup.h>
#include <uapi/linux/rtnetlink.h>
extern int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, u32 group, int echo);
@@ -47,8 +46,6 @@ extern int rtnl_is_locked(void);
extern int rtnl_lock_killable(void);
extern bool refcount_dec_and_rtnl_lock(refcount_t *r);
-DEFINE_LOCK_GUARD_0(rtnl, rtnl_lock(), rtnl_unlock())
-
extern wait_queue_head_t netdev_unregistering_wq;
extern atomic_t dev_unreg_count;
extern struct rw_semaphore pernet_ops_rwsem;
--
2.30.2
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v3 net-next 2/4] rtnetlink: Add per-netns RTNL.
2024-10-04 22:10 [PATCH v3 net-next 0/4] rtnetlink: Per-netns RTNL Kuniyuki Iwashima
2024-10-04 22:10 ` [PATCH v3 net-next 1/4] Revert "rtnetlink: add guard for RTNL" Kuniyuki Iwashima
@ 2024-10-04 22:10 ` Kuniyuki Iwashima
2024-10-05 8:16 ` Eric Dumazet
2024-10-04 22:10 ` [PATCH v3 net-next 3/4] rtnetlink: Add assertion helpers for " Kuniyuki Iwashima
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Kuniyuki Iwashima @ 2024-10-04 22:10 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
The goal is to break RTNL down into per-netns mutex.
This patch adds per-netns mutex and its helper functions, rtnl_net_lock()
and rtnl_net_unlock().
rtnl_net_lock() acquires the global RTNL and per-netns RTNL mutex, and
rtnl_net_unlock() releases them.
We will replace 800+ rtnl_lock() with rtnl_net_lock() and finally removes
rtnl_lock() in rtnl_net_lock().
When we need to nest per-netns RTNL mutex, we will use __rtnl_net_lock(),
and its locking order is defined by rtnl_net_lock_cmp_fn() as follows:
1. init_net is first
2. netns address ascending order
Note that the conversion will be done under CONFIG_DEBUG_NET_SMALL_RTNL
with LOCKDEP so that we can carefully add the extra mutex without slowing
down RTNL operations during conversion.
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
include/linux/rtnetlink.h | 21 ++++++++++++++
include/net/net_namespace.h | 4 +++
net/Kconfig.debug | 15 ++++++++++
net/core/net_namespace.c | 6 ++++
net/core/rtnetlink.c | 58 +++++++++++++++++++++++++++++++++++++
5 files changed, 104 insertions(+)
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index cdfc897f1e3c..edd840a49989 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -92,6 +92,27 @@ static inline bool lockdep_rtnl_is_held(void)
#define rcu_replace_pointer_rtnl(rp, p) \
rcu_replace_pointer(rp, p, lockdep_rtnl_is_held())
+#ifdef CONFIG_DEBUG_NET_SMALL_RTNL
+void __rtnl_net_lock(struct net *net);
+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);
+#else
+static inline void __rtnl_net_lock(struct net *net) {}
+static inline void __rtnl_net_unlock(struct net *net) {}
+
+static inline void rtnl_net_lock(struct net *net)
+{
+ rtnl_lock();
+}
+
+static inline void rtnl_net_unlock(struct net *net)
+{
+ rtnl_unlock();
+}
+#endif
+
static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev)
{
return rtnl_dereference(dev->ingress_queue);
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index e67b483cc8bb..873c0f9fdac6 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -188,6 +188,10 @@ struct net {
#if IS_ENABLED(CONFIG_SMC)
struct netns_smc smc;
#endif
+#ifdef CONFIG_DEBUG_NET_SMALL_RTNL
+ /* Move to a better place when the config guard is removed. */
+ struct mutex rtnl_mutex;
+#endif
} __randomize_layout;
#include <linux/seq_file_net.h>
diff --git a/net/Kconfig.debug b/net/Kconfig.debug
index 5e3fffe707dd..277fab8c4d77 100644
--- a/net/Kconfig.debug
+++ b/net/Kconfig.debug
@@ -24,3 +24,18 @@ config DEBUG_NET
help
Enable extra sanity checks in networking.
This is mostly used by fuzzers, but is safe to select.
+
+config DEBUG_NET_SMALL_RTNL
+ bool "Add extra per-netns mutex inside RTNL"
+ depends on DEBUG_KERNEL && NET && LOCK_DEBUGGING_SUPPORT
+ select PROVE_LOCKING
+ default n
+ help
+ rtnl_lock() is being replaced with rtnl_net_lock() that
+ acquires the global RTNL and a small per-netns RTNL mutex.
+
+ During the conversion, rtnl_net_lock() just adds an extra
+ mutex in every RTNL scope and slows down the operations.
+
+ Once the conversion completes, rtnl_lock() will be removed
+ and rtnetlink will gain per-netns scalability.
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index e39479f1c9a4..105e3cd26763 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -334,6 +334,12 @@ static __net_init void preinit_net(struct net *net, struct user_namespace *user_
idr_init(&net->netns_ids);
spin_lock_init(&net->nsid_lock);
mutex_init(&net->ipv4.ra_mutex);
+
+#ifdef CONFIG_DEBUG_NET_SMALL_RTNL
+ mutex_init(&net->rtnl_mutex);
+ lock_set_cmp_fn(&net->rtnl_mutex, rtnl_net_lock_cmp_fn, NULL);
+#endif
+
preinit_net_sysctl(net);
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f0a520987085..edf530441b65 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -179,6 +179,64 @@ bool lockdep_rtnl_is_held(void)
EXPORT_SYMBOL(lockdep_rtnl_is_held);
#endif /* #ifdef CONFIG_PROVE_LOCKING */
+#ifdef CONFIG_DEBUG_NET_SMALL_RTNL
+void __rtnl_net_lock(struct net *net)
+{
+ ASSERT_RTNL();
+
+ mutex_lock(&net->rtnl_mutex);
+}
+EXPORT_SYMBOL(__rtnl_net_lock);
+
+void __rtnl_net_unlock(struct net *net)
+{
+ ASSERT_RTNL();
+
+ mutex_unlock(&net->rtnl_mutex);
+}
+EXPORT_SYMBOL(__rtnl_net_unlock);
+
+void rtnl_net_lock(struct net *net)
+{
+ rtnl_lock();
+ __rtnl_net_lock(net);
+}
+EXPORT_SYMBOL(rtnl_net_lock);
+
+void rtnl_net_unlock(struct net *net)
+{
+ __rtnl_net_unlock(net);
+ rtnl_unlock();
+}
+EXPORT_SYMBOL(rtnl_net_unlock);
+
+static int rtnl_net_cmp_locks(const struct net *net_a, const struct net *net_b)
+{
+ if (net_eq(net_a, net_b))
+ return 0;
+
+ /* always init_net first */
+ if (net_eq(net_a, &init_net))
+ return -1;
+
+ if (net_eq(net_b, &init_net))
+ return 1;
+
+ /* otherwise lock in ascending order */
+ return net_a < net_b ? -1 : 1;
+}
+
+int rtnl_net_lock_cmp_fn(const struct lockdep_map *a, const struct lockdep_map *b)
+{
+ const struct net *net_a, *net_b;
+
+ net_a = container_of(a, struct net, rtnl_mutex.dep_map);
+ net_b = container_of(b, struct net, rtnl_mutex.dep_map);
+
+ return rtnl_net_cmp_locks(net_a, net_b);
+}
+#endif
+
static struct rtnl_link __rcu *__rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];
static inline int rtm_msgindex(int msgtype)
--
2.30.2
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v3 net-next 2/4] rtnetlink: Add per-netns RTNL.
2024-10-04 22:10 ` [PATCH v3 net-next 2/4] rtnetlink: Add per-netns RTNL Kuniyuki Iwashima
@ 2024-10-05 8:16 ` Eric Dumazet
0 siblings, 0 replies; 11+ messages in thread
From: Eric Dumazet @ 2024-10-05 8:16 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Kuniyuki Iwashima,
netdev
On Sat, Oct 5, 2024 at 12:11 AM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
>
> The goal is to break RTNL down into per-netns mutex.
>
> This patch adds per-netns mutex and its helper functions, rtnl_net_lock()
> and rtnl_net_unlock().
>
> rtnl_net_lock() acquires the global RTNL and per-netns RTNL mutex, and
> rtnl_net_unlock() releases them.
>
> We will replace 800+ rtnl_lock() with rtnl_net_lock() and finally removes
> rtnl_lock() in rtnl_net_lock().
>
> When we need to nest per-netns RTNL mutex, we will use __rtnl_net_lock(),
> and its locking order is defined by rtnl_net_lock_cmp_fn() as follows:
>
> 1. init_net is first
> 2. netns address ascending order
>
> Note that the conversion will be done under CONFIG_DEBUG_NET_SMALL_RTNL
> with LOCKDEP so that we can carefully add the extra mutex without slowing
> down RTNL operations during conversion.
>
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 net-next 3/4] rtnetlink: Add assertion helpers for per-netns RTNL.
2024-10-04 22:10 [PATCH v3 net-next 0/4] rtnetlink: Per-netns RTNL Kuniyuki Iwashima
2024-10-04 22:10 ` [PATCH v3 net-next 1/4] Revert "rtnetlink: add guard for RTNL" Kuniyuki Iwashima
2024-10-04 22:10 ` [PATCH v3 net-next 2/4] rtnetlink: Add per-netns RTNL Kuniyuki Iwashima
@ 2024-10-04 22:10 ` Kuniyuki Iwashima
2024-10-08 11:39 ` Paolo Abeni
2024-10-08 11:48 ` Eric Dumazet
2024-10-04 22:10 ` [PATCH v3 net-next 4/4] rtnetlink: Add ASSERT_RTNL_NET() placeholder for netdev notifier Kuniyuki Iwashima
2024-10-08 13:30 ` [PATCH v3 net-next 0/4] rtnetlink: Per-netns RTNL patchwork-bot+netdevbpf
4 siblings, 2 replies; 11+ messages in thread
From: Kuniyuki Iwashima @ 2024-10-04 22:10 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
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(-)
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];
--
2.30.2
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v3 net-next 3/4] rtnetlink: Add assertion helpers for per-netns RTNL.
2024-10-04 22:10 ` [PATCH v3 net-next 3/4] rtnetlink: Add assertion helpers for " Kuniyuki Iwashima
@ 2024-10-08 11:39 ` Paolo Abeni
2024-10-08 11:46 ` Eric Dumazet
2024-10-08 16:12 ` Kuniyuki Iwashima
2024-10-08 11:48 ` Eric Dumazet
1 sibling, 2 replies; 11+ messages in thread
From: Paolo Abeni @ 2024-10-08 11:39 UTC (permalink / raw)
To: Kuniyuki Iwashima, Eric Dumazet
Cc: Kuniyuki Iwashima, netdev, David S. Miller, Jakub Kicinski
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 net-next 3/4] rtnetlink: Add assertion helpers for per-netns RTNL.
2024-10-08 11:39 ` Paolo Abeni
@ 2024-10-08 11:46 ` Eric Dumazet
2024-10-08 16:12 ` Kuniyuki Iwashima
1 sibling, 0 replies; 11+ messages in thread
From: Eric Dumazet @ 2024-10-08 11:46 UTC (permalink / raw)
To: Paolo Abeni
Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev, David S. Miller,
Jakub Kicinski
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 :)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 net-next 3/4] rtnetlink: Add assertion helpers for per-netns RTNL.
2024-10-08 11:39 ` Paolo Abeni
2024-10-08 11:46 ` Eric Dumazet
@ 2024-10-08 16:12 ` Kuniyuki Iwashima
1 sibling, 0 replies; 11+ messages in thread
From: Kuniyuki Iwashima @ 2024-10-08 16:12 UTC (permalink / raw)
To: pabeni; +Cc: davem, edumazet, kuba, kuni1840, kuniyu, netdev
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!
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 net-next 3/4] rtnetlink: Add assertion helpers for per-netns RTNL.
2024-10-04 22:10 ` [PATCH v3 net-next 3/4] rtnetlink: Add assertion helpers for " Kuniyuki Iwashima
2024-10-08 11:39 ` Paolo Abeni
@ 2024-10-08 11:48 ` Eric Dumazet
1 sibling, 0 replies; 11+ messages in thread
From: Eric Dumazet @ 2024-10-08 11:48 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Kuniyuki Iwashima,
netdev
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>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 net-next 4/4] rtnetlink: Add ASSERT_RTNL_NET() placeholder for netdev notifier.
2024-10-04 22:10 [PATCH v3 net-next 0/4] rtnetlink: Per-netns RTNL Kuniyuki Iwashima
` (2 preceding siblings ...)
2024-10-04 22:10 ` [PATCH v3 net-next 3/4] rtnetlink: Add assertion helpers for " Kuniyuki Iwashima
@ 2024-10-04 22:10 ` Kuniyuki Iwashima
2024-10-08 13:30 ` [PATCH v3 net-next 0/4] rtnetlink: Per-netns RTNL patchwork-bot+netdevbpf
4 siblings, 0 replies; 11+ messages in thread
From: Kuniyuki Iwashima @ 2024-10-04 22:10 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
The global and per-netns netdev notifier depend on RTNL, and its
dependency is not so clear due to nested calls.
Let's add a placeholder to place ASSERT_RTNL_NET() for each event.
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
---
net/core/Makefile | 1 +
net/core/rtnl_net_debug.c | 131 ++++++++++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+)
create mode 100644 net/core/rtnl_net_debug.c
diff --git a/net/core/Makefile b/net/core/Makefile
index c3ebbaf9c81e..5a72a87ee0f1 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -45,3 +45,4 @@ obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o
obj-$(CONFIG_OF) += of_net.o
obj-$(CONFIG_NET_TEST) += net_test.o
obj-$(CONFIG_NET_DEVMEM) += devmem.o
+obj-$(CONFIG_DEBUG_NET_SMALL_RTNL) += rtnl_net_debug.o
diff --git a/net/core/rtnl_net_debug.c b/net/core/rtnl_net_debug.c
new file mode 100644
index 000000000000..e90a32242e22
--- /dev/null
+++ b/net/core/rtnl_net_debug.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright Amazon.com Inc. or its affiliates. */
+
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/notifier.h>
+#include <linux/rtnetlink.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
+static int rtnl_net_debug_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ struct net *net = dev_net(dev);
+ enum netdev_cmd cmd = event;
+
+ /* Keep enum and don't add default to trigger -Werror=switch */
+ switch (cmd) {
+ case NETDEV_UP:
+ case NETDEV_DOWN:
+ case NETDEV_REBOOT:
+ case NETDEV_CHANGE:
+ case NETDEV_REGISTER:
+ case NETDEV_UNREGISTER:
+ case NETDEV_CHANGEMTU:
+ case NETDEV_CHANGEADDR:
+ case NETDEV_PRE_CHANGEADDR:
+ case NETDEV_GOING_DOWN:
+ case NETDEV_CHANGENAME:
+ case NETDEV_FEAT_CHANGE:
+ case NETDEV_BONDING_FAILOVER:
+ case NETDEV_PRE_UP:
+ case NETDEV_PRE_TYPE_CHANGE:
+ case NETDEV_POST_TYPE_CHANGE:
+ case NETDEV_POST_INIT:
+ case NETDEV_PRE_UNINIT:
+ case NETDEV_RELEASE:
+ case NETDEV_NOTIFY_PEERS:
+ case NETDEV_JOIN:
+ case NETDEV_CHANGEUPPER:
+ case NETDEV_RESEND_IGMP:
+ case NETDEV_PRECHANGEMTU:
+ case NETDEV_CHANGEINFODATA:
+ case NETDEV_BONDING_INFO:
+ case NETDEV_PRECHANGEUPPER:
+ case NETDEV_CHANGELOWERSTATE:
+ case NETDEV_UDP_TUNNEL_PUSH_INFO:
+ case NETDEV_UDP_TUNNEL_DROP_INFO:
+ case NETDEV_CHANGE_TX_QUEUE_LEN:
+ case NETDEV_CVLAN_FILTER_PUSH_INFO:
+ case NETDEV_CVLAN_FILTER_DROP_INFO:
+ case NETDEV_SVLAN_FILTER_PUSH_INFO:
+ case NETDEV_SVLAN_FILTER_DROP_INFO:
+ case NETDEV_OFFLOAD_XSTATS_ENABLE:
+ case NETDEV_OFFLOAD_XSTATS_DISABLE:
+ case NETDEV_OFFLOAD_XSTATS_REPORT_USED:
+ case NETDEV_OFFLOAD_XSTATS_REPORT_DELTA:
+ case NETDEV_XDP_FEAT_CHANGE:
+ ASSERT_RTNL();
+ break;
+
+ /* Once an event fully supports RTNL_NET, move it here
+ * and remove "if (0)" below.
+ *
+ * case NETDEV_XXX:
+ * ASSERT_RTNL_NET(net);
+ * break;
+ */
+ }
+
+ /* Just to avoid unused-variable error for dev and net. */
+ if (0)
+ ASSERT_RTNL_NET(net);
+
+ return NOTIFY_DONE;
+}
+
+static int rtnl_net_debug_net_id;
+
+static int __net_init rtnl_net_debug_net_init(struct net *net)
+{
+ struct notifier_block *nb;
+
+ nb = net_generic(net, rtnl_net_debug_net_id);
+ nb->notifier_call = rtnl_net_debug_event;
+
+ return register_netdevice_notifier_net(net, nb);
+}
+
+static void __net_exit rtnl_net_debug_net_exit(struct net *net)
+{
+ struct notifier_block *nb;
+
+ nb = net_generic(net, rtnl_net_debug_net_id);
+ unregister_netdevice_notifier_net(net, nb);
+}
+
+static struct pernet_operations rtnl_net_debug_net_ops __net_initdata = {
+ .init = rtnl_net_debug_net_init,
+ .exit = rtnl_net_debug_net_exit,
+ .id = &rtnl_net_debug_net_id,
+ .size = sizeof(struct notifier_block),
+};
+
+static struct notifier_block rtnl_net_debug_block = {
+ .notifier_call = rtnl_net_debug_event,
+};
+
+static int __init rtnl_net_debug_init(void)
+{
+ int ret;
+
+ ret = register_pernet_device(&rtnl_net_debug_net_ops);
+ if (ret)
+ return ret;
+
+ ret = register_netdevice_notifier(&rtnl_net_debug_block);
+ if (ret)
+ unregister_pernet_subsys(&rtnl_net_debug_net_ops);
+
+ return ret;
+}
+
+static void __exit rtnl_net_debug_exit(void)
+{
+ unregister_netdevice_notifier(&rtnl_net_debug_block);
+ unregister_pernet_device(&rtnl_net_debug_net_ops);
+}
+
+subsys_initcall(rtnl_net_debug_init);
--
2.30.2
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v3 net-next 0/4] rtnetlink: Per-netns RTNL.
2024-10-04 22:10 [PATCH v3 net-next 0/4] rtnetlink: Per-netns RTNL Kuniyuki Iwashima
` (3 preceding siblings ...)
2024-10-04 22:10 ` [PATCH v3 net-next 4/4] rtnetlink: Add ASSERT_RTNL_NET() placeholder for netdev notifier Kuniyuki Iwashima
@ 2024-10-08 13:30 ` patchwork-bot+netdevbpf
4 siblings, 0 replies; 11+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-10-08 13:30 UTC (permalink / raw)
To: Kuniyuki Iwashima; +Cc: davem, edumazet, kuba, pabeni, kuni1840, netdev
Hello:
This series was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Fri, 4 Oct 2024 15:10:27 -0700 you wrote:
> rtnl_lock() is a "Big Kernel Lock" in the networking slow path and
> serialised all rtnetlink requests until 4.13.
>
> Since RTNL_FLAG_DOIT_UNLOCKED and RTNL_FLAG_DUMP_UNLOCKED have been
> introduced in 4.14 and 6.9, respectively, rtnetlink message handlers
> are ready to be converted to RTNL-less/free.
>
> [...]
Here is the summary with links:
- [v3,net-next,1/4] Revert "rtnetlink: add guard for RTNL"
https://git.kernel.org/netdev/net-next/c/ec763c234d7f
- [v3,net-next,2/4] rtnetlink: Add per-netns RTNL.
https://git.kernel.org/netdev/net-next/c/76aed95319da
- [v3,net-next,3/4] rtnetlink: Add assertion helpers for per-netns RTNL.
https://git.kernel.org/netdev/net-next/c/844e5e7e656d
- [v3,net-next,4/4] rtnetlink: Add ASSERT_RTNL_NET() placeholder for netdev notifier.
https://git.kernel.org/netdev/net-next/c/03fa53485659
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 11+ messages in thread