hash.c (1759B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (C) B.A.T.M.A.N. contributors: 3 * 4 * Simon Wunderlich, Marek Lindner 5 */ 6 7#include "hash.h" 8#include "main.h" 9 10#include <linux/gfp.h> 11#include <linux/lockdep.h> 12#include <linux/slab.h> 13 14/* clears the hash */ 15static void batadv_hash_init(struct batadv_hashtable *hash) 16{ 17 u32 i; 18 19 for (i = 0; i < hash->size; i++) { 20 INIT_HLIST_HEAD(&hash->table[i]); 21 spin_lock_init(&hash->list_locks[i]); 22 } 23 24 atomic_set(&hash->generation, 0); 25} 26 27/** 28 * batadv_hash_destroy() - Free only the hashtable and the hash itself 29 * @hash: hash object to destroy 30 */ 31void batadv_hash_destroy(struct batadv_hashtable *hash) 32{ 33 kfree(hash->list_locks); 34 kfree(hash->table); 35 kfree(hash); 36} 37 38/** 39 * batadv_hash_new() - Allocates and clears the hashtable 40 * @size: number of hash buckets to allocate 41 * 42 * Return: newly allocated hashtable, NULL on errors 43 */ 44struct batadv_hashtable *batadv_hash_new(u32 size) 45{ 46 struct batadv_hashtable *hash; 47 48 hash = kmalloc(sizeof(*hash), GFP_ATOMIC); 49 if (!hash) 50 return NULL; 51 52 hash->table = kmalloc_array(size, sizeof(*hash->table), GFP_ATOMIC); 53 if (!hash->table) 54 goto free_hash; 55 56 hash->list_locks = kmalloc_array(size, sizeof(*hash->list_locks), 57 GFP_ATOMIC); 58 if (!hash->list_locks) 59 goto free_table; 60 61 hash->size = size; 62 batadv_hash_init(hash); 63 return hash; 64 65free_table: 66 kfree(hash->table); 67free_hash: 68 kfree(hash); 69 return NULL; 70} 71 72/** 73 * batadv_hash_set_lock_class() - Set specific lockdep class for hash spinlocks 74 * @hash: hash object to modify 75 * @key: lockdep class key address 76 */ 77void batadv_hash_set_lock_class(struct batadv_hashtable *hash, 78 struct lock_class_key *key) 79{ 80 u32 i; 81 82 for (i = 0; i < hash->size; i++) 83 lockdep_set_class(&hash->list_locks[i], key); 84}