hash.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. #include "hash.h"
  19. #include "main.h"
  20. #include <linux/gfp.h>
  21. #include <linux/lockdep.h>
  22. #include <linux/slab.h>
  23. /* clears the hash */
  24. static void batadv_hash_init(struct batadv_hashtable *hash)
  25. {
  26. u32 i;
  27. for (i = 0; i < hash->size; i++) {
  28. INIT_HLIST_HEAD(&hash->table[i]);
  29. spin_lock_init(&hash->list_locks[i]);
  30. }
  31. }
  32. /**
  33. * batadv_hash_destroy() - Free only the hashtable and the hash itself
  34. * @hash: hash object to destroy
  35. */
  36. void batadv_hash_destroy(struct batadv_hashtable *hash)
  37. {
  38. kfree(hash->list_locks);
  39. kfree(hash->table);
  40. kfree(hash);
  41. }
  42. /**
  43. * batadv_hash_new() - Allocates and clears the hashtable
  44. * @size: number of hash buckets to allocate
  45. *
  46. * Return: newly allocated hashtable, NULL on errors
  47. */
  48. struct batadv_hashtable *batadv_hash_new(u32 size)
  49. {
  50. struct batadv_hashtable *hash;
  51. hash = kmalloc(sizeof(*hash), GFP_ATOMIC);
  52. if (!hash)
  53. return NULL;
  54. hash->table = kmalloc_array(size, sizeof(*hash->table), GFP_ATOMIC);
  55. if (!hash->table)
  56. goto free_hash;
  57. hash->list_locks = kmalloc_array(size, sizeof(*hash->list_locks),
  58. GFP_ATOMIC);
  59. if (!hash->list_locks)
  60. goto free_table;
  61. hash->size = size;
  62. batadv_hash_init(hash);
  63. return hash;
  64. free_table:
  65. kfree(hash->table);
  66. free_hash:
  67. kfree(hash);
  68. return NULL;
  69. }
  70. /**
  71. * batadv_hash_set_lock_class() - Set specific lockdep class for hash spinlocks
  72. * @hash: hash object to modify
  73. * @key: lockdep class key address
  74. */
  75. void batadv_hash_set_lock_class(struct batadv_hashtable *hash,
  76. struct lock_class_key *key)
  77. {
  78. u32 i;
  79. for (i = 0; i < hash->size; i++)
  80. lockdep_set_class(&hash->list_locks[i], key);
  81. }