Skip to content

Commit 844e5e7

Browse files
q2venPaolo Abeni
authored and
Paolo Abeni
committed
rtnetlink: Add assertion helpers for per-netns RTNL.
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> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 76aed95 commit 844e5e7

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

include/linux/rtnetlink.h

+41-4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ extern atomic_t dev_unreg_count;
5151
extern struct rw_semaphore pernet_ops_rwsem;
5252
extern struct rw_semaphore net_rwsem;
5353

54+
#define ASSERT_RTNL() \
55+
WARN_ONCE(!rtnl_is_locked(), \
56+
"RTNL: assertion failed at %s (%d)\n", __FILE__, __LINE__)
57+
5458
#ifdef CONFIG_PROVE_LOCKING
5559
extern bool lockdep_rtnl_is_held(void);
5660
#else
@@ -98,6 +102,22 @@ void __rtnl_net_unlock(struct net *net);
98102
void rtnl_net_lock(struct net *net);
99103
void rtnl_net_unlock(struct net *net);
100104
int rtnl_net_lock_cmp_fn(const struct lockdep_map *a, const struct lockdep_map *b);
105+
106+
bool rtnl_net_is_locked(struct net *net);
107+
108+
#define ASSERT_RTNL_NET(net) \
109+
WARN_ONCE(!rtnl_net_is_locked(net), \
110+
"RTNL_NET: assertion failed at %s (%d)\n", \
111+
__FILE__, __LINE__)
112+
113+
bool lockdep_rtnl_net_is_held(struct net *net);
114+
115+
#define rcu_dereference_rtnl_net(net, p) \
116+
rcu_dereference_check(p, lockdep_rtnl_net_is_held(net))
117+
#define rtnl_net_dereference(net, p) \
118+
rcu_dereference_protected(p, lockdep_rtnl_net_is_held(net))
119+
#define rcu_replace_pointer_rtnl_net(net, rp, p) \
120+
rcu_replace_pointer(rp, p, lockdep_rtnl_net_is_held(net))
101121
#else
102122
static inline void __rtnl_net_lock(struct net *net) {}
103123
static inline void __rtnl_net_unlock(struct net *net) {}
@@ -111,6 +131,27 @@ static inline void rtnl_net_unlock(struct net *net)
111131
{
112132
rtnl_unlock();
113133
}
134+
135+
static inline void ASSERT_RTNL_NET(struct net *net)
136+
{
137+
ASSERT_RTNL();
138+
}
139+
140+
static inline void *rcu_dereference_rtnl_net(struct net *net, void *p)
141+
{
142+
return rcu_dereference_rtnl(p);
143+
}
144+
145+
static inline void *rtnl_net_dereference(struct net *net, void *p)
146+
{
147+
return rtnl_dereference(p);
148+
}
149+
150+
static inline void *rcu_replace_pointer_rtnl_net(struct net *net,
151+
void *rp, void *p)
152+
{
153+
return rcu_replace_pointer_rtnl(rp, p);
154+
}
114155
#endif
115156

116157
static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev)
@@ -140,10 +181,6 @@ void rtnetlink_init(void);
140181
void __rtnl_unlock(void);
141182
void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail);
142183

143-
#define ASSERT_RTNL() \
144-
WARN_ONCE(!rtnl_is_locked(), \
145-
"RTNL: assertion failed at %s (%d)\n", __FILE__, __LINE__)
146-
147184
extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
148185
struct netlink_callback *cb,
149186
struct net_device *dev,

net/core/rtnetlink.c

+12
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,18 @@ int rtnl_net_lock_cmp_fn(const struct lockdep_map *a, const struct lockdep_map *
235235

236236
return rtnl_net_cmp_locks(net_a, net_b);
237237
}
238+
239+
bool rtnl_net_is_locked(struct net *net)
240+
{
241+
return rtnl_is_locked() && mutex_is_locked(&net->rtnl_mutex);
242+
}
243+
EXPORT_SYMBOL(rtnl_net_is_locked);
244+
245+
bool lockdep_rtnl_net_is_held(struct net *net)
246+
{
247+
return lockdep_rtnl_is_held() && lockdep_is_held(&net->rtnl_mutex);
248+
}
249+
EXPORT_SYMBOL(lockdep_rtnl_net_is_held);
238250
#endif
239251

240252
static struct rtnl_link __rcu *__rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];

0 commit comments

Comments
 (0)