2017-11-19 17:05:11 +03:00
// SPDX-License-Identifier: GPL-2.0
2021-01-01 02:00:01 +03:00
/* Copyright (C) B.A.T.M.A.N. contributors:
2010-12-13 14:19:28 +03:00
*
* Simon Wunderlich , Marek Lindner
*/
# include "hash.h"
2015-04-17 20:40:28 +03:00
# include "main.h"
2017-11-19 19:12:02 +03:00
# include <linux/gfp.h>
2015-04-17 20:40:28 +03:00
# include <linux/lockdep.h>
# include <linux/slab.h>
2010-12-13 14:19:28 +03:00
/* clears the hash */
2012-06-06 00:31:28 +04:00
static void batadv_hash_init ( struct batadv_hashtable * hash )
2010-12-13 14:19:28 +03:00
{
2015-05-26 19:34:26 +03:00
u32 i ;
2010-12-13 14:19:28 +03:00
2012-06-17 18:27:22 +04:00
for ( i = 0 ; i < hash - > size ; i + + ) {
2010-12-13 14:19:28 +03:00
INIT_HLIST_HEAD ( & hash - > table [ i ] ) ;
2011-01-19 23:01:40 +03:00
spin_lock_init ( & hash - > list_locks [ i ] ) ;
}
2018-10-31 00:01:25 +03:00
atomic_set ( & hash - > generation , 0 ) ;
2010-12-13 14:19:28 +03:00
}
2017-12-02 21:51:53 +03:00
/**
* batadv_hash_destroy ( ) - Free only the hashtable and the hash itself
* @ hash : hash object to destroy
*/
2012-06-06 00:31:28 +04:00
void batadv_hash_destroy ( struct batadv_hashtable * hash )
2010-12-13 14:19:28 +03:00
{
2011-01-19 23:01:40 +03:00
kfree ( hash - > list_locks ) ;
2010-12-13 14:19:28 +03:00
kfree ( hash - > table ) ;
kfree ( hash ) ;
}
2017-12-02 21:51:53 +03:00
/**
* batadv_hash_new ( ) - Allocates and clears the hashtable
* @ size : number of hash buckets to allocate
*
* Return : newly allocated hashtable , NULL on errors
*/
2015-05-26 19:34:26 +03:00
struct batadv_hashtable * batadv_hash_new ( u32 size )
2010-12-13 14:19:28 +03:00
{
2012-06-06 00:31:28 +04:00
struct batadv_hashtable * hash ;
2010-12-13 14:19:28 +03:00
2011-05-15 01:14:54 +04:00
hash = kmalloc ( sizeof ( * hash ) , GFP_ATOMIC ) ;
2010-12-13 14:19:28 +03:00
if ( ! hash )
return NULL ;
2014-05-24 08:43:47 +04:00
hash - > table = kmalloc_array ( size , sizeof ( * hash - > table ) , GFP_ATOMIC ) ;
2011-01-19 23:01:40 +03:00
if ( ! hash - > table )
goto free_hash ;
2010-12-13 14:19:28 +03:00
2014-05-24 08:43:47 +04:00
hash - > list_locks = kmalloc_array ( size , sizeof ( * hash - > list_locks ) ,
GFP_ATOMIC ) ;
2011-01-19 23:01:40 +03:00
if ( ! hash - > list_locks )
goto free_table ;
2010-12-13 14:19:28 +03:00
2011-01-19 23:01:40 +03:00
hash - > size = size ;
2012-05-12 20:33:58 +04:00
batadv_hash_init ( hash ) ;
2010-12-13 14:19:28 +03:00
return hash ;
2011-01-19 23:01:40 +03:00
free_table :
kfree ( hash - > table ) ;
free_hash :
kfree ( hash ) ;
return NULL ;
}
2012-03-29 14:38:20 +04:00
2017-12-02 21:51:53 +03:00
/**
* batadv_hash_set_lock_class ( ) - Set specific lockdep class for hash spinlocks
* @ hash : hash object to modify
* @ key : lockdep class key address
*/
2012-06-06 00:31:28 +04:00
void batadv_hash_set_lock_class ( struct batadv_hashtable * hash ,
2012-03-29 14:38:20 +04:00
struct lock_class_key * key )
{
2015-05-26 19:34:26 +03:00
u32 i ;
2012-03-29 14:38:20 +04:00
for ( i = 0 ; i < hash - > size ; i + + )
lockdep_set_class ( & hash - > list_locks [ i ] , key ) ;
}