1 /* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2021 Cisco Systems, Inc.
5 #include <vppinfra/format.h>
6 #include <vppinfra/test/test.h>
7 #include <vppinfra/vector/toeplitz.h>
9 /* secret key and test cases taken from:
10 * https://docs.microsoft.com/en-us/windows-hardware/drivers/network/verifying-the-rss-hash-calculation
17 } __clib_packed ip4_key_t;
29 } __clib_packed ip6_key_t;
39 #define N_LENGTH_TESTS 240
41 #ifndef CLIB_MARCH_VARIANT
42 #define _IP4(a, b, c, d) ((d) << 24 | (c) << 16 | (b) << 8 | (a))
43 #define _IP6(a, b, c, d, e, f, g, h) \
45 (u16) ((a) << 8) | (u8) ((a) >> 8), (u16) ((b) << 8) | (u8) ((b) >> 8), \
46 (u16) ((c) << 8) | (u8) ((c) >> 8), (u16) ((d) << 8) | (u8) ((d) >> 8), \
47 (u16) ((e) << 8) | (u8) ((e) >> 8), (u16) ((f) << 8) | (u8) ((f) >> 8), \
48 (u16) ((g) << 8) | (u8) ((g) >> 8), (u16) ((h) << 8) | (u8) ((h) >> 8), \
50 #define _PORT(a) ((a) >> 8 | (((a) &0xff) << 8))
52 const ip4_test_t ip4_tests[N_IP4_TESTS] = {
55 .key.sip = _IP4 (66, 9, 149, 187),
56 .key.dip = _IP4 (161, 142, 100, 80),
57 .key.sport = _PORT (2794),
58 .key.dport = _PORT (1766),
59 .hash_2t = 0x323e8fc2,
60 .hash_4t = 0x51ccc178,
63 .key.sip = _IP4 (199, 92, 111, 2),
64 .key.dip = _IP4 (65, 69, 140, 83),
65 .key.sport = _PORT (14230),
66 .key.dport = _PORT (4739),
67 .hash_2t = 0xd718262a,
68 .hash_4t = 0xc626b0ea,
71 .key.sip = _IP4 (24, 19, 198, 95),
72 .key.dip = _IP4 (12, 22, 207, 184),
73 .key.sport = _PORT (12898),
74 .key.dport = _PORT (38024),
75 .hash_2t = 0xd2d0a5de,
76 .hash_4t = 0x5c2b394a,
79 .key.sip = _IP4 (38, 27, 205, 30),
80 .key.dip = _IP4 (209, 142, 163, 6),
81 .key.sport = _PORT (48228),
82 .key.dport = _PORT (2217),
83 .hash_2t = 0x82989176,
84 .hash_4t = 0xafc7327f,
87 .key.sip = _IP4 (153, 39, 163, 191),
88 .key.dip = _IP4 (202, 188, 127, 2),
89 .key.sport = _PORT (44251),
90 .key.dport = _PORT (1303),
91 .hash_2t = 0x5d1809c5,
92 .hash_4t = 0x10e828a2,
96 const ip6_test_t ip6_tests[N_IP6_TESTS] = {
98 .key.sip = _IP6 (0x3ffe, 0x2501, 0x200, 0x1fff, 0, 0, 0, 7),
99 .key.dip = _IP6 (0x3ffe, 0x2501, 0x200, 3, 0, 0, 0, 1),
100 .key.sport = _PORT (2794),
101 .key.dport = _PORT (1766),
102 .hash_2t = 0x2cc18cd5,
103 .hash_4t = 0x40207d3d,
106 .key.sip = _IP6 (0x3ffe, 0x501, 8, 0, 0x260, 0x97ff, 0xfe40, 0xefab),
107 .key.dip = _IP6 (0xff02, 0, 0, 0, 0, 0, 0, 1),
108 .key.sport = _PORT (14230),
109 .key.dport = _PORT (4739),
110 .hash_2t = 0x0f0c461c,
111 .hash_4t = 0xdde51bbf,
114 .key.sip = _IP6 (0x3ffe, 0x1900, 0x4545, 3, 0x200, 0xf8ff, 0xfe21, 0x67cf),
115 .key.dip = _IP6 (0xfe80, 0, 0, 0, 0x200, 0xf8ff, 0xfe21, 0x67cf),
116 .key.sport = _PORT (44251),
117 .key.dport = _PORT (38024),
118 .hash_2t = 0x4b61e985,
119 .hash_4t = 0x02d1feef,
123 const u32 length_test_hashes[N_LENGTH_TESTS] = {
124 0x00000000, 0x00000000, 0x2b6d12ad, 0x9de4446e, 0x061f00bf, 0xad7ed8f7,
125 0x4bc7b068, 0x231fc545, 0xdbd97a33, 0xcdab29e7, 0x2d665c0c, 0x31e28ed7,
126 0x14e19218, 0x5aa89f0f, 0xd47de07f, 0x355ec712, 0x7e1cbfc0, 0xf84de19d,
127 0xbcf66bd3, 0x104086c6, 0x71900b34, 0xcd2f9819, 0xeae68ebb, 0x54d63b4c,
128 0x5f865a2c, 0x9d6ded08, 0xe00b0912, 0x3fcf07a6, 0x3bd9ca93, 0x3f4f3bbb,
129 0xd0b82624, 0xa28a08e1, 0xa585969f, 0x0c8f4a71, 0x5dce7bdd, 0x4fcf2a6d,
130 0x91c89ae9, 0xbef8a24d, 0x8e3d30fe, 0xc8027848, 0xc1e7e513, 0xa12bd3d9,
131 0x46700bb4, 0xc6339dab, 0x970805ad, 0xfcb50ac8, 0xc6db4f44, 0x792e2987,
132 0xacfb7836, 0xa25ec529, 0x957d7beb, 0x6732809a, 0x891836ed, 0xeefb83b2,
133 0xca96b40b, 0x93fd5abd, 0x9076f922, 0x59adb4eb, 0x9705aafb, 0x282719b1,
134 0xdda9cb8a, 0x3f499131, 0x47491130, 0x30ef0759, 0xad1cf855, 0x428aa312,
135 0x4200240a, 0x71a72857, 0x16b30c36, 0x10cca9a3, 0x166f091e, 0x30e00560,
136 0x8acd20ba, 0xfa633d76, 0x0fe32eb7, 0xdcc0122f, 0x20aa8ab0, 0x62b2a9af,
137 0x7a6c80a6, 0x27e87268, 0x95b797a8, 0x25d18ccd, 0x68a7fb00, 0xc54bcdad,
138 0x3bd0e717, 0xf0df54c9, 0x780daadf, 0x7b435605, 0x150c1e10, 0x8a892e54,
139 0x9d27cb25, 0xe23383a5, 0x57aac408, 0x83b8abf8, 0x560f33af, 0xd5cb3307,
140 0x79ae8edc, 0x9b127665, 0x320f18bd, 0x385d636b, 0xbd1b2dbf, 0x97679888,
141 0x738894a4, 0xeba2afb0, 0xfa7c2d50, 0xb6741aa1, 0x28922bba, 0x7783242b,
142 0xa694cca2, 0xa32781c0, 0x696cd670, 0xa714d72f, 0xea34d35a, 0xc5aed81e,
143 0x0438433a, 0xc1939ab2, 0xb51c123a, 0x121426b9, 0x1add93ba, 0x50c56b6a,
144 0x7e90902a, 0xae3abd85, 0x2f7a0088, 0xb45cf6f9, 0x80070094, 0x8bd46467,
145 0xdfd1b762, 0x0bb25856, 0x48eefe84, 0x0989dbb9, 0xfc32472b, 0x965fec6b,
146 0x5a256bd0, 0x6df7127a, 0x7856d0d6, 0xedc82bd3, 0x1b563b96, 0xc73eace7,
147 0xba4c0a93, 0xdfd6dd97, 0x923c41db, 0x14926ca6, 0x22e52ab1, 0x22852a66,
148 0x79606b9c, 0xb0f22b23, 0xb46354ba, 0x9c3cd931, 0x03a92bd6, 0x84000834,
149 0x5425df65, 0xf4dd3fc9, 0x391cc873, 0xa560b52e, 0x828037d9, 0x31323dd5,
150 0x5c6e3147, 0x28e21f85, 0xa431eb51, 0xf468c4a3, 0x9bea1d2e, 0x43d9109c,
151 0x5bb9b081, 0xe0825675, 0xc9c92591, 0xd29fc812, 0x03136bc9, 0x5e005a1f,
152 0x6d821ed8, 0x3f0bfcc4, 0x24774162, 0x893bde94, 0x6475efea, 0x6711538e,
153 0xc4755f6d, 0x9425ebe2, 0xacf471b4, 0xb947ab0c, 0x1f78c455, 0x372b3ed7,
154 0xb3ec24d7, 0x18c4459f, 0xa8ff3695, 0xe4aa2b85, 0x8a52ad7e, 0xe05e8177,
155 0x7aa348ed, 0x3e4ac6aa, 0x17dcf8a5, 0x93b933b0, 0x8f7413ec, 0xc77bfe61,
156 0xfdb72874, 0x4370f138, 0xdf3462ad, 0xc8970a59, 0xb4a9fed8, 0xa2ddc39b,
157 0xd61db62a, 0x95c5fc1b, 0x7b22e6e0, 0x1969702c, 0x7992aebb, 0x59d7c225,
158 0x0e16db0b, 0x9f2afc21, 0x246cf66b, 0xb3d6569d, 0x29c532d7, 0xe155747a,
159 0xe38d7872, 0xea704969, 0xb69095b0, 0x1b198efd, 0x55daab76, 0xa2a377b6,
160 0xb31aa2fa, 0x48b73c41, 0xf0cc501a, 0x9c9ca831, 0x1b591b99, 0xb2d8d22f,
161 0xab4b5f69, 0x4fe00e71, 0xdf5480bd, 0x982540d7, 0x7f34ea4f, 0xd7be66e1,
162 0x9d2ab1ba, 0x1ba62e12, 0xee3fb36c, 0xf28d7c5a, 0x756311eb, 0xc68567f2,
163 0x7b6ea177, 0xc398d9f3
167 extern const ip4_test_t ip4_tests[N_IP4_TESTS];
168 extern const ip6_test_t ip6_tests[N_IP6_TESTS];
169 extern const u32 length_test_hashes[N_LENGTH_TESTS];
173 wrapper (clib_toeplitz_hash_key_t *k, u8 *data, u32 n_bytes)
175 return clib_toeplitz_hash (k, data, n_bytes);
179 wrapper_x4 (clib_toeplitz_hash_key_t *k, u8 *d0, u8 *d1, u8 *d2, u8 *d3,
180 u32 *h0, u32 *h1, u32 *h2, u32 *h3, u32 n_bytes)
182 clib_toeplitz_hash_x4 (k, d0, d1, d2, d3, h0, h1, h2, h3, n_bytes);
185 static clib_error_t *
186 test_clib_toeplitz_hash (clib_error_t *err)
189 int n_key_copies, bigkey_len, bigdata_len;
190 u8 *bigkey, *bigdata;
191 clib_toeplitz_hash_key_t *k;
193 k = clib_toeplitz_hash_key_init (0, 0);
195 for (int i = 0; i < N_IP4_TESTS; i++)
197 r = wrapper (k, (u8 *) &ip4_tests[i].key, 8);
198 if (ip4_tests[i].hash_2t != r)
199 return clib_error_return (err,
200 "wrong IPv4 2 tuple hash for test %u, "
201 "calculated 0x%08x expected 0x%08x",
202 i, ip4_tests[i].hash_2t, r);
204 r = wrapper (k, (u8 *) &ip4_tests[i].key, 12);
205 if (ip4_tests[i].hash_4t != r)
206 return clib_error_return (err,
207 "wrong IPv4 4 tuple hash for test %u, "
208 "calculated 0x%08x expected 0x%08x",
209 i, ip4_tests[i].hash_4t, r);
212 for (int i = 0; i < N_IP6_TESTS; i++)
214 r = wrapper (k, (u8 *) &ip6_tests[i].key, 32);
215 if (ip6_tests[i].hash_2t != r)
216 return clib_error_return (err,
217 "wrong IPv6 2 tuple hash for test %u, "
218 "calculated 0x%08x expected 0x%08x",
219 i, ip6_tests[i].hash_2t, r);
221 r = wrapper (k, (u8 *) &ip6_tests[i].key, 36);
222 if (ip6_tests[i].hash_4t != r)
223 return clib_error_return (err,
224 "wrong IPv6 4 tuple hash for test %u, "
225 "calculated 0x%08x expected 0x%08x",
226 i, ip6_tests[i].hash_4t, r);
230 bigkey_len = k->key_length * n_key_copies;
231 bigdata_len = bigkey_len - 4;
232 bigkey = test_mem_alloc_and_splat (k->key_length, n_key_copies, k->data);
233 bigdata = test_mem_alloc_and_fill_inc_u8 (bigdata_len, 0, 0);
234 u32 key_len = k->key_length;
236 clib_toeplitz_hash_key_free (k);
237 k = clib_toeplitz_hash_key_init (bigkey, n_key_copies * key_len);
239 for (int i = 0; i < N_LENGTH_TESTS - 4; i++)
241 r = wrapper (k, bigdata, i);
242 if (length_test_hashes[i] != r)
244 err = clib_error_return (err,
245 "wrong length test hash for length %u, "
246 "calculated 0x%08x expected 0x%08x "
248 i, r, length_test_hashes[i],
249 r ^ length_test_hashes[i]);
255 clib_toeplitz_hash_key_free (k);
256 test_mem_free (bigkey);
257 test_mem_free (bigdata);
262 perftest_fixed_12byte (test_perf_t *tp)
265 u8 *data = test_mem_alloc_and_splat (12, n, (void *) &ip4_tests[0].key);
266 u8 *res = test_mem_alloc (4 * n);
267 clib_toeplitz_hash_key_t *k = clib_toeplitz_hash_key_init (0, 0);
269 test_perf_event_enable (tp);
270 for (int i = 0; i < n; i++)
271 ((u32 *) res)[i] = clib_toeplitz_hash (k, data + i * 12, 12);
272 test_perf_event_disable (tp);
274 clib_toeplitz_hash_key_free (k);
275 test_mem_free (data);
280 perftest_fixed_36byte (test_perf_t *tp)
283 u8 *data = test_mem_alloc_and_splat (36, n, (void *) &ip6_tests[0].key);
284 u8 *res = test_mem_alloc (4 * n);
285 clib_toeplitz_hash_key_t *k = clib_toeplitz_hash_key_init (0, 0);
287 test_perf_event_enable (tp);
288 for (int i = 0; i < n; i++)
289 ((u32 *) res)[i] = clib_toeplitz_hash (k, data + i * 36, 36);
290 test_perf_event_disable (tp);
292 clib_toeplitz_hash_key_free (k);
293 test_mem_free (data);
298 perftest_variable_size (test_perf_t *tp)
300 u32 key_len, n_keys, n = tp->n_ops;
301 u8 *key, *data = test_mem_alloc (n);
302 u32 *res = test_mem_alloc (sizeof (u32));
303 clib_toeplitz_hash_key_t *k = clib_toeplitz_hash_key_init (0, 0);
305 k = clib_toeplitz_hash_key_init (0, 0);
306 key_len = k->key_length;
307 n_keys = ((n + 4) / k->key_length) + 1;
308 key = test_mem_alloc_and_splat (n_keys, key_len, k->data);
309 clib_toeplitz_hash_key_free (k);
310 k = clib_toeplitz_hash_key_init (key, key_len * n_keys);
312 test_perf_event_enable (tp);
313 res[0] = clib_toeplitz_hash (k, data, n);
314 test_perf_event_disable (tp);
316 clib_toeplitz_hash_key_free (k);
317 test_mem_free (data);
322 REGISTER_TEST (clib_toeplitz_hash) = {
323 .name = "clib_toeplitz_hash",
324 .fn = test_clib_toeplitz_hash,
325 .perf_tests = PERF_TESTS ({ .name = "fixed (per 12 byte tuple)",
327 .fn = perftest_fixed_12byte },
328 { .name = "fixed (per 36 byte tuple)",
330 .fn = perftest_fixed_36byte },
331 { .name = "variable size (per byte)",
333 .fn = perftest_variable_size }),
336 static clib_error_t *
337 test_clib_toeplitz_hash_x4 (clib_error_t *err)
340 int n_key_copies, bigkey_len, bigdata_len;
341 u8 *bigkey, *bigdata0, *bigdata1, *bigdata2, *bigdata3;
342 clib_toeplitz_hash_key_t *k;
344 k = clib_toeplitz_hash_key_init (0, 0);
346 wrapper_x4 (k, (u8 *) &ip4_tests[0].key, (u8 *) &ip4_tests[1].key,
347 (u8 *) &ip4_tests[2].key, (u8 *) &ip4_tests[3].key, r, r + 1,
350 if (ip4_tests[0].hash_2t != r[0] || ip4_tests[1].hash_2t != r[1] ||
351 ip4_tests[2].hash_2t != r[2] || ip4_tests[3].hash_2t != r[3])
352 return clib_error_return (err,
353 "wrong IPv4 2 tuple x4 hash "
354 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x } "
355 "expected { 0x%08x, 0x%08x, 0x%08x, 0x%08x }",
356 ip4_tests[0].hash_2t, ip4_tests[1].hash_2t,
357 ip4_tests[2].hash_2t, ip4_tests[3].hash_2t, r[0],
360 wrapper_x4 (k, (u8 *) &ip4_tests[0].key, (u8 *) &ip4_tests[1].key,
361 (u8 *) &ip4_tests[2].key, (u8 *) &ip4_tests[3].key, r, r + 1,
364 if (ip4_tests[0].hash_4t != r[0] || ip4_tests[1].hash_4t != r[1] ||
365 ip4_tests[2].hash_4t != r[2] || ip4_tests[3].hash_4t != r[3])
366 return clib_error_return (err,
367 "wrong IPv4 4 tuple x4 hash "
368 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x } "
369 "expected { 0x%08x, 0x%08x, 0x%08x, 0x%08x }",
370 ip4_tests[0].hash_4t, ip4_tests[1].hash_4t,
371 ip4_tests[2].hash_4t, ip4_tests[3].hash_4t, r[0],
374 wrapper_x4 (k, (u8 *) &ip6_tests[0].key, (u8 *) &ip6_tests[1].key,
375 (u8 *) &ip6_tests[2].key, (u8 *) &ip6_tests[0].key, r, r + 1,
378 if (ip6_tests[0].hash_2t != r[0] || ip6_tests[1].hash_2t != r[1] ||
379 ip6_tests[2].hash_2t != r[2] || ip6_tests[0].hash_2t != r[3])
380 return clib_error_return (err,
381 "wrong IPv6 2 tuple x4 hash "
382 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x } "
383 "expected { 0x%08x, 0x%08x, 0x%08x, 0x%08x }",
384 ip6_tests[0].hash_2t, ip6_tests[1].hash_2t,
385 ip6_tests[2].hash_2t, ip6_tests[0].hash_2t, r[0],
388 wrapper_x4 (k, (u8 *) &ip6_tests[0].key, (u8 *) &ip6_tests[1].key,
389 (u8 *) &ip6_tests[2].key, (u8 *) &ip6_tests[0].key, r, r + 1,
392 if (ip6_tests[0].hash_4t != r[0] || ip6_tests[1].hash_4t != r[1] ||
393 ip6_tests[2].hash_4t != r[2] || ip6_tests[0].hash_4t != r[3])
394 return clib_error_return (err,
395 "wrong IPv6 4 tuple x4 hash "
396 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x } "
397 "expected { 0x%08x, 0x%08x, 0x%08x, 0x%08x }",
398 ip6_tests[0].hash_4t, ip6_tests[1].hash_4t,
399 ip6_tests[2].hash_4t, ip6_tests[0].hash_4t, r[0],
403 bigkey_len = k->key_length * n_key_copies;
404 bigdata_len = bigkey_len - 4;
405 bigkey = test_mem_alloc_and_splat (k->key_length, n_key_copies, k->data);
406 bigdata0 = test_mem_alloc_and_fill_inc_u8 (bigdata_len, 0, 0);
407 bigdata1 = test_mem_alloc_and_fill_inc_u8 (bigdata_len, 0, 0);
408 bigdata2 = test_mem_alloc_and_fill_inc_u8 (bigdata_len, 0, 0);
409 bigdata3 = test_mem_alloc_and_fill_inc_u8 (bigdata_len, 0, 0);
410 u32 key_len = k->key_length;
412 clib_toeplitz_hash_key_free (k);
413 k = clib_toeplitz_hash_key_init (bigkey, n_key_copies * key_len);
415 for (int i = 0; i < N_LENGTH_TESTS - 4; i++)
417 wrapper_x4 (k, bigdata0, bigdata1, bigdata2, bigdata3, r, r + 1, r + 2,
419 if (length_test_hashes[i] != r[0] || length_test_hashes[i] != r[1] ||
420 length_test_hashes[i] != r[2] || length_test_hashes[i] != r[3])
422 err = clib_error_return (
424 "wrong length test hash x4 for length %u, "
425 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x }, expected 0x%08x",
426 i, r[0], r[1], r[2], r[3], length_test_hashes[i]);
432 clib_toeplitz_hash_key_free (k);
433 test_mem_free (bigkey);
434 test_mem_free (bigdata0);
435 test_mem_free (bigdata1);
436 test_mem_free (bigdata2);
437 test_mem_free (bigdata3);
442 perftest_fixed_12byte_x4 (test_perf_t *tp)
444 u32 n = tp->n_ops / 4;
445 u8 *d0 = test_mem_alloc_and_splat (12, n, (void *) &ip4_tests[0].key);
446 u8 *d1 = test_mem_alloc_and_splat (12, n, (void *) &ip4_tests[1].key);
447 u8 *d2 = test_mem_alloc_and_splat (12, n, (void *) &ip4_tests[2].key);
448 u8 *d3 = test_mem_alloc_and_splat (12, n, (void *) &ip4_tests[3].key);
449 u32 *h0 = test_mem_alloc (4 * n);
450 u32 *h1 = test_mem_alloc (4 * n);
451 u32 *h2 = test_mem_alloc (4 * n);
452 u32 *h3 = test_mem_alloc (4 * n);
453 clib_toeplitz_hash_key_t *k = clib_toeplitz_hash_key_init (0, 0);
455 test_perf_event_enable (tp);
456 for (int i = 0; i < n; i++)
457 clib_toeplitz_hash_x4 (k, d0 + i * 12, d1 + i * 12, d2 + i * 12,
458 d3 + i * 12, h0 + i, h1 + i, h2 + i, h3 + i, 12);
459 test_perf_event_disable (tp);
461 clib_toeplitz_hash_key_free (k);
473 perftest_fixed_36byte_x4 (test_perf_t *tp)
475 u32 n = tp->n_ops / 4;
476 u8 *d0 = test_mem_alloc_and_splat (36, n, (void *) &ip4_tests[0].key);
477 u8 *d1 = test_mem_alloc_and_splat (36, n, (void *) &ip4_tests[1].key);
478 u8 *d2 = test_mem_alloc_and_splat (36, n, (void *) &ip4_tests[2].key);
479 u8 *d3 = test_mem_alloc_and_splat (36, n, (void *) &ip4_tests[3].key);
480 u32 *h0 = test_mem_alloc (4 * n);
481 u32 *h1 = test_mem_alloc (4 * n);
482 u32 *h2 = test_mem_alloc (4 * n);
483 u32 *h3 = test_mem_alloc (4 * n);
484 clib_toeplitz_hash_key_t *k = clib_toeplitz_hash_key_init (0, 0);
486 test_perf_event_enable (tp);
487 for (int i = 0; i < n; i++)
488 clib_toeplitz_hash_x4 (k, d0 + i * 36, d1 + i * 36, d2 + i * 36,
489 d3 + i * 36, h0 + i, h1 + i, h2 + i, h3 + i, 36);
490 test_perf_event_disable (tp);
492 clib_toeplitz_hash_key_free (k);
504 perftest_variable_size_x4 (test_perf_t *tp)
506 u32 key_len, n_keys, n = tp->n_ops / 4;
508 u8 *d0 = test_mem_alloc (n);
509 u8 *d1 = test_mem_alloc (n);
510 u8 *d2 = test_mem_alloc (n);
511 u8 *d3 = test_mem_alloc (n);
512 u32 *h0 = test_mem_alloc (sizeof (u32));
513 u32 *h1 = test_mem_alloc (sizeof (u32));
514 u32 *h2 = test_mem_alloc (sizeof (u32));
515 u32 *h3 = test_mem_alloc (sizeof (u32));
516 clib_toeplitz_hash_key_t *k = clib_toeplitz_hash_key_init (0, 0);
518 k = clib_toeplitz_hash_key_init (0, 0);
519 key_len = k->key_length;
520 n_keys = ((n + 4) / k->key_length) + 1;
521 key = test_mem_alloc_and_splat (n_keys, key_len, k->data);
522 clib_toeplitz_hash_key_free (k);
523 k = clib_toeplitz_hash_key_init (key, key_len * n_keys);
525 test_perf_event_enable (tp);
526 clib_toeplitz_hash_x4 (k, d0, d1, d2, d3, h0, h1, h2, h3, n);
527 test_perf_event_disable (tp);
529 clib_toeplitz_hash_key_free (k);
541 REGISTER_TEST (clib_toeplitz_hash_x4) = {
542 .name = "clib_toeplitz_hash_x4",
543 .fn = test_clib_toeplitz_hash_x4,
544 .perf_tests = PERF_TESTS ({ .name = "fixed (per 12 byte tuple)",
546 .fn = perftest_fixed_12byte_x4 },
547 { .name = "fixed (per 36 byte tuple)",
549 .fn = perftest_fixed_36byte_x4 },
550 { .name = "variable size (per byte)",
552 .fn = perftest_variable_size_x4 }),