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>
This commit is contained in:
David S. Miller 2014-11-13 15:13:13 -05:00
commit 9cf5476bfd
4 changed files with 24 additions and 7 deletions

View File

@ -65,7 +65,10 @@ struct rhashtable_params {
size_t new_size); size_t new_size);
bool (*shrink_decision)(const struct rhashtable *ht, bool (*shrink_decision)(const struct rhashtable *ht,
size_t new_size); size_t new_size);
int (*mutex_is_held)(void); #ifdef CONFIG_PROVE_LOCKING
int (*mutex_is_held)(void *parent);
void *parent;
#endif
}; };
/** /**

View File

@ -32,7 +32,7 @@
#ifdef CONFIG_PROVE_LOCKING #ifdef CONFIG_PROVE_LOCKING
int lockdep_rht_mutex_is_held(const struct rhashtable *ht) int lockdep_rht_mutex_is_held(const struct rhashtable *ht)
{ {
return ht->p.mutex_is_held(); return ht->p.mutex_is_held(ht->p.parent);
} }
EXPORT_SYMBOL_GPL(lockdep_rht_mutex_is_held); EXPORT_SYMBOL_GPL(lockdep_rht_mutex_is_held);
#endif #endif
@ -532,7 +532,9 @@ static size_t rounded_hashtable_size(struct rhashtable_params *params)
* .key_offset = offsetof(struct test_obj, key), * .key_offset = offsetof(struct test_obj, key),
* .key_len = sizeof(int), * .key_len = sizeof(int),
* .hashfn = arch_fast_hash, * .hashfn = arch_fast_hash,
* #ifdef CONFIG_PROVE_LOCKING
* .mutex_is_held = &my_mutex_is_held, * .mutex_is_held = &my_mutex_is_held,
* #endif
* }; * };
* *
* Configuration Example 2: Variable length keys * Configuration Example 2: Variable length keys
@ -552,7 +554,9 @@ static size_t rounded_hashtable_size(struct rhashtable_params *params)
* .head_offset = offsetof(struct test_obj, node), * .head_offset = offsetof(struct test_obj, node),
* .hashfn = arch_fast_hash, * .hashfn = arch_fast_hash,
* .obj_hashfn = my_hash_fn, * .obj_hashfn = my_hash_fn,
* #ifdef CONFIG_PROVE_LOCKING
* .mutex_is_held = &my_mutex_is_held, * .mutex_is_held = &my_mutex_is_held,
* #endif
* }; * };
*/ */
int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params) int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params)
@ -613,10 +617,12 @@ EXPORT_SYMBOL_GPL(rhashtable_destroy);
#define TEST_PTR ((void *) 0xdeadbeef) #define TEST_PTR ((void *) 0xdeadbeef)
#define TEST_NEXPANDS 4 #define TEST_NEXPANDS 4
static int test_mutex_is_held(void) #ifdef CONFIG_PROVE_LOCKING
static int test_mutex_is_held(void *parent)
{ {
return 1; return 1;
} }
#endif
struct test_obj { struct test_obj {
void *ptr; void *ptr;
@ -767,7 +773,9 @@ static int __init test_rht_init(void)
.key_offset = offsetof(struct test_obj, value), .key_offset = offsetof(struct test_obj, value),
.key_len = sizeof(int), .key_len = sizeof(int),
.hashfn = arch_fast_hash, .hashfn = arch_fast_hash,
#ifdef CONFIG_PROVE_LOCKING
.mutex_is_held = &test_mutex_is_held, .mutex_is_held = &test_mutex_is_held,
#endif
.grow_decision = rht_grow_above_75, .grow_decision = rht_grow_above_75,
.shrink_decision = rht_shrink_below_30, .shrink_decision = rht_shrink_below_30,
}; };

View File

@ -153,10 +153,12 @@ static unsigned int nft_hash_privsize(const struct nlattr * const nla[])
return sizeof(struct rhashtable); return sizeof(struct rhashtable);
} }
static int lockdep_nfnl_lock_is_held(void) #ifdef CONFIG_PROVE_LOCKING
static int lockdep_nfnl_lock_is_held(void *parent)
{ {
return lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES); return lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES);
} }
#endif
static int nft_hash_init(const struct nft_set *set, static int nft_hash_init(const struct nft_set *set,
const struct nft_set_desc *desc, const struct nft_set_desc *desc,
@ -171,7 +173,9 @@ static int nft_hash_init(const struct nft_set *set,
.hashfn = jhash, .hashfn = jhash,
.grow_decision = rht_grow_above_75, .grow_decision = rht_grow_above_75,
.shrink_decision = rht_shrink_below_30, .shrink_decision = rht_shrink_below_30,
#ifdef CONFIG_PROVE_LOCKING
.mutex_is_held = lockdep_nfnl_lock_is_held, .mutex_is_held = lockdep_nfnl_lock_is_held,
#endif
}; };
return rhashtable_init(priv, &params); return rhashtable_init(priv, &params);

View File

@ -114,14 +114,14 @@ static atomic_t nl_table_users = ATOMIC_INIT(0);
DEFINE_MUTEX(nl_sk_hash_lock); DEFINE_MUTEX(nl_sk_hash_lock);
EXPORT_SYMBOL_GPL(nl_sk_hash_lock); EXPORT_SYMBOL_GPL(nl_sk_hash_lock);
static int lockdep_nl_sk_hash_is_held(void) #ifdef CONFIG_PROVE_LOCKING
static int lockdep_nl_sk_hash_is_held(void *parent)
{ {
#ifdef CONFIG_LOCKDEP
if (debug_locks) if (debug_locks)
return lockdep_is_held(&nl_sk_hash_lock) || lockdep_is_held(&nl_table_lock); return lockdep_is_held(&nl_sk_hash_lock) || lockdep_is_held(&nl_table_lock);
#endif
return 1; return 1;
} }
#endif
static ATOMIC_NOTIFIER_HEAD(netlink_chain); static ATOMIC_NOTIFIER_HEAD(netlink_chain);
@ -3133,7 +3133,9 @@ static int __init netlink_proto_init(void)
.max_shift = 16, /* 64K */ .max_shift = 16, /* 64K */
.grow_decision = rht_grow_above_75, .grow_decision = rht_grow_above_75,
.shrink_decision = rht_shrink_below_30, .shrink_decision = rht_shrink_below_30,
#ifdef CONFIG_PROVE_LOCKING
.mutex_is_held = lockdep_nl_sk_hash_is_held, .mutex_is_held = lockdep_nl_sk_hash_is_held,
#endif
}; };
if (err != 0) if (err != 0)