diff options
author | Marek Lindner <lindner_marek@yahoo.de> | 2011-01-19 15:01:40 -0500 |
---|---|---|
committer | Marek Lindner <lindner_marek@yahoo.de> | 2011-03-05 06:49:58 -0500 |
commit | fb778ea173fcd58b8fc3d75c674f07fab187b55f (patch) | |
tree | b14cfc99b7ca61ddcb49cc56c9a8e2822675debc /net/batman-adv/hash.c | |
parent | a775eb847ae66211577d4fd2c46749b77c9993c9 (diff) |
batman-adv: protect each hash row with rcu locks
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv/hash.c')
-rw-r--r-- | net/batman-adv/hash.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c index fa2693973ab8..02653666a26b 100644 --- a/net/batman-adv/hash.c +++ b/net/batman-adv/hash.c | |||
@@ -27,13 +27,16 @@ static void hash_init(struct hashtable_t *hash) | |||
27 | { | 27 | { |
28 | int i; | 28 | int i; |
29 | 29 | ||
30 | for (i = 0 ; i < hash->size; i++) | 30 | for (i = 0 ; i < hash->size; i++) { |
31 | INIT_HLIST_HEAD(&hash->table[i]); | 31 | INIT_HLIST_HEAD(&hash->table[i]); |
32 | spin_lock_init(&hash->list_locks[i]); | ||
33 | } | ||
32 | } | 34 | } |
33 | 35 | ||
34 | /* free only the hashtable and the hash itself. */ | 36 | /* free only the hashtable and the hash itself. */ |
35 | void hash_destroy(struct hashtable_t *hash) | 37 | void hash_destroy(struct hashtable_t *hash) |
36 | { | 38 | { |
39 | kfree(hash->list_locks); | ||
37 | kfree(hash->table); | 40 | kfree(hash->table); |
38 | kfree(hash); | 41 | kfree(hash); |
39 | } | 42 | } |
@@ -43,20 +46,33 @@ struct hashtable_t *hash_new(int size) | |||
43 | { | 46 | { |
44 | struct hashtable_t *hash; | 47 | struct hashtable_t *hash; |
45 | 48 | ||
46 | hash = kmalloc(sizeof(struct hashtable_t) , GFP_ATOMIC); | 49 | hash = kmalloc(sizeof(struct hashtable_t), GFP_ATOMIC); |
47 | |||
48 | if (!hash) | 50 | if (!hash) |
49 | return NULL; | 51 | return NULL; |
50 | 52 | ||
51 | hash->size = size; | ||
52 | hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC); | 53 | hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC); |
54 | if (!hash->table) | ||
55 | goto free_hash; | ||
53 | 56 | ||
54 | if (!hash->table) { | 57 | hash->list_locks = kmalloc(sizeof(spinlock_t) * size, GFP_ATOMIC); |
55 | kfree(hash); | 58 | if (!hash->list_locks) |
56 | return NULL; | 59 | goto free_table; |
57 | } | ||
58 | 60 | ||
61 | hash->size = size; | ||
59 | hash_init(hash); | 62 | hash_init(hash); |
60 | |||
61 | return hash; | 63 | return hash; |
64 | |||
65 | free_table: | ||
66 | kfree(hash->table); | ||
67 | free_hash: | ||
68 | kfree(hash); | ||
69 | return NULL; | ||
70 | } | ||
71 | |||
72 | void bucket_free_rcu(struct rcu_head *rcu) | ||
73 | { | ||
74 | struct element_t *bucket; | ||
75 | |||
76 | bucket = container_of(rcu, struct element_t, rcu); | ||
77 | kfree(bucket); | ||
62 | } | 78 | } |