diff options
author | Patrick McHardy <kaber@trash.net> | 2014-02-18 13:06:48 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-02-25 05:29:21 -0500 |
commit | 0eb5db7ad302a24fe6f0eb4bfd235357047a28db (patch) | |
tree | 70ab0a2618925c66700ed7f7e47fe70793c550b4 | |
parent | 3e90ebd3c920e335e155e5d3a794197897630f99 (diff) |
netfilter: nfnetlink: add rcu_dereference_protected() helpers
Add a lockdep_nfnl_is_held() function and a nfnl_dereference() macro for
RCU dereferences protected by a NFNL subsystem mutex.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | include/linux/netfilter/nfnetlink.h | 21 | ||||
-rw-r--r-- | net/netfilter/nfnetlink.c | 8 |
2 files changed, 29 insertions, 0 deletions
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 28c74367e900..e955d4730625 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h | |||
@@ -44,6 +44,27 @@ int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u32 portid, | |||
44 | 44 | ||
45 | void nfnl_lock(__u8 subsys_id); | 45 | void nfnl_lock(__u8 subsys_id); |
46 | void nfnl_unlock(__u8 subsys_id); | 46 | void nfnl_unlock(__u8 subsys_id); |
47 | #ifdef CONFIG_PROVE_LOCKING | ||
48 | int lockdep_nfnl_is_held(__u8 subsys_id); | ||
49 | #else | ||
50 | static inline int lockdep_nfnl_is_held(__u8 subsys_id) | ||
51 | { | ||
52 | return 1; | ||
53 | } | ||
54 | #endif /* CONFIG_PROVE_LOCKING */ | ||
55 | |||
56 | /* | ||
57 | * nfnl_dereference - fetch RCU pointer when updates are prevented by subsys mutex | ||
58 | * | ||
59 | * @p: The pointer to read, prior to dereferencing | ||
60 | * @ss: The nfnetlink subsystem ID | ||
61 | * | ||
62 | * Return the value of the specified RCU-protected pointer, but omit | ||
63 | * both the smp_read_barrier_depends() and the ACCESS_ONCE(), because | ||
64 | * caller holds the NFNL subsystem mutex. | ||
65 | */ | ||
66 | #define nfnl_dereference(p, ss) \ | ||
67 | rcu_dereference_protected(p, lockdep_nfnl_is_held(ss)) | ||
47 | 68 | ||
48 | #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \ | 69 | #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \ |
49 | MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys)) | 70 | MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys)) |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 046aa13b4fea..e8138da4c14f 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -61,6 +61,14 @@ void nfnl_unlock(__u8 subsys_id) | |||
61 | } | 61 | } |
62 | EXPORT_SYMBOL_GPL(nfnl_unlock); | 62 | EXPORT_SYMBOL_GPL(nfnl_unlock); |
63 | 63 | ||
64 | #ifdef CONFIG_PROVE_LOCKING | ||
65 | int lockdep_nfnl_is_held(u8 subsys_id) | ||
66 | { | ||
67 | return lockdep_is_held(&table[subsys_id].mutex); | ||
68 | } | ||
69 | EXPORT_SYMBOL_GPL(lockdep_nfnl_is_held); | ||
70 | #endif | ||
71 | |||
64 | int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n) | 72 | int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n) |
65 | { | 73 | { |
66 | nfnl_lock(n->subsys_id); | 74 | nfnl_lock(n->subsys_id); |