summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2018-06-17 22:52:50 -0400
committerDavid S. Miller <davem@davemloft.net>2018-06-22 00:43:27 -0400
commit9f9a707738aa7a8b9f78a641b83927ada256a626 (patch)
treebc5635cd713869c628fd43e18f7334bbb6bb6aeb
parent0eb71a9da5796851fa87ddc1a534066c0fe54055 (diff)
rhashtable: remove nulls_base and related code.
This "feature" is unused, undocumented, and untested and so doesn't really belong. A patch is under development to properly implement support for detecting when a search gets diverted down a different chain, which the common purpose of nulls markers. This patch actually fixes a bug too. The table resizing allows a table to grow to 2^31 buckets, but the hash is truncated to 27 bits - any growth beyond 2^27 is wasteful an ineffective. This patch results in NULLS_MARKER(0) being used for all chains, and leaves the use of rht_is_a_null() to test for it. Acked-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/rhashtable-types.h2
-rw-r--r--include/linux/rhashtable.h33
-rw-r--r--lib/rhashtable.c8
-rw-r--r--lib/test_rhashtable.c5
-rw-r--r--net/core/xdp.c4
5 files changed, 6 insertions, 46 deletions
diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h
index 9740063ff13b..763d613ce2c2 100644
--- a/include/linux/rhashtable-types.h
+++ b/include/linux/rhashtable-types.h
@@ -50,7 +50,6 @@ typedef int (*rht_obj_cmpfn_t)(struct rhashtable_compare_arg *arg,
50 * @min_size: Minimum size while shrinking 50 * @min_size: Minimum size while shrinking
51 * @locks_mul: Number of bucket locks to allocate per cpu (default: 32) 51 * @locks_mul: Number of bucket locks to allocate per cpu (default: 32)
52 * @automatic_shrinking: Enable automatic shrinking of tables 52 * @automatic_shrinking: Enable automatic shrinking of tables
53 * @nulls_base: Base value to generate nulls marker
54 * @hashfn: Hash function (default: jhash2 if !(key_len % 4), or jhash) 53 * @hashfn: Hash function (default: jhash2 if !(key_len % 4), or jhash)
55 * @obj_hashfn: Function to hash object 54 * @obj_hashfn: Function to hash object
56 * @obj_cmpfn: Function to compare key with object 55 * @obj_cmpfn: Function to compare key with object
@@ -64,7 +63,6 @@ struct rhashtable_params {
64 u16 min_size; 63 u16 min_size;
65 bool automatic_shrinking; 64 bool automatic_shrinking;
66 u8 locks_mul; 65 u8 locks_mul;
67 u32 nulls_base;
68 rht_hashfn_t hashfn; 66 rht_hashfn_t hashfn;
69 rht_obj_hashfn_t obj_hashfn; 67 rht_obj_hashfn_t obj_hashfn;
70 rht_obj_cmpfn_t obj_cmpfn; 68 rht_obj_cmpfn_t obj_cmpfn;
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 48754ab07cdf..d9f719af7936 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -28,25 +28,8 @@
28#include <linux/rhashtable-types.h> 28#include <linux/rhashtable-types.h>
29/* 29/*
30 * The end of the chain is marked with a special nulls marks which has 30 * The end of the chain is marked with a special nulls marks which has
31 * the following format: 31 * the least significant bit set.
32 *
33 * +-------+-----------------------------------------------------+-+
34 * | Base | Hash |1|
35 * +-------+-----------------------------------------------------+-+
36 *
37 * Base (4 bits) : Reserved to distinguish between multiple tables.
38 * Specified via &struct rhashtable_params.nulls_base.
39 * Hash (27 bits): Full hash (unmasked) of first element added to bucket
40 * 1 (1 bit) : Nulls marker (always set)
41 *
42 * The remaining bits of the next pointer remain unused for now.
43 */ 32 */
44#define RHT_BASE_BITS 4
45#define RHT_HASH_BITS 27
46#define RHT_BASE_SHIFT RHT_HASH_BITS
47
48/* Base bits plus 1 bit for nulls marker */
49#define RHT_HASH_RESERVED_SPACE (RHT_BASE_BITS + 1)
50 33
51/* Maximum chain length before rehash 34/* Maximum chain length before rehash
52 * 35 *
@@ -92,24 +75,14 @@ struct bucket_table {
92 struct rhash_head __rcu *buckets[] ____cacheline_aligned_in_smp; 75 struct rhash_head __rcu *buckets[] ____cacheline_aligned_in_smp;
93}; 76};
94 77
95static inline unsigned long rht_marker(const struct rhashtable *ht, u32 hash)
96{
97 return NULLS_MARKER(ht->p.nulls_base + hash);
98}
99
100#define INIT_RHT_NULLS_HEAD(ptr, ht, hash) \ 78#define INIT_RHT_NULLS_HEAD(ptr, ht, hash) \
101 ((ptr) = (typeof(ptr)) rht_marker(ht, hash)) 79 ((ptr) = (typeof(ptr)) NULLS_MARKER(0))
102 80
103static inline bool rht_is_a_nulls(const struct rhash_head *ptr) 81static inline bool rht_is_a_nulls(const struct rhash_head *ptr)
104{ 82{
105 return ((unsigned long) ptr & 1); 83 return ((unsigned long) ptr & 1);
106} 84}
107 85
108static inline unsigned long rht_get_nulls_value(const struct rhash_head *ptr)
109{
110 return ((unsigned long) ptr) >> 1;
111}
112
113static inline void *rht_obj(const struct rhashtable *ht, 86static inline void *rht_obj(const struct rhashtable *ht,
114 const struct rhash_head *he) 87 const struct rhash_head *he)
115{ 88{
@@ -119,7 +92,7 @@ static inline void *rht_obj(const struct rhashtable *ht,
119static inline unsigned int rht_bucket_index(const struct bucket_table *tbl, 92static inline unsigned int rht_bucket_index(const struct bucket_table *tbl,
120 unsigned int hash) 93 unsigned int hash)
121{ 94{
122 return (hash >> RHT_HASH_RESERVED_SPACE) & (tbl->size - 1); 95 return hash & (tbl->size - 1);
123} 96}
124 97
125static inline unsigned int rht_key_get_hash(struct rhashtable *ht, 98static inline unsigned int rht_key_get_hash(struct rhashtable *ht,
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index c9fafea7dc6e..688693c919be 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -995,7 +995,6 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed)
995 * .key_offset = offsetof(struct test_obj, key), 995 * .key_offset = offsetof(struct test_obj, key),
996 * .key_len = sizeof(int), 996 * .key_len = sizeof(int),
997 * .hashfn = jhash, 997 * .hashfn = jhash,
998 * .nulls_base = (1U << RHT_BASE_SHIFT),
999 * }; 998 * };
1000 * 999 *
1001 * Configuration Example 2: Variable length keys 1000 * Configuration Example 2: Variable length keys
@@ -1029,9 +1028,6 @@ int rhashtable_init(struct rhashtable *ht,
1029 (params->obj_hashfn && !params->obj_cmpfn)) 1028 (params->obj_hashfn && !params->obj_cmpfn))
1030 return -EINVAL; 1029 return -EINVAL;
1031 1030
1032 if (params->nulls_base && params->nulls_base < (1U << RHT_BASE_SHIFT))
1033 return -EINVAL;
1034
1035 memset(ht, 0, sizeof(*ht)); 1031 memset(ht, 0, sizeof(*ht));
1036 mutex_init(&ht->mutex); 1032 mutex_init(&ht->mutex);
1037 spin_lock_init(&ht->lock); 1033 spin_lock_init(&ht->lock);
@@ -1096,10 +1092,6 @@ int rhltable_init(struct rhltable *hlt, const struct rhashtable_params *params)
1096{ 1092{
1097 int err; 1093 int err;
1098 1094
1099 /* No rhlist NULLs marking for now. */
1100 if (params->nulls_base)
1101 return -EINVAL;
1102
1103 err = rhashtable_init(&hlt->ht, params); 1095 err = rhashtable_init(&hlt->ht, params);
1104 hlt->ht.rhlist = true; 1096 hlt->ht.rhlist = true;
1105 return err; 1097 return err;
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
index 6ca59ffcacbe..82ac39ce5310 100644
--- a/lib/test_rhashtable.c
+++ b/lib/test_rhashtable.c
@@ -83,7 +83,7 @@ static u32 my_hashfn(const void *data, u32 len, u32 seed)
83{ 83{
84 const struct test_obj_rhl *obj = data; 84 const struct test_obj_rhl *obj = data;
85 85
86 return (obj->value.id % 10) << RHT_HASH_RESERVED_SPACE; 86 return (obj->value.id % 10);
87} 87}
88 88
89static int my_cmpfn(struct rhashtable_compare_arg *arg, const void *obj) 89static int my_cmpfn(struct rhashtable_compare_arg *arg, const void *obj)
@@ -99,7 +99,6 @@ static struct rhashtable_params test_rht_params = {
99 .key_offset = offsetof(struct test_obj, value), 99 .key_offset = offsetof(struct test_obj, value),
100 .key_len = sizeof(struct test_obj_val), 100 .key_len = sizeof(struct test_obj_val),
101 .hashfn = jhash, 101 .hashfn = jhash,
102 .nulls_base = (3U << RHT_BASE_SHIFT),
103}; 102};
104 103
105static struct rhashtable_params test_rht_params_dup = { 104static struct rhashtable_params test_rht_params_dup = {
@@ -296,8 +295,6 @@ static int __init test_rhltable(unsigned int entries)
296 if (!obj_in_table) 295 if (!obj_in_table)
297 goto out_free; 296 goto out_free;
298 297
299 /* nulls_base not supported in rhlist interface */
300 test_rht_params.nulls_base = 0;
301 err = rhltable_init(&rhlt, &test_rht_params); 298 err = rhltable_init(&rhlt, &test_rht_params);
302 if (WARN_ON(err)) 299 if (WARN_ON(err))
303 goto out_free; 300 goto out_free;
diff --git a/net/core/xdp.c b/net/core/xdp.c
index 9d1f22072d5d..31c58719b5a9 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -45,8 +45,8 @@ static u32 xdp_mem_id_hashfn(const void *data, u32 len, u32 seed)
45 BUILD_BUG_ON(FIELD_SIZEOF(struct xdp_mem_allocator, mem.id) 45 BUILD_BUG_ON(FIELD_SIZEOF(struct xdp_mem_allocator, mem.id)
46 != sizeof(u32)); 46 != sizeof(u32));
47 47
48 /* Use cyclic increasing ID as direct hash key, see rht_bucket_index */ 48 /* Use cyclic increasing ID as direct hash key */
49 return key << RHT_HASH_RESERVED_SPACE; 49 return key;
50} 50}
51 51
52static int xdp_mem_id_cmp(struct rhashtable_compare_arg *arg, 52static int xdp_mem_id_cmp(struct rhashtable_compare_arg *arg,