diff options
author | NeilBrown <neilb@suse.com> | 2018-06-17 22:52:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-06-22 00:43:27 -0400 |
commit | 9f9a707738aa7a8b9f78a641b83927ada256a626 (patch) | |
tree | bc5635cd713869c628fd43e18f7334bbb6bb6aeb | |
parent | 0eb71a9da5796851fa87ddc1a534066c0fe54055 (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.h | 2 | ||||
-rw-r--r-- | include/linux/rhashtable.h | 33 | ||||
-rw-r--r-- | lib/rhashtable.c | 8 | ||||
-rw-r--r-- | lib/test_rhashtable.c | 5 | ||||
-rw-r--r-- | net/core/xdp.c | 4 |
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 | ||
95 | static 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 | ||
103 | static inline bool rht_is_a_nulls(const struct rhash_head *ptr) | 81 | static 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 | ||
108 | static inline unsigned long rht_get_nulls_value(const struct rhash_head *ptr) | ||
109 | { | ||
110 | return ((unsigned long) ptr) >> 1; | ||
111 | } | ||
112 | |||
113 | static inline void *rht_obj(const struct rhashtable *ht, | 86 | static 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, | |||
119 | static inline unsigned int rht_bucket_index(const struct bucket_table *tbl, | 92 | static 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 | ||
125 | static inline unsigned int rht_key_get_hash(struct rhashtable *ht, | 98 | static 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 | ||
89 | static int my_cmpfn(struct rhashtable_compare_arg *arg, const void *obj) | 89 | static 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 | ||
105 | static struct rhashtable_params test_rht_params_dup = { | 104 | static 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 | ||
52 | static int xdp_mem_id_cmp(struct rhashtable_compare_arg *arg, | 52 | static int xdp_mem_id_cmp(struct rhashtable_compare_arg *arg, |