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); |
