1 /* Copyright (C) 2006-2012 B.A.T.M.A.N. contributors: 2 * 3 * Simon Wunderlich, Marek Lindner 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of version 2 of the GNU General Public 7 * License as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * 02110-1301, USA 18 */ 19 20 #include "main.h" 21 #include "hash.h" 22 23 /* clears the hash */ 24 static void batadv_hash_init(struct batadv_hashtable *hash) 25 { 26 uint32_t i; 27 28 for (i = 0; i < hash->size; i++) { 29 INIT_HLIST_HEAD(&hash->table[i]); 30 spin_lock_init(&hash->list_locks[i]); 31 } 32 } 33 34 /* free only the hashtable and the hash itself. */ 35 void batadv_hash_destroy(struct batadv_hashtable *hash) 36 { 37 kfree(hash->list_locks); 38 kfree(hash->table); 39 kfree(hash); 40 } 41 42 /* allocates and clears the hash */ 43 struct batadv_hashtable *batadv_hash_new(uint32_t size) 44 { 45 struct batadv_hashtable *hash; 46 47 hash = kmalloc(sizeof(*hash), GFP_ATOMIC); 48 if (!hash) 49 return NULL; 50 51 hash->table = kmalloc(sizeof(*hash->table) * size, GFP_ATOMIC); 52 if (!hash->table) 53 goto free_hash; 54 55 hash->list_locks = kmalloc(sizeof(*hash->list_locks) * size, 56 GFP_ATOMIC); 57 if (!hash->list_locks) 58 goto free_table; 59 60 hash->size = size; 61 batadv_hash_init(hash); 62 return hash; 63 64 free_table: 65 kfree(hash->table); 66 free_hash: 67 kfree(hash); 68 return NULL; 69 } 70 71 void batadv_hash_set_lock_class(struct batadv_hashtable *hash, 72 struct lock_class_key *key) 73 { 74 uint32_t i; 75 76 for (i = 0; i < hash->size; i++) 77 lockdep_set_class(&hash->list_locks[i], key); 78 } 79