0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/compiler.h>
0018 #include <linux/types.h>
0019 #include <linux/module.h>
0020 #include <linux/hash.h>
0021 #include <linux/stringhash.h>
0022 #include <kunit/test.h>
0023
0024
0025 static u32 __attribute_const__
0026 xorshift(u32 seed)
0027 {
0028 seed ^= seed << 13;
0029 seed ^= seed >> 17;
0030 seed ^= seed << 5;
0031 return seed;
0032 }
0033
0034
0035 static u8 __attribute_const__
0036 mod255(u32 x)
0037 {
0038 x = (x & 0xffff) + (x >> 16);
0039 x = (x & 0xff) + (x >> 8);
0040 x = (x & 0xff) + (x >> 8);
0041 x = (x & 0xff) + (x >> 8);
0042 return x;
0043 }
0044
0045
0046 static void fill_buf(char *buf, size_t len, u32 seed)
0047 {
0048 size_t i;
0049
0050 for (i = 0; i < len; i++) {
0051 seed = xorshift(seed);
0052 buf[i] = mod255(seed);
0053 }
0054 }
0055
0056
0057 struct test_hash_params {
0058
0059 unsigned long long *h64;
0060
0061 u32 h0;
0062
0063 u32 h1;
0064
0065 u32 h2;
0066
0067 u32 (*hash_or)[33];
0068 };
0069
0070 #ifdef HAVE_ARCH__HASH_32
0071 static void
0072 test_int__hash_32(struct kunit *test, struct test_hash_params *params)
0073 {
0074 params->hash_or[1][0] |= params->h2 = __hash_32_generic(params->h0);
0075 #if HAVE_ARCH__HASH_32 == 1
0076 KUNIT_EXPECT_EQ_MSG(test, params->h1, params->h2,
0077 "__hash_32(%#x) = %#x != __hash_32_generic() = %#x",
0078 params->h0, params->h1, params->h2);
0079 #endif
0080 }
0081 #endif
0082
0083 #ifdef HAVE_ARCH_HASH_64
0084 static void
0085 test_int_hash_64(struct kunit *test, struct test_hash_params *params, u32 const *m, int *k)
0086 {
0087 params->h2 = hash_64_generic(*params->h64, *k);
0088 #if HAVE_ARCH_HASH_64 == 1
0089 KUNIT_EXPECT_EQ_MSG(test, params->h1, params->h2,
0090 "hash_64(%#llx, %d) = %#x != hash_64_generic() = %#x",
0091 *params->h64, *k, params->h1, params->h2);
0092 #else
0093 KUNIT_EXPECT_LE_MSG(test, params->h1, params->h2,
0094 "hash_64_generic(%#llx, %d) = %#x > %#x",
0095 *params->h64, *k, params->h1, *m);
0096 #endif
0097 }
0098 #endif
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 static void
0110 test_int_hash(struct kunit *test, unsigned long long h64, u32 hash_or[2][33])
0111 {
0112 int k;
0113 struct test_hash_params params = { &h64, (u32)h64, 0, 0, hash_or };
0114
0115
0116 hash_or[0][0] |= params.h1 = __hash_32(params.h0);
0117 #ifdef HAVE_ARCH__HASH_32
0118 test_int__hash_32(test, ¶ms);
0119 #endif
0120
0121
0122 for (k = 1; k <= 32; k++) {
0123 u32 const m = ((u32)2 << (k-1)) - 1;
0124
0125
0126 hash_or[0][k] |= params.h1 = hash_32(params.h0, k);
0127 KUNIT_EXPECT_LE_MSG(test, params.h1, m,
0128 "hash_32(%#x, %d) = %#x > %#x",
0129 params.h0, k, params.h1, m);
0130
0131
0132 hash_or[1][k] |= params.h1 = hash_64(h64, k);
0133 KUNIT_EXPECT_LE_MSG(test, params.h1, m,
0134 "hash_64(%#llx, %d) = %#x > %#x",
0135 h64, k, params.h1, m);
0136 #ifdef HAVE_ARCH_HASH_64
0137 test_int_hash_64(test, ¶ms, &m, &k);
0138 #endif
0139 }
0140 }
0141
0142 #define SIZE 256
0143
0144 static void test_string_or(struct kunit *test)
0145 {
0146 char buf[SIZE+1];
0147 u32 string_or = 0;
0148 int i, j;
0149
0150 fill_buf(buf, SIZE, 1);
0151
0152
0153 for (j = SIZE; j > 0; --j) {
0154 buf[j] = '\0';
0155
0156 for (i = 0; i <= j; i++) {
0157 u32 h0 = full_name_hash(buf+i, buf+i, j-i);
0158
0159 string_or |= h0;
0160 }
0161 }
0162
0163
0164 KUNIT_EXPECT_EQ_MSG(test, string_or, -1u,
0165 "OR of all string hash results = %#x != %#x",
0166 string_or, -1u);
0167 }
0168
0169 static void test_hash_or(struct kunit *test)
0170 {
0171 char buf[SIZE+1];
0172 u32 hash_or[2][33] = { { 0, } };
0173 unsigned long long h64 = 0;
0174 int i, j;
0175
0176 fill_buf(buf, SIZE, 1);
0177
0178
0179 for (j = SIZE; j > 0; --j) {
0180 buf[j] = '\0';
0181
0182 for (i = 0; i <= j; i++) {
0183 u64 hashlen = hashlen_string(buf+i, buf+i);
0184 u32 h0 = full_name_hash(buf+i, buf+i, j-i);
0185
0186
0187 KUNIT_EXPECT_EQ_MSG(test, hashlen_len(hashlen), j-i,
0188 "hashlen_string(%d..%d) returned length %u, expected %d",
0189 i, j, hashlen_len(hashlen), j-i);
0190
0191 KUNIT_EXPECT_EQ_MSG(test, hashlen_hash(hashlen), h0,
0192 "hashlen_string(%d..%d) = %08x != full_name_hash() = %08x",
0193 i, j, hashlen_hash(hashlen), h0);
0194
0195 h64 = h64 << 32 | h0;
0196 test_int_hash(test, h64, hash_or);
0197 }
0198 }
0199
0200 KUNIT_EXPECT_EQ_MSG(test, hash_or[0][0], -1u,
0201 "OR of all __hash_32 results = %#x != %#x",
0202 hash_or[0][0], -1u);
0203 #ifdef HAVE_ARCH__HASH_32
0204 #if HAVE_ARCH__HASH_32 != 1
0205 KUNIT_EXPECT_EQ_MSG(test, hash_or[1][0], -1u,
0206 "OR of all __hash_32_generic results = %#x != %#x",
0207 hash_or[1][0], -1u);
0208 #endif
0209 #endif
0210
0211
0212 for (i = 1; i <= 32; i++) {
0213 u32 const m = ((u32)2 << (i-1)) - 1;
0214
0215 KUNIT_EXPECT_EQ_MSG(test, hash_or[0][i], m,
0216 "OR of all hash_32(%d) results = %#x (%#x expected)",
0217 i, hash_or[0][i], m);
0218 KUNIT_EXPECT_EQ_MSG(test, hash_or[1][i], m,
0219 "OR of all hash_64(%d) results = %#x (%#x expected)",
0220 i, hash_or[1][i], m);
0221 }
0222 }
0223
0224 static struct kunit_case hash_test_cases[] __refdata = {
0225 KUNIT_CASE(test_string_or),
0226 KUNIT_CASE(test_hash_or),
0227 {}
0228 };
0229
0230 static struct kunit_suite hash_test_suite = {
0231 .name = "hash",
0232 .test_cases = hash_test_cases,
0233 };
0234
0235
0236 kunit_test_suite(hash_test_suite);
0237
0238 MODULE_LICENSE("GPL");