1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2006-2018 B.A.T.M.A.N. contributors: 3 * 4 * Simon Wunderlich, Marek Lindner 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of version 2 of the GNU General Public 8 * License as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include "hash.h" 20 #include "main.h" 21 22 #include <linux/gfp.h> 23 #include <linux/lockdep.h> 24 #include <linux/slab.h> 25 26 /* clears the hash */ 27 static void batadv_hash_init(struct batadv_hashtable *hash) 28 { 29 u32 i; 30 31 for (i = 0; i < hash->size; i++) { 32 INIT_HLIST_HEAD(&hash->table[i]); 33 spin_lock_init(&hash->list_locks[i]); 34 } 35 } 36 37 /** 38 * batadv_hash_destroy() - Free only the hashtable and the hash itself 39 * @hash: hash object to destroy 40 */ 41 void batadv_hash_destroy(struct batadv_hashtable *hash) 42 { 43 kfree(hash->list_locks); 44 kfree(hash->table); 45 kfree(hash); 46 } 47 48 /** 49 * batadv_hash_new() - Allocates and clears the hashtable 50 * @size: number of hash buckets to allocate 51 * 52 * Return: newly allocated hashtable, NULL on errors 53 */ 54 struct batadv_hashtable *batadv_hash_new(u32 size) 55 { 56 struct batadv_hashtable *hash; 57 58 hash = kmalloc(sizeof(*hash), GFP_ATOMIC); 59 if (!hash) 60 return NULL; 61 62 hash->table = kmalloc_array(size, sizeof(*hash->table), GFP_ATOMIC); 63 if (!hash->table) 64 goto free_hash; 65 66 hash->list_locks = kmalloc_array(size, sizeof(*hash->list_locks), 67 GFP_ATOMIC); 68 if (!hash->list_locks) 69 goto free_table; 70 71 hash->size = size; 72 batadv_hash_init(hash); 73 return hash; 74 75 free_table: 76 kfree(hash->table); 77 free_hash: 78 kfree(hash); 79 return NULL; 80 } 81 82 /** 83 * batadv_hash_set_lock_class() - Set specific lockdep class for hash spinlocks 84 * @hash: hash object to modify 85 * @key: lockdep class key address 86 */ 87 void batadv_hash_set_lock_class(struct batadv_hashtable *hash, 88 struct lock_class_key *key) 89 { 90 u32 i; 91 92 for (i = 0; i < hash->size; i++) 93 lockdep_set_class(&hash->list_locks[i], key); 94 } 95