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