aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/hash.c
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2011-01-19 15:01:40 -0500
committerMarek Lindner <lindner_marek@yahoo.de>2011-03-05 06:49:58 -0500
commitfb778ea173fcd58b8fc3d75c674f07fab187b55f (patch)
treeb14cfc99b7ca61ddcb49cc56c9a8e2822675debc /net/batman-adv/hash.c
parenta775eb847ae66211577d4fd2c46749b77c9993c9 (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.c34
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. */
35void hash_destroy(struct hashtable_t *hash) 37void 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
65free_table:
66 kfree(hash->table);
67free_hash:
68 kfree(hash);
69 return NULL;
70}
71
72void 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}