blob: d425a443eec8b2f6fb579708fbfd3ee088689485 [file] [log] [blame]
Damjan Marion2e5921b2021-11-28 22:57:15 +01001/* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2021 Cisco Systems, Inc.
3 */
4
5#include <vppinfra/format.h>
6#include <vppinfra/vector/test/test.h>
7#include <vppinfra/vector/toeplitz.h>
8
9/* secret key and test cases taken from:
10 * https://docs.microsoft.com/en-us/windows-hardware/drivers/network/verifying-the-rss-hash-calculation
11 */
12
13typedef struct
14{
15 u32 sip, dip;
16 u16 sport, dport;
17} __clib_packed ip4_key_t;
18
19typedef struct
20{
21 ip4_key_t key;
22 u32 hash_2t, hash_4t;
23} ip4_test_t;
24
25typedef struct
26{
27 u16 sip[8], dip[8];
28 u16 sport, dport;
29} __clib_packed ip6_key_t;
30
31typedef struct
32{
33 ip6_key_t key;
34 u32 hash_2t, hash_4t;
35} ip6_test_t;
36
37#define N_IP4_TESTS 5
38#define N_IP6_TESTS 3
39#define N_LENGTH_TESTS 240
40
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) \
44 { \
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), \
49 }
50#define _PORT(a) ((a) >> 8 | (((a) &0xff) << 8))
51
52const ip4_test_t ip4_tests[N_IP4_TESTS] = {
53 /* ipv4 tests */
54 {
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,
61 },
62 {
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,
69 },
70 {
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,
77 },
78 {
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,
85 },
86 {
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,
93 }
94};
95
96const ip6_test_t ip6_tests[N_IP6_TESTS] = {
97 {
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,
104 },
105 {
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,
112 },
113 {
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,
120 }
121};
122
123const 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
164};
165
166#else
167extern const ip4_test_t ip4_tests[N_IP4_TESTS];
168extern const ip6_test_t ip6_tests[N_IP6_TESTS];
169extern const u32 length_test_hashes[N_LENGTH_TESTS];
170#endif
171
172__test_funct_fn u32
173wrapper (clib_toeplitz_hash_key_t *k, u8 *data, u32 n_bytes)
174{
175 return clib_toeplitz_hash (k, data, n_bytes);
176}
177
Damjan Marion88019c42021-12-15 10:17:04 +0000178__test_funct_fn void
179wrapper_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)
181{
182 clib_toeplitz_hash_x4 (k, d0, d1, d2, d3, h0, h1, h2, h3, n_bytes);
183}
184
Damjan Marion2e5921b2021-11-28 22:57:15 +0100185static clib_error_t *
186test_clib_toeplitz_hash (clib_error_t *err)
187{
188 u32 r;
189 int n_key_copies, bigkey_len, bigdata_len;
190 u8 *bigkey, *bigdata;
191 clib_toeplitz_hash_key_t *k;
192
193 k = clib_toeplitz_hash_key_init (0, 0);
194
195 for (int i = 0; i < N_IP4_TESTS; i++)
196 {
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);
203
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);
210 }
211
212 for (int i = 0; i < N_IP6_TESTS; i++)
213 {
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);
220
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);
227 }
228
229 n_key_copies = 6;
230 bigkey_len = k->key_length * n_key_copies;
231 bigdata_len = bigkey_len - 4;
Damjan Marion88019c42021-12-15 10:17:04 +0000232 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);
Damjan Marion2e5921b2021-11-28 22:57:15 +0100234 u32 key_len = k->key_length;
235
Damjan Marion2e5921b2021-11-28 22:57:15 +0100236 clib_toeplitz_hash_key_free (k);
237 k = clib_toeplitz_hash_key_init (bigkey, n_key_copies * key_len);
238
239 for (int i = 0; i < N_LENGTH_TESTS - 4; i++)
240 {
241 r = wrapper (k, bigdata, i);
242 if (length_test_hashes[i] != r)
243 {
244 err = clib_error_return (err,
245 "wrong length test hash for length %u, "
246 "calculated 0x%08x expected 0x%08x "
247 "xor 0x%08x",
248 i, r, length_test_hashes[i],
249 r ^ length_test_hashes[i]);
250 goto done;
251 }
252 }
253
254done:
255 clib_toeplitz_hash_key_free (k);
Damjan Marion88019c42021-12-15 10:17:04 +0000256 test_mem_free (bigkey);
257 test_mem_free (bigdata);
Damjan Marion2e5921b2021-11-28 22:57:15 +0100258 return err;
259}
260
261void __test_perf_fn
262perftest_fixed_12byte (int fd, test_perf_t *tp)
263{
264 u32 n = tp->n_ops;
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);
268
269 test_perf_event_enable (fd);
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 (fd);
273
274 clib_toeplitz_hash_key_free (k);
275 test_mem_free (data);
276 test_mem_free (res);
277}
278
279void __test_perf_fn
280perftest_fixed_36byte (int fd, test_perf_t *tp)
281{
282 u32 n = tp->n_ops;
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);
286
287 test_perf_event_enable (fd);
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 (fd);
291
292 clib_toeplitz_hash_key_free (k);
293 test_mem_free (data);
294 test_mem_free (res);
295}
296
297void __test_perf_fn
298perftest_variable_size (int fd, test_perf_t *tp)
299{
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);
304
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);
311
312 test_perf_event_enable (fd);
313 res[0] = clib_toeplitz_hash (k, data, n);
314 test_perf_event_disable (fd);
315
316 clib_toeplitz_hash_key_free (k);
317 test_mem_free (data);
318 test_mem_free (res);
319 test_mem_free (key);
320}
321
322REGISTER_TEST (clib_toeplitz_hash) = {
323 .name = "clib_toeplitz_hash",
324 .fn = test_clib_toeplitz_hash,
325 .perf_tests = PERF_TESTS ({ .name = "fixed_12",
326 .op_name = "12B Tuple",
327 .n_ops = 1024,
328 .fn = perftest_fixed_12byte },
329 { .name = "fixed_36",
330 .op_name = "36B Tuple",
331 .n_ops = 1024,
332 .fn = perftest_fixed_36byte },
333 { .name = "variable_size",
334 .op_name = "Byte",
335 .n_ops = 16384,
336 .fn = perftest_variable_size }),
337};
Damjan Marion88019c42021-12-15 10:17:04 +0000338
339static clib_error_t *
340test_clib_toeplitz_hash_x4 (clib_error_t *err)
341{
342 u32 r[4];
343 int n_key_copies, bigkey_len, bigdata_len;
344 u8 *bigkey, *bigdata0, *bigdata1, *bigdata2, *bigdata3;
345 clib_toeplitz_hash_key_t *k;
346
347 k = clib_toeplitz_hash_key_init (0, 0);
348
349 wrapper_x4 (k, (u8 *) &ip4_tests[0].key, (u8 *) &ip4_tests[1].key,
350 (u8 *) &ip4_tests[2].key, (u8 *) &ip4_tests[3].key, r, r + 1,
351 r + 2, r + 3, 8);
352
353 if (ip4_tests[0].hash_2t != r[0] || ip4_tests[1].hash_2t != r[1] ||
354 ip4_tests[2].hash_2t != r[2] || ip4_tests[3].hash_2t != r[3])
355 return clib_error_return (err,
356 "wrong IPv4 2 tuple x4 hash "
357 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x } "
358 "expected { 0x%08x, 0x%08x, 0x%08x, 0x%08x }",
359 ip4_tests[0].hash_2t, ip4_tests[1].hash_2t,
360 ip4_tests[2].hash_2t, ip4_tests[3].hash_2t, r[0],
361 r[1], r[2], r[3]);
362
363 wrapper_x4 (k, (u8 *) &ip4_tests[0].key, (u8 *) &ip4_tests[1].key,
364 (u8 *) &ip4_tests[2].key, (u8 *) &ip4_tests[3].key, r, r + 1,
365 r + 2, r + 3, 12);
366
367 if (ip4_tests[0].hash_4t != r[0] || ip4_tests[1].hash_4t != r[1] ||
368 ip4_tests[2].hash_4t != r[2] || ip4_tests[3].hash_4t != r[3])
369 return clib_error_return (err,
370 "wrong IPv4 4 tuple x4 hash "
371 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x } "
372 "expected { 0x%08x, 0x%08x, 0x%08x, 0x%08x }",
373 ip4_tests[0].hash_4t, ip4_tests[1].hash_4t,
374 ip4_tests[2].hash_4t, ip4_tests[3].hash_4t, r[0],
375 r[1], r[2], r[3]);
376
377 wrapper_x4 (k, (u8 *) &ip6_tests[0].key, (u8 *) &ip6_tests[1].key,
378 (u8 *) &ip6_tests[2].key, (u8 *) &ip6_tests[0].key, r, r + 1,
379 r + 2, r + 3, 32);
380
381 if (ip6_tests[0].hash_2t != r[0] || ip6_tests[1].hash_2t != r[1] ||
382 ip6_tests[2].hash_2t != r[2] || ip6_tests[0].hash_2t != r[3])
383 return clib_error_return (err,
384 "wrong IPv6 2 tuple x4 hash "
385 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x } "
386 "expected { 0x%08x, 0x%08x, 0x%08x, 0x%08x }",
387 ip6_tests[0].hash_2t, ip6_tests[1].hash_2t,
388 ip6_tests[2].hash_2t, ip6_tests[0].hash_2t, r[0],
389 r[1], r[2], r[3]);
390
391 wrapper_x4 (k, (u8 *) &ip6_tests[0].key, (u8 *) &ip6_tests[1].key,
392 (u8 *) &ip6_tests[2].key, (u8 *) &ip6_tests[0].key, r, r + 1,
393 r + 2, r + 3, 36);
394
395 if (ip6_tests[0].hash_4t != r[0] || ip6_tests[1].hash_4t != r[1] ||
396 ip6_tests[2].hash_4t != r[2] || ip6_tests[0].hash_4t != r[3])
397 return clib_error_return (err,
398 "wrong IPv6 4 tuple x4 hash "
399 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x } "
400 "expected { 0x%08x, 0x%08x, 0x%08x, 0x%08x }",
401 ip6_tests[0].hash_4t, ip6_tests[1].hash_4t,
402 ip6_tests[2].hash_4t, ip6_tests[0].hash_4t, r[0],
403 r[1], r[2], r[3]);
404
405 n_key_copies = 6;
406 bigkey_len = k->key_length * n_key_copies;
407 bigdata_len = bigkey_len - 4;
408 bigkey = test_mem_alloc_and_splat (k->key_length, n_key_copies, k->data);
409 bigdata0 = test_mem_alloc_and_fill_inc_u8 (bigdata_len, 0, 0);
410 bigdata1 = test_mem_alloc_and_fill_inc_u8 (bigdata_len, 0, 0);
411 bigdata2 = test_mem_alloc_and_fill_inc_u8 (bigdata_len, 0, 0);
412 bigdata3 = test_mem_alloc_and_fill_inc_u8 (bigdata_len, 0, 0);
413 u32 key_len = k->key_length;
414
415 clib_toeplitz_hash_key_free (k);
416 k = clib_toeplitz_hash_key_init (bigkey, n_key_copies * key_len);
417
418 for (int i = 0; i < N_LENGTH_TESTS - 4; i++)
419 {
420 wrapper_x4 (k, bigdata0, bigdata1, bigdata2, bigdata3, r, r + 1, r + 2,
421 r + 3, i);
422 if (length_test_hashes[i] != r[0] || length_test_hashes[i] != r[1] ||
423 length_test_hashes[i] != r[2] || length_test_hashes[i] != r[3])
424 {
425 err = clib_error_return (
426 err,
427 "wrong length test hash x4 for length %u, "
428 "calculated { 0x%08x, 0x%08x, 0x%08x, 0x%08x }, expected 0x%08x",
429 i, r[0], r[1], r[2], r[3], length_test_hashes[i]);
430 goto done;
431 }
432 }
433
434done:
435 clib_toeplitz_hash_key_free (k);
436 test_mem_free (bigkey);
437 test_mem_free (bigdata0);
438 test_mem_free (bigdata1);
439 test_mem_free (bigdata2);
440 test_mem_free (bigdata3);
441 return err;
442}
443
444void __test_perf_fn
445perftest_fixed_12byte_x4 (int fd, test_perf_t *tp)
446{
447 u32 n = tp->n_ops / 4;
448 u8 *d0 = test_mem_alloc_and_splat (12, n, (void *) &ip4_tests[0].key);
449 u8 *d1 = test_mem_alloc_and_splat (12, n, (void *) &ip4_tests[1].key);
450 u8 *d2 = test_mem_alloc_and_splat (12, n, (void *) &ip4_tests[2].key);
451 u8 *d3 = test_mem_alloc_and_splat (12, n, (void *) &ip4_tests[3].key);
452 u32 *h0 = test_mem_alloc (4 * n);
453 u32 *h1 = test_mem_alloc (4 * n);
454 u32 *h2 = test_mem_alloc (4 * n);
455 u32 *h3 = test_mem_alloc (4 * n);
456 clib_toeplitz_hash_key_t *k = clib_toeplitz_hash_key_init (0, 0);
457
458 test_perf_event_enable (fd);
459 for (int i = 0; i < n; i++)
460 clib_toeplitz_hash_x4 (k, d0 + i * 12, d1 + i * 12, d2 + i * 12,
461 d3 + i * 12, h0 + i, h1 + i, h2 + i, h3 + i, 12);
462 test_perf_event_disable (fd);
463
464 clib_toeplitz_hash_key_free (k);
465 test_mem_free (d0);
466 test_mem_free (d1);
467 test_mem_free (d2);
468 test_mem_free (d3);
469 test_mem_free (h0);
470 test_mem_free (h1);
471 test_mem_free (h2);
472 test_mem_free (h3);
473}
474
475void __test_perf_fn
476perftest_fixed_36byte_x4 (int fd, test_perf_t *tp)
477{
478 u32 n = tp->n_ops / 4;
479 u8 *d0 = test_mem_alloc_and_splat (36, n, (void *) &ip4_tests[0].key);
480 u8 *d1 = test_mem_alloc_and_splat (36, n, (void *) &ip4_tests[1].key);
481 u8 *d2 = test_mem_alloc_and_splat (36, n, (void *) &ip4_tests[2].key);
482 u8 *d3 = test_mem_alloc_and_splat (36, n, (void *) &ip4_tests[3].key);
483 u32 *h0 = test_mem_alloc (4 * n);
484 u32 *h1 = test_mem_alloc (4 * n);
485 u32 *h2 = test_mem_alloc (4 * n);
486 u32 *h3 = test_mem_alloc (4 * n);
487 clib_toeplitz_hash_key_t *k = clib_toeplitz_hash_key_init (0, 0);
488
489 test_perf_event_enable (fd);
490 for (int i = 0; i < n; i++)
491 clib_toeplitz_hash_x4 (k, d0 + i * 36, d1 + i * 36, d2 + i * 36,
492 d3 + i * 36, h0 + i, h1 + i, h2 + i, h3 + i, 36);
493 test_perf_event_disable (fd);
494
495 clib_toeplitz_hash_key_free (k);
496 test_mem_free (d0);
497 test_mem_free (d1);
498 test_mem_free (d2);
499 test_mem_free (d3);
500 test_mem_free (h0);
501 test_mem_free (h1);
502 test_mem_free (h2);
503 test_mem_free (h3);
504}
505
506void __test_perf_fn
507perftest_variable_size_x4 (int fd, test_perf_t *tp)
508{
509 u32 key_len, n_keys, n = tp->n_ops / 4;
510 u8 *key;
511 u8 *d0 = test_mem_alloc (n);
512 u8 *d1 = test_mem_alloc (n);
513 u8 *d2 = test_mem_alloc (n);
514 u8 *d3 = test_mem_alloc (n);
515 u32 *h0 = test_mem_alloc (sizeof (u32));
516 u32 *h1 = test_mem_alloc (sizeof (u32));
517 u32 *h2 = test_mem_alloc (sizeof (u32));
518 u32 *h3 = test_mem_alloc (sizeof (u32));
519 clib_toeplitz_hash_key_t *k = clib_toeplitz_hash_key_init (0, 0);
520
521 k = clib_toeplitz_hash_key_init (0, 0);
522 key_len = k->key_length;
523 n_keys = ((n + 4) / k->key_length) + 1;
524 key = test_mem_alloc_and_splat (n_keys, key_len, k->data);
525 clib_toeplitz_hash_key_free (k);
526 k = clib_toeplitz_hash_key_init (key, key_len * n_keys);
527
528 test_perf_event_enable (fd);
529 clib_toeplitz_hash_x4 (k, d0, d1, d2, d3, h0, h1, h2, h3, n);
530 test_perf_event_disable (fd);
531
532 clib_toeplitz_hash_key_free (k);
533 test_mem_free (key);
534 test_mem_free (d0);
535 test_mem_free (d1);
536 test_mem_free (d2);
537 test_mem_free (d3);
538 test_mem_free (h0);
539 test_mem_free (h1);
540 test_mem_free (h2);
541 test_mem_free (h3);
542}
543
544REGISTER_TEST (clib_toeplitz_hash_x4) = {
545 .name = "clib_toeplitz_hash_x4",
546 .fn = test_clib_toeplitz_hash_x4,
547 .perf_tests = PERF_TESTS ({ .name = "fixed_12",
548 .op_name = "12B Tuple",
549 .n_ops = 1024,
550 .fn = perftest_fixed_12byte_x4 },
551 { .name = "fixed_36",
552 .op_name = "36B Tuple",
553 .n_ops = 1024,
554 .fn = perftest_fixed_36byte_x4 },
555 { .name = "variable_size",
556 .op_name = "Byte",
557 .n_ops = 16384,
558 .fn = perftest_variable_size_x4 }),
559};