1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2006-2019 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 atomic_set(&hash->generation, 0); 37 } 38 39 /** 40 * batadv_hash_destroy() - Free only the hashtable and the hash itself 41 * @hash: hash object to destroy 42 */ 43 void batadv_hash_destroy(struct batadv_hashtable *hash) 44 { 45 kfree(hash->list_locks); 46 kfree(hash->table); 47 kfree(hash); 48 } 49 50 /** 51 * batadv_hash_new() - Allocates and clears the hashtable 52 * @size: number of hash buckets to allocate 53 * 54 * Return: newly allocated hashtable, NULL on errors 55 */ 56 struct batadv_hashtable *batadv_hash_new(u32 size) 57 { 58 struct batadv_hashtable *hash; 59 60 hash = kmalloc(sizeof(*hash), GFP_ATOMIC); 61 if (!hash) 62 return NULL; 63 64 hash->table = kmalloc_array(size, sizeof(*hash->table), GFP_ATOMIC); 65 if (!hash->table) 66 goto free_hash; 67 68 hash->list_locks = kmalloc_array(size, sizeof(*hash->list_locks), 69 GFP_ATOMIC); 70 if (!hash->list_locks) 71 goto free_table; 72 73 hash->size = size; 74 batadv_hash_init(hash); 75 return hash; 76 77 free_table: 78 kfree(hash->table); 79 free_hash: 80 kfree(hash); 81 return NULL; 82 } 83 84 /** 85 * batadv_hash_set_lock_class() - Set specific lockdep class for hash spinlocks 86 * @hash: hash object to modify 87 * @key: lockdep class key address 88 */ 89 void batadv_hash_set_lock_class(struct batadv_hashtable *hash, 90 struct lock_class_key *key) 91 { 92 u32 i; 93 94 for (i = 0; i < hash->size; i++) 95 lockdep_set_class(&hash->list_locks[i], key); 96 } 97