diff options
Diffstat (limited to 'include/linux/rhashtable.h')
-rw-r--r-- | include/linux/rhashtable.h | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index dbcbcc59aa92..843ceca9a21e 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #ifndef _LINUX_RHASHTABLE_H | 17 | #ifndef _LINUX_RHASHTABLE_H |
18 | #define _LINUX_RHASHTABLE_H | 18 | #define _LINUX_RHASHTABLE_H |
19 | 19 | ||
20 | #include <linux/atomic.h> | ||
20 | #include <linux/compiler.h> | 21 | #include <linux/compiler.h> |
21 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
22 | #include <linux/jhash.h> | 23 | #include <linux/jhash.h> |
@@ -100,6 +101,7 @@ struct rhashtable; | |||
100 | * @key_len: Length of key | 101 | * @key_len: Length of key |
101 | * @key_offset: Offset of key in struct to be hashed | 102 | * @key_offset: Offset of key in struct to be hashed |
102 | * @head_offset: Offset of rhash_head in struct to be hashed | 103 | * @head_offset: Offset of rhash_head in struct to be hashed |
104 | * @insecure_max_entries: Maximum number of entries (may be exceeded) | ||
103 | * @max_size: Maximum size while expanding | 105 | * @max_size: Maximum size while expanding |
104 | * @min_size: Minimum size while shrinking | 106 | * @min_size: Minimum size while shrinking |
105 | * @nulls_base: Base value to generate nulls marker | 107 | * @nulls_base: Base value to generate nulls marker |
@@ -115,6 +117,7 @@ struct rhashtable_params { | |||
115 | size_t key_len; | 117 | size_t key_len; |
116 | size_t key_offset; | 118 | size_t key_offset; |
117 | size_t head_offset; | 119 | size_t head_offset; |
120 | unsigned int insecure_max_entries; | ||
118 | unsigned int max_size; | 121 | unsigned int max_size; |
119 | unsigned int min_size; | 122 | unsigned int min_size; |
120 | u32 nulls_base; | 123 | u32 nulls_base; |
@@ -286,6 +289,18 @@ static inline bool rht_grow_above_100(const struct rhashtable *ht, | |||
286 | (!ht->p.max_size || tbl->size < ht->p.max_size); | 289 | (!ht->p.max_size || tbl->size < ht->p.max_size); |
287 | } | 290 | } |
288 | 291 | ||
292 | /** | ||
293 | * rht_grow_above_max - returns true if table is above maximum | ||
294 | * @ht: hash table | ||
295 | * @tbl: current table | ||
296 | */ | ||
297 | static inline bool rht_grow_above_max(const struct rhashtable *ht, | ||
298 | const struct bucket_table *tbl) | ||
299 | { | ||
300 | return ht->p.insecure_max_entries && | ||
301 | atomic_read(&ht->nelems) >= ht->p.insecure_max_entries; | ||
302 | } | ||
303 | |||
289 | /* The bucket lock is selected based on the hash and protects mutations | 304 | /* The bucket lock is selected based on the hash and protects mutations |
290 | * on a group of hash buckets. | 305 | * on a group of hash buckets. |
291 | * | 306 | * |
@@ -589,6 +604,10 @@ restart: | |||
589 | goto out; | 604 | goto out; |
590 | } | 605 | } |
591 | 606 | ||
607 | err = -E2BIG; | ||
608 | if (unlikely(rht_grow_above_max(ht, tbl))) | ||
609 | goto out; | ||
610 | |||
592 | if (unlikely(rht_grow_above_100(ht, tbl))) { | 611 | if (unlikely(rht_grow_above_100(ht, tbl))) { |
593 | slow_path: | 612 | slow_path: |
594 | spin_unlock_bh(lock); | 613 | spin_unlock_bh(lock); |