batman-adv: protect each hash row with rcu locks
[deliverable/linux.git] / net / batman-adv / hash.c
index fa2693973ab8769c0bd57f828f8eea93d34d6ed3..02653666a26bee9776b96517a28c77cadfe9419a 100644 (file)
@@ -27,13 +27,16 @@ static void hash_init(struct hashtable_t *hash)
 {
        int i;
 
-       for (i = 0 ; i < hash->size; i++)
+       for (i = 0 ; i < hash->size; i++) {
                INIT_HLIST_HEAD(&hash->table[i]);
+               spin_lock_init(&hash->list_locks[i]);
+       }
 }
 
 /* free only the hashtable and the hash itself. */
 void hash_destroy(struct hashtable_t *hash)
 {
+       kfree(hash->list_locks);
        kfree(hash->table);
        kfree(hash);
 }
@@ -43,20 +46,33 @@ struct hashtable_t *hash_new(int size)
 {
        struct hashtable_t *hash;
 
-       hash = kmalloc(sizeof(struct hashtable_t) , GFP_ATOMIC);
-
+       hash = kmalloc(sizeof(struct hashtable_t), GFP_ATOMIC);
        if (!hash)
                return NULL;
 
-       hash->size = size;
        hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC);
+       if (!hash->table)
+               goto free_hash;
 
-       if (!hash->table) {
-               kfree(hash);
-               return NULL;
-       }
+       hash->list_locks = kmalloc(sizeof(spinlock_t) * size, GFP_ATOMIC);
+       if (!hash->list_locks)
+               goto free_table;
 
+       hash->size = size;
        hash_init(hash);
-
        return hash;
+
+free_table:
+       kfree(hash->table);
+free_hash:
+       kfree(hash);
+       return NULL;
+}
+
+void bucket_free_rcu(struct rcu_head *rcu)
+{
+       struct element_t *bucket;
+
+       bucket = container_of(rcu, struct element_t, rcu);
+       kfree(bucket);
 }
This page took 0.026664 seconds and 5 git commands to generate.