aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-11-13 15:13:13 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-13 15:13:13 -0500
commit9cf5476bfda3c2f1d5712d7bf09b3dad91fc2f2d (patch)
tree9e5d9d20cf30672d2db081a0de8604ad47680e49
parent9488e1e5b319751c71eebfd49027bf9e2377f38c (diff)
parent7b4ce2353467fdab6e003be7a3129fb09b09deac (diff)
Merge branch 'rhash_prove_locking'
Herbert Xu says: ==================== rhashtable: Allow local locks to be used and tested This series moves mutex_is_held entirely under PROVE_LOCKING so there is zero foot print when we're not debugging. More importantly it adds a parrent argument to mutex_is_held so that we can test local locks rather than global ones (e.g., per-namespace locks). ==================== Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/rhashtable.h5
-rw-r--r--lib/rhashtable.c12
-rw-r--r--net/netfilter/nft_hash.c6
-rw-r--r--net/netlink/af_netlink.c8
4 files changed, 24 insertions, 7 deletions
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index fb298e9d6d3a..473e26bdb91d 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -65,7 +65,10 @@ struct rhashtable_params {
65 size_t new_size); 65 size_t new_size);
66 bool (*shrink_decision)(const struct rhashtable *ht, 66 bool (*shrink_decision)(const struct rhashtable *ht,
67 size_t new_size); 67 size_t new_size);
68 int (*mutex_is_held)(void); 68#ifdef CONFIG_PROVE_LOCKING
69 int (*mutex_is_held)(void *parent);
70 void *parent;
71#endif
69}; 72};
70 73
71/** 74/**
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 081be3ba9ea8..4b4b53bfa08b 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -32,7 +32,7 @@
32#ifdef CONFIG_PROVE_LOCKING 32#ifdef CONFIG_PROVE_LOCKING
33int lockdep_rht_mutex_is_held(const struct rhashtable *ht) 33int lockdep_rht_mutex_is_held(const struct rhashtable *ht)
34{ 34{
35 return ht->p.mutex_is_held(); 35 return ht->p.mutex_is_held(ht->p.parent);
36} 36}
37EXPORT_SYMBOL_GPL(lockdep_rht_mutex_is_held); 37EXPORT_SYMBOL_GPL(lockdep_rht_mutex_is_held);
38#endif 38#endif
@@ -532,7 +532,9 @@ static size_t rounded_hashtable_size(struct rhashtable_params *params)
532 * .key_offset = offsetof(struct test_obj, key), 532 * .key_offset = offsetof(struct test_obj, key),
533 * .key_len = sizeof(int), 533 * .key_len = sizeof(int),
534 * .hashfn = arch_fast_hash, 534 * .hashfn = arch_fast_hash,
535 * #ifdef CONFIG_PROVE_LOCKING
535 * .mutex_is_held = &my_mutex_is_held, 536 * .mutex_is_held = &my_mutex_is_held,
537 * #endif
536 * }; 538 * };
537 * 539 *
538 * Configuration Example 2: Variable length keys 540 * Configuration Example 2: Variable length keys
@@ -552,7 +554,9 @@ static size_t rounded_hashtable_size(struct rhashtable_params *params)
552 * .head_offset = offsetof(struct test_obj, node), 554 * .head_offset = offsetof(struct test_obj, node),
553 * .hashfn = arch_fast_hash, 555 * .hashfn = arch_fast_hash,
554 * .obj_hashfn = my_hash_fn, 556 * .obj_hashfn = my_hash_fn,
557 * #ifdef CONFIG_PROVE_LOCKING
555 * .mutex_is_held = &my_mutex_is_held, 558 * .mutex_is_held = &my_mutex_is_held,
559 * #endif
556 * }; 560 * };
557 */ 561 */
558int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params) 562int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params)
@@ -613,10 +617,12 @@ EXPORT_SYMBOL_GPL(rhashtable_destroy);
613#define TEST_PTR ((void *) 0xdeadbeef) 617#define TEST_PTR ((void *) 0xdeadbeef)
614#define TEST_NEXPANDS 4 618#define TEST_NEXPANDS 4
615 619
616static int test_mutex_is_held(void) 620#ifdef CONFIG_PROVE_LOCKING
621static int test_mutex_is_held(void *parent)
617{ 622{
618 return 1; 623 return 1;
619} 624}
625#endif
620 626
621struct test_obj { 627struct test_obj {
622 void *ptr; 628 void *ptr;
@@ -767,7 +773,9 @@ static int __init test_rht_init(void)
767 .key_offset = offsetof(struct test_obj, value), 773 .key_offset = offsetof(struct test_obj, value),
768 .key_len = sizeof(int), 774 .key_len = sizeof(int),
769 .hashfn = arch_fast_hash, 775 .hashfn = arch_fast_hash,
776#ifdef CONFIG_PROVE_LOCKING
770 .mutex_is_held = &test_mutex_is_held, 777 .mutex_is_held = &test_mutex_is_held,
778#endif
771 .grow_decision = rht_grow_above_75, 779 .grow_decision = rht_grow_above_75,
772 .shrink_decision = rht_shrink_below_30, 780 .shrink_decision = rht_shrink_below_30,
773 }; 781 };
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 8892b7b6184a..3f75aaaf9d06 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -153,10 +153,12 @@ static unsigned int nft_hash_privsize(const struct nlattr * const nla[])
153 return sizeof(struct rhashtable); 153 return sizeof(struct rhashtable);
154} 154}
155 155
156static int lockdep_nfnl_lock_is_held(void) 156#ifdef CONFIG_PROVE_LOCKING
157static int lockdep_nfnl_lock_is_held(void *parent)
157{ 158{
158 return lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES); 159 return lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES);
159} 160}
161#endif
160 162
161static int nft_hash_init(const struct nft_set *set, 163static int nft_hash_init(const struct nft_set *set,
162 const struct nft_set_desc *desc, 164 const struct nft_set_desc *desc,
@@ -171,7 +173,9 @@ static int nft_hash_init(const struct nft_set *set,
171 .hashfn = jhash, 173 .hashfn = jhash,
172 .grow_decision = rht_grow_above_75, 174 .grow_decision = rht_grow_above_75,
173 .shrink_decision = rht_shrink_below_30, 175 .shrink_decision = rht_shrink_below_30,
176#ifdef CONFIG_PROVE_LOCKING
174 .mutex_is_held = lockdep_nfnl_lock_is_held, 177 .mutex_is_held = lockdep_nfnl_lock_is_held,
178#endif
175 }; 179 };
176 180
177 return rhashtable_init(priv, &params); 181 return rhashtable_init(priv, &params);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 580b79452bec..9e0628cfdf67 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -114,14 +114,14 @@ static atomic_t nl_table_users = ATOMIC_INIT(0);
114DEFINE_MUTEX(nl_sk_hash_lock); 114DEFINE_MUTEX(nl_sk_hash_lock);
115EXPORT_SYMBOL_GPL(nl_sk_hash_lock); 115EXPORT_SYMBOL_GPL(nl_sk_hash_lock);
116 116
117static int lockdep_nl_sk_hash_is_held(void) 117#ifdef CONFIG_PROVE_LOCKING
118static int lockdep_nl_sk_hash_is_held(void *parent)
118{ 119{
119#ifdef CONFIG_LOCKDEP
120 if (debug_locks) 120 if (debug_locks)
121 return lockdep_is_held(&nl_sk_hash_lock) || lockdep_is_held(&nl_table_lock); 121 return lockdep_is_held(&nl_sk_hash_lock) || lockdep_is_held(&nl_table_lock);
122#endif
123 return 1; 122 return 1;
124} 123}
124#endif
125 125
126static ATOMIC_NOTIFIER_HEAD(netlink_chain); 126static ATOMIC_NOTIFIER_HEAD(netlink_chain);
127 127
@@ -3133,7 +3133,9 @@ static int __init netlink_proto_init(void)
3133 .max_shift = 16, /* 64K */ 3133 .max_shift = 16, /* 64K */
3134 .grow_decision = rht_grow_above_75, 3134 .grow_decision = rht_grow_above_75,
3135 .shrink_decision = rht_shrink_below_30, 3135 .shrink_decision = rht_shrink_below_30,
3136#ifdef CONFIG_PROVE_LOCKING
3136 .mutex_is_held = lockdep_nl_sk_hash_is_held, 3137 .mutex_is_held = lockdep_nl_sk_hash_is_held,
3138#endif
3137 }; 3139 };
3138 3140
3139 if (err != 0) 3141 if (err != 0)