]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/dpdk/test/test/test_table_tables.c
update download target update for octopus release
[ceph.git] / ceph / src / spdk / dpdk / test / test / test_table_tables.c
CommitLineData
11fdf7f2
TL
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2016 Intel Corporation
7c673cae
FG
3 */
4
5#include <string.h>
6#include <rte_byteorder.h>
7#include <rte_table_lpm_ipv6.h>
8#include <rte_lru.h>
9#include <rte_cycles.h>
10#include "test_table_tables.h"
11#include "test_table.h"
12
13table_test table_tests[] = {
14 test_table_stub,
15 test_table_array,
16 test_table_lpm,
17 test_table_lpm_ipv6,
18 test_table_hash_lru,
19 test_table_hash_ext,
20 test_table_hash_cuckoo,
21};
22
23#define PREPARE_PACKET(mbuf, value) do { \
24 uint32_t *k32, *signature; \
25 uint8_t *key; \
26 mbuf = rte_pktmbuf_alloc(pool); \
27 signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, \
28 APP_METADATA_OFFSET(0)); \
29 key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \
30 APP_METADATA_OFFSET(32)); \
31 memset(key, 0, 32); \
32 k32 = (uint32_t *) key; \
33 k32[0] = (value); \
11fdf7f2 34 *signature = pipeline_test_hash(key, NULL, 0, 0); \
7c673cae
FG
35} while (0)
36
37unsigned n_table_tests = RTE_DIM(table_tests);
38
39/* Function prototypes */
40static int
11fdf7f2 41test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size);
7c673cae 42static int
11fdf7f2 43test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size);
7c673cae
FG
44
45struct rte_bucket_4_8 {
46 /* Cache line 0 */
47 uint64_t signature;
48 uint64_t lru_list;
49 struct rte_bucket_4_8 *next;
50 uint64_t next_valid;
51 uint64_t key[4];
52 /* Cache line 1 */
53 uint8_t data[0];
54};
55
56#if RTE_TABLE_HASH_LRU_STRATEGY == 3
57uint64_t shuffles = 0xfffffffdfffbfff9ULL;
58#else
59uint64_t shuffles = 0x0003000200010000ULL;
60#endif
61
62static int test_lru_update(void)
63{
64 struct rte_bucket_4_8 b;
65 struct rte_bucket_4_8 *bucket;
66 uint32_t i;
67 uint64_t pos;
68 uint64_t iterations;
69 uint64_t j;
70 int poss;
71
72 printf("---------------------------\n");
73 printf("Testing lru_update macro...\n");
74 printf("---------------------------\n");
75 bucket = &b;
76 iterations = 10;
77#if RTE_TABLE_HASH_LRU_STRATEGY == 3
78 bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL;
79#else
80 bucket->lru_list = 0x0000000100020003ULL;
81#endif
82 poss = 0;
83 for (j = 0; j < iterations; j++)
84 for (i = 0; i < 9; i++) {
85 uint32_t idx = i >> 1;
86 lru_update(bucket, idx);
87 pos = lru_pos(bucket);
88 poss += pos;
89 printf("%s: %d lru_list=%016"PRIx64", upd=%d, "
90 "pos=%"PRIx64"\n",
91 __func__, i, bucket->lru_list, i>>1, pos);
92 }
93
94 if (bucket->lru_list != shuffles) {
95 printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016"
96 PRIx64"\n",
97 __func__, i, bucket->lru_list, shuffles);
98 return -1;
99 }
100 printf("%s: output checksum of results =%d\n",
101 __func__, poss);
102#if 0
103 if (poss != 126) {
104 printf("%s: ERROR output checksum of results =%d expected %d\n",
105 __func__, poss, 126);
106 return -1;
107 }
108#endif
109
110 fflush(stdout);
111
112 uint64_t sc_start = rte_rdtsc();
113 iterations = 100000000;
114 poss = 0;
115 for (j = 0; j < iterations; j++) {
116 for (i = 0; i < 4; i++) {
117 lru_update(bucket, i);
118 pos |= bucket->lru_list;
119 }
120 }
121 uint64_t sc_end = rte_rdtsc();
122
123 printf("%s: output checksum of results =%llu\n",
124 __func__, (long long unsigned int)pos);
125 printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n",
126 __func__, sc_start, sc_end);
127 printf("\nlru_update: %lu cycles per loop iteration.\n\n",
128 (long unsigned int)((sc_end-sc_start)/(iterations*4)));
129
130 return 0;
131}
132
133/* Table tests */
134int
135test_table_stub(void)
136{
137 int i;
138 uint64_t expected_mask = 0, result_mask;
139 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
140 void *table;
141 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
142
143 /* Create */
144 table = rte_table_stub_ops.f_create(NULL, 0, 1);
145 if (table == NULL)
146 return -1;
147
148 /* Traffic flow */
149 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
150 if (i % 2 == 0)
151 PREPARE_PACKET(mbufs[i], 0xadadadad);
152 else
153 PREPARE_PACKET(mbufs[i], 0xadadadab);
154
155 expected_mask = 0;
156 rte_table_stub_ops.f_lookup(table, mbufs, -1,
157 &result_mask, (void **)entries);
158 if (result_mask != expected_mask)
159 return -2;
160
161 /* Free resources */
162 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
163 rte_pktmbuf_free(mbufs[i]);
164
165 return 0;
166}
167
168int
169test_table_array(void)
170{
171 int status, i;
172 uint64_t result_mask;
173 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
174 void *table;
175 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
176 char entry1, entry2;
177 void *entry_ptr;
178 int key_found;
179
180 /* Initialize params and create tables */
181 struct rte_table_array_params array_params = {
182 .n_entries = 7,
183 .offset = APP_METADATA_OFFSET(1)
184 };
185
186 table = rte_table_array_ops.f_create(NULL, 0, 1);
187 if (table != NULL)
188 return -1;
189
190 array_params.n_entries = 0;
191
192 table = rte_table_array_ops.f_create(&array_params, 0, 1);
193 if (table != NULL)
194 return -2;
195
196 array_params.n_entries = 7;
197
198 table = rte_table_array_ops.f_create(&array_params, 0, 1);
199 if (table != NULL)
200 return -3;
201
202 array_params.n_entries = 1 << 24;
203 array_params.offset = APP_METADATA_OFFSET(1);
204
205 table = rte_table_array_ops.f_create(&array_params, 0, 1);
206 if (table == NULL)
207 return -4;
208
209 array_params.offset = APP_METADATA_OFFSET(32);
210
211 table = rte_table_array_ops.f_create(&array_params, 0, 1);
212 if (table == NULL)
213 return -5;
214
215 /* Free */
216 status = rte_table_array_ops.f_free(table);
217 if (status < 0)
218 return -6;
219
220 status = rte_table_array_ops.f_free(NULL);
221 if (status == 0)
222 return -7;
223
224 /* Add */
225 struct rte_table_array_key array_key_1 = {
226 .pos = 10,
227 };
228 struct rte_table_array_key array_key_2 = {
229 .pos = 20,
230 };
231 entry1 = 'A';
232 entry2 = 'B';
233
234 table = rte_table_array_ops.f_create(&array_params, 0, 1);
235 if (table == NULL)
236 return -8;
237
238 status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1,
239 &key_found, &entry_ptr);
240 if (status == 0)
241 return -9;
242
243 status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL,
244 &key_found, &entry_ptr);
245 if (status == 0)
246 return -10;
247
248 status = rte_table_array_ops.f_add(table, (void *) &array_key_1,
249 &entry1, &key_found, &entry_ptr);
250 if (status != 0)
251 return -11;
252
253 /* Traffic flow */
254 status = rte_table_array_ops.f_add(table, (void *) &array_key_2,
255 &entry2, &key_found, &entry_ptr);
256 if (status != 0)
257 return -12;
258
259 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
260 if (i % 2 == 0)
261 PREPARE_PACKET(mbufs[i], 10);
262 else
263 PREPARE_PACKET(mbufs[i], 20);
264
265 rte_table_array_ops.f_lookup(table, mbufs, -1,
266 &result_mask, (void **)entries);
267
268 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
269 if (i % 2 == 0 && *entries[i] != 'A')
270 return -13;
271 else
272 if (i % 2 == 1 && *entries[i] != 'B')
273 return -13;
274
275 /* Free resources */
276 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
277 rte_pktmbuf_free(mbufs[i]);
278
279 status = rte_table_array_ops.f_free(table);
280
281 return 0;
282}
283
284int
285test_table_lpm(void)
286{
287 int status, i;
288 uint64_t expected_mask = 0, result_mask;
289 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
290 void *table;
291 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
292 char entry;
293 void *entry_ptr;
294 int key_found;
295 uint32_t entry_size = 1;
296
297 /* Initialize params and create tables */
298 struct rte_table_lpm_params lpm_params = {
299 .name = "LPM",
300 .n_rules = 1 << 24,
301 .number_tbl8s = 1 << 8,
302 .flags = 0,
303 .entry_unique_size = entry_size,
304 .offset = APP_METADATA_OFFSET(1)
305 };
306
307 table = rte_table_lpm_ops.f_create(NULL, 0, entry_size);
308 if (table != NULL)
309 return -1;
310
311 lpm_params.name = NULL;
312
313 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
314 if (table != NULL)
315 return -2;
316
317 lpm_params.name = "LPM";
318 lpm_params.n_rules = 0;
319
320 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
321 if (table != NULL)
322 return -3;
323
324 lpm_params.n_rules = 1 << 24;
325 lpm_params.offset = APP_METADATA_OFFSET(32);
326 lpm_params.entry_unique_size = 0;
327
328 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
329 if (table != NULL)
330 return -4;
331
332 lpm_params.entry_unique_size = entry_size + 1;
333
334 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
335 if (table != NULL)
336 return -5;
337
338 lpm_params.entry_unique_size = entry_size;
339
340 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
341 if (table == NULL)
342 return -6;
343
344 /* Free */
345 status = rte_table_lpm_ops.f_free(table);
346 if (status < 0)
347 return -7;
348
349 status = rte_table_lpm_ops.f_free(NULL);
350 if (status == 0)
351 return -8;
352
353 /* Add */
354 struct rte_table_lpm_key lpm_key;
355 lpm_key.ip = 0xadadadad;
356
357 table = rte_table_lpm_ops.f_create(&lpm_params, 0, 1);
358 if (table == NULL)
359 return -9;
360
361 status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found,
362 &entry_ptr);
363 if (status == 0)
364 return -10;
365
366 status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found,
367 &entry_ptr);
368 if (status == 0)
369 return -11;
370
371 status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found,
372 &entry_ptr);
373 if (status == 0)
374 return -12;
375
376 lpm_key.depth = 0;
377 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
378 &entry_ptr);
379 if (status == 0)
380 return -13;
381
382 lpm_key.depth = 33;
383 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
384 &entry_ptr);
385 if (status == 0)
386 return -14;
387
388 lpm_key.depth = 16;
389 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
390 &entry_ptr);
391 if (status != 0)
392 return -15;
393
394 /* Delete */
395 status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL);
396 if (status == 0)
397 return -16;
398
399 status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL);
400 if (status == 0)
401 return -17;
402
403 lpm_key.depth = 0;
404 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
405 if (status == 0)
406 return -18;
407
408 lpm_key.depth = 33;
409 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
410 if (status == 0)
411 return -19;
412
413 lpm_key.depth = 16;
414 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
415 if (status != 0)
416 return -20;
417
418 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
419 if (status != 0)
420 return -21;
421
422 /* Traffic flow */
423 entry = 'A';
424 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
425 &entry_ptr);
426 if (status < 0)
427 return -22;
428
429 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
430 if (i % 2 == 0) {
431 expected_mask |= (uint64_t)1 << i;
432 PREPARE_PACKET(mbufs[i], 0xadadadad);
433 } else
434 PREPARE_PACKET(mbufs[i], 0xadadadab);
435
436 rte_table_lpm_ops.f_lookup(table, mbufs, -1,
437 &result_mask, (void **)entries);
438 if (result_mask != expected_mask)
439 return -23;
440
441 /* Free resources */
442 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
443 rte_pktmbuf_free(mbufs[i]);
444
445 status = rte_table_lpm_ops.f_free(table);
446
447 return 0;
448}
449
450int
451test_table_lpm_ipv6(void)
452{
453 int status, i;
454 uint64_t expected_mask = 0, result_mask;
455 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
456 void *table;
457 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
458 char entry;
459 void *entry_ptr;
460 int key_found;
461 uint32_t entry_size = 1;
462
463 /* Initialize params and create tables */
464 struct rte_table_lpm_ipv6_params lpm_params = {
465 .name = "LPM",
466 .n_rules = 1 << 24,
467 .number_tbl8s = 1 << 21,
468 .entry_unique_size = entry_size,
469 .offset = APP_METADATA_OFFSET(32)
470 };
471
472 table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size);
473 if (table != NULL)
474 return -1;
475
476 lpm_params.name = NULL;
477
478 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
479 if (table != NULL)
480 return -2;
481
482 lpm_params.name = "LPM";
483 lpm_params.n_rules = 0;
484
485 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
486 if (table != NULL)
487 return -3;
488
489 lpm_params.n_rules = 1 << 24;
490 lpm_params.number_tbl8s = 0;
491 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
492 if (table != NULL)
493 return -4;
494
495 lpm_params.number_tbl8s = 1 << 21;
496 lpm_params.entry_unique_size = 0;
497 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
498 if (table != NULL)
499 return -5;
500
501 lpm_params.entry_unique_size = entry_size + 1;
502 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
503 if (table != NULL)
504 return -6;
505
506 lpm_params.entry_unique_size = entry_size;
507 lpm_params.offset = APP_METADATA_OFFSET(32);
508
509 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
510 if (table == NULL)
511 return -7;
512
513 /* Free */
514 status = rte_table_lpm_ipv6_ops.f_free(table);
515 if (status < 0)
516 return -8;
517
518 status = rte_table_lpm_ipv6_ops.f_free(NULL);
519 if (status == 0)
520 return -9;
521
522 /* Add */
523 struct rte_table_lpm_ipv6_key lpm_key;
524
525 lpm_key.ip[0] = 0xad;
526 lpm_key.ip[1] = 0xad;
527 lpm_key.ip[2] = 0xad;
528 lpm_key.ip[3] = 0xad;
529
530 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
531 if (table == NULL)
532 return -10;
533
534 status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry,
535 &key_found, &entry_ptr);
536 if (status == 0)
537 return -11;
538
539 status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found,
540 &entry_ptr);
541 if (status == 0)
542 return -12;
543
544 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found,
545 &entry_ptr);
546 if (status == 0)
547 return -13;
548
549 lpm_key.depth = 0;
550 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
551 &key_found, &entry_ptr);
552 if (status == 0)
553 return -14;
554
555 lpm_key.depth = 129;
556 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
557 &key_found, &entry_ptr);
558 if (status == 0)
559 return -15;
560
561 lpm_key.depth = 16;
562 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
563 &key_found, &entry_ptr);
564 if (status != 0)
565 return -16;
566
567 /* Delete */
568 status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found,
569 NULL);
570 if (status == 0)
571 return -17;
572
573 status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL);
574 if (status == 0)
575 return -18;
576
577 lpm_key.depth = 0;
578 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
579 NULL);
580 if (status == 0)
581 return -19;
582
583 lpm_key.depth = 129;
584 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
585 NULL);
586 if (status == 0)
587 return -20;
588
589 lpm_key.depth = 16;
590 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
591 NULL);
592 if (status != 0)
593 return -21;
594
595 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
596 NULL);
597 if (status != 0)
598 return -22;
599
600 /* Traffic flow */
601 entry = 'A';
602 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
603 &key_found, &entry_ptr);
604 if (status < 0)
605 return -23;
606
607 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
608 if (i % 2 == 0) {
609 expected_mask |= (uint64_t)1 << i;
610 PREPARE_PACKET(mbufs[i], 0xadadadad);
611 } else
612 PREPARE_PACKET(mbufs[i], 0xadadadab);
613
614 rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1,
615 &result_mask, (void **)entries);
616 if (result_mask != expected_mask)
617 return -24;
618
619 /* Free resources */
620 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
621 rte_pktmbuf_free(mbufs[i]);
622
623 status = rte_table_lpm_ipv6_ops.f_free(table);
624
625 return 0;
626}
627
628static int
11fdf7f2 629test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size)
7c673cae
FG
630{
631 int status, i;
632 uint64_t expected_mask = 0, result_mask;
633 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
634 void *table;
635 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
636 char entry;
637 void *entry_ptr;
638 int key_found;
639
640 /* Initialize params and create tables */
11fdf7f2
TL
641 struct rte_table_hash_params hash_params = {
642 .name = "TABLE",
643 .key_size = key_size,
7c673cae
FG
644 .key_offset = APP_METADATA_OFFSET(32),
645 .key_mask = NULL,
11fdf7f2
TL
646 .n_keys = 1 << 10,
647 .n_buckets = 1 << 10,
648 .f_hash = pipeline_test_hash,
649 .seed = 0,
7c673cae
FG
650 };
651
11fdf7f2 652 hash_params.n_keys = 0;
7c673cae
FG
653
654 table = ops->f_create(&hash_params, 0, 1);
655 if (table != NULL)
656 return -1;
657
11fdf7f2 658 hash_params.n_keys = 1 << 10;
7c673cae
FG
659 hash_params.f_hash = NULL;
660
661 table = ops->f_create(&hash_params, 0, 1);
662 if (table != NULL)
663 return -4;
664
665 hash_params.f_hash = pipeline_test_hash;
666
667 table = ops->f_create(&hash_params, 0, 1);
668 if (table == NULL)
669 return -5;
670
671 /* Free */
672 status = ops->f_free(table);
673 if (status < 0)
674 return -6;
675
676 status = ops->f_free(NULL);
677 if (status == 0)
678 return -7;
679
680 /* Add */
681 uint8_t key[32];
682 uint32_t *k32 = (uint32_t *) &key;
683
684 memset(key, 0, 32);
685 k32[0] = rte_be_to_cpu_32(0xadadadad);
686
687 table = ops->f_create(&hash_params, 0, 1);
688 if (table == NULL)
689 return -8;
690
691 entry = 'A';
692 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
693 if (status != 0)
694 return -9;
695
696 /* Delete */
697 status = ops->f_delete(table, &key, &key_found, NULL);
698 if (status != 0)
699 return -10;
700
701 status = ops->f_delete(table, &key, &key_found, NULL);
702 if (status != 0)
703 return -11;
704
705 /* Traffic flow */
706 entry = 'A';
707 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
708 if (status < 0)
709 return -12;
710
711 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
712 if (i % 2 == 0) {
713 expected_mask |= (uint64_t)1 << i;
714 PREPARE_PACKET(mbufs[i], 0xadadadad);
715 } else
716 PREPARE_PACKET(mbufs[i], 0xadadadab);
717
718 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
719 if (result_mask != expected_mask)
720 return -13;
721
722 /* Free resources */
723 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
724 rte_pktmbuf_free(mbufs[i]);
725
726 status = ops->f_free(table);
727
728 return 0;
729}
730
731static int
11fdf7f2 732test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size)
7c673cae
FG
733{
734 int status, i;
735 uint64_t expected_mask = 0, result_mask;
736 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
737 void *table;
738 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
739 char entry;
740 int key_found;
741 void *entry_ptr;
742
743 /* Initialize params and create tables */
11fdf7f2
TL
744 struct rte_table_hash_params hash_params = {
745 .name = "TABLE",
746 .key_size = key_size,
7c673cae
FG
747 .key_offset = APP_METADATA_OFFSET(32),
748 .key_mask = NULL,
11fdf7f2
TL
749 .n_keys = 1 << 10,
750 .n_buckets = 1 << 10,
751 .f_hash = pipeline_test_hash,
752 .seed = 0,
7c673cae
FG
753 };
754
11fdf7f2 755 hash_params.n_keys = 0;
7c673cae
FG
756
757 table = ops->f_create(&hash_params, 0, 1);
758 if (table != NULL)
759 return -1;
760
11fdf7f2 761 hash_params.n_keys = 1 << 10;
7c673cae
FG
762 hash_params.key_offset = APP_METADATA_OFFSET(1);
763
764 table = ops->f_create(&hash_params, 0, 1);
765 if (table == NULL)
766 return -3;
767
768 hash_params.key_offset = APP_METADATA_OFFSET(32);
769 hash_params.f_hash = NULL;
770
771 table = ops->f_create(&hash_params, 0, 1);
772 if (table != NULL)
773 return -4;
774
775 hash_params.f_hash = pipeline_test_hash;
776
777 table = ops->f_create(&hash_params, 0, 1);
778 if (table == NULL)
779 return -5;
780
781 /* Free */
782 status = ops->f_free(table);
783 if (status < 0)
784 return -6;
785
786 status = ops->f_free(NULL);
787 if (status == 0)
788 return -7;
789
790 /* Add */
791 uint8_t key[32];
792 uint32_t *k32 = (uint32_t *) &key;
793
794 memset(key, 0, 32);
795 k32[0] = rte_be_to_cpu_32(0xadadadad);
796
797 table = ops->f_create(&hash_params, 0, 1);
798 if (table == NULL)
799 return -8;
800
801 entry = 'A';
802 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
803 if (status != 0)
804 return -9;
805
806 /* Delete */
807 status = ops->f_delete(table, &key, &key_found, NULL);
808 if (status != 0)
809 return -10;
810
811 status = ops->f_delete(table, &key, &key_found, NULL);
812 if (status != 0)
813 return -11;
814
815 /* Traffic flow */
816 entry = 'A';
817 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
818 if (status < 0)
819 return -12;
820
821 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
822 if (i % 2 == 0) {
823 expected_mask |= (uint64_t)1 << i;
824 PREPARE_PACKET(mbufs[i], 0xadadadad);
825 } else
826 PREPARE_PACKET(mbufs[i], 0xadadadab);
827
828 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
829 if (result_mask != expected_mask)
830 return -13;
831
832 /* Free resources */
833 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
834 rte_pktmbuf_free(mbufs[i]);
835
836 status = ops->f_free(table);
837
838 return 0;
839}
840
841int
842test_table_hash_lru(void)
843{
844 int status;
845
7c673cae 846 status = test_table_hash_lru_generic(
11fdf7f2
TL
847 &rte_table_hash_key8_lru_ops,
848 8);
7c673cae
FG
849 if (status < 0)
850 return status;
851
11fdf7f2
TL
852 status = test_table_hash_lru_generic(
853 &rte_table_hash_key16_lru_ops,
854 16);
7c673cae
FG
855 if (status < 0)
856 return status;
857
11fdf7f2
TL
858 status = test_table_hash_lru_generic(
859 &rte_table_hash_key32_lru_ops,
860 32);
7c673cae
FG
861 if (status < 0)
862 return status;
863
864 status = test_lru_update();
865 if (status < 0)
866 return status;
867
868 return 0;
869}
870
871int
872test_table_hash_ext(void)
873{
874 int status;
875
11fdf7f2 876 status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops, 8);
7c673cae
FG
877 if (status < 0)
878 return status;
879
11fdf7f2 880 status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops, 16);
7c673cae
FG
881 if (status < 0)
882 return status;
883
11fdf7f2 884 status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops, 32);
7c673cae
FG
885 if (status < 0)
886 return status;
887
888 return 0;
889}
890
891
892int
893test_table_hash_cuckoo(void)
894{
895 int status, i;
896 uint64_t expected_mask = 0, result_mask;
897 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
898 void *table;
899 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
900 char entry;
901 void *entry_ptr;
902 int key_found;
903 uint32_t entry_size = 1;
904
905 /* Initialize params and create tables */
906 struct rte_table_hash_cuckoo_params cuckoo_params = {
11fdf7f2 907 .name = "TABLE",
7c673cae 908 .key_size = 32,
7c673cae 909 .key_offset = APP_METADATA_OFFSET(32),
11fdf7f2
TL
910 .key_mask = NULL,
911 .n_keys = 1 << 16,
912 .n_buckets = 1 << 16,
913 .f_hash = pipeline_test_hash_cuckoo,
914 .seed = 0,
7c673cae
FG
915 };
916
11fdf7f2 917 table = rte_table_hash_cuckoo_ops.f_create(NULL, 0, entry_size);
7c673cae
FG
918 if (table != NULL)
919 return -1;
920
921 cuckoo_params.key_size = 0;
922
11fdf7f2 923 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
7c673cae
FG
924 0, entry_size);
925 if (table != NULL)
926 return -2;
927
928 cuckoo_params.key_size = 32;
929 cuckoo_params.n_keys = 0;
930
11fdf7f2 931 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
7c673cae
FG
932 0, entry_size);
933 if (table != NULL)
934 return -3;
935
936 cuckoo_params.n_keys = 1 << 24;
937 cuckoo_params.f_hash = NULL;
938
11fdf7f2 939 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
7c673cae
FG
940 0, entry_size);
941 if (table != NULL)
942 return -4;
943
11fdf7f2 944 cuckoo_params.f_hash = pipeline_test_hash_cuckoo;
7c673cae
FG
945 cuckoo_params.name = NULL;
946
11fdf7f2 947 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
7c673cae
FG
948 0, entry_size);
949 if (table != NULL)
950 return -5;
951
952 cuckoo_params.name = "CUCKOO";
953
11fdf7f2 954 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
7c673cae
FG
955 0, entry_size);
956 if (table == NULL)
957 return -6;
958
959 /* Free */
11fdf7f2 960 status = rte_table_hash_cuckoo_ops.f_free(table);
7c673cae
FG
961 if (status < 0)
962 return -7;
963
11fdf7f2 964 status = rte_table_hash_cuckoo_ops.f_free(NULL);
7c673cae
FG
965 if (status == 0)
966 return -8;
967
968 /* Add */
969 uint8_t key_cuckoo[32];
970 uint32_t *kcuckoo = (uint32_t *) &key_cuckoo;
971
972 memset(key_cuckoo, 0, 32);
973 kcuckoo[0] = rte_be_to_cpu_32(0xadadadad);
974
11fdf7f2 975 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 0, 1);
7c673cae
FG
976 if (table == NULL)
977 return -9;
978
979 entry = 'A';
11fdf7f2 980 status = rte_table_hash_cuckoo_ops.f_add(NULL, &key_cuckoo,
7c673cae
FG
981 &entry, &key_found, &entry_ptr);
982 if (status == 0)
983 return -10;
984
11fdf7f2 985 status = rte_table_hash_cuckoo_ops.f_add(table, NULL, &entry,
7c673cae
FG
986 &key_found, &entry_ptr);
987 if (status == 0)
988 return -11;
989
11fdf7f2 990 status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
7c673cae
FG
991 NULL, &key_found, &entry_ptr);
992 if (status == 0)
993 return -12;
994
11fdf7f2 995 status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
7c673cae
FG
996 &entry, &key_found, &entry_ptr);
997 if (status != 0)
998 return -13;
999
11fdf7f2 1000 status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
7c673cae
FG
1001 &entry, &key_found, &entry_ptr);
1002 if (status != 0)
1003 return -14;
1004
1005 /* Delete */
11fdf7f2 1006 status = rte_table_hash_cuckoo_ops.f_delete(NULL, &key_cuckoo,
7c673cae
FG
1007 &key_found, NULL);
1008 if (status == 0)
1009 return -15;
1010
11fdf7f2 1011 status = rte_table_hash_cuckoo_ops.f_delete(table, NULL,
7c673cae
FG
1012 &key_found, NULL);
1013 if (status == 0)
1014 return -16;
1015
11fdf7f2 1016 status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
7c673cae
FG
1017 &key_found, NULL);
1018 if (status != 0)
1019 return -17;
1020
11fdf7f2 1021 status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
7c673cae
FG
1022 &key_found, NULL);
1023 if (status != -ENOENT)
1024 return -18;
1025
1026 /* Traffic flow */
1027 entry = 'A';
11fdf7f2 1028 status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
7c673cae
FG
1029 &entry, &key_found,
1030 &entry_ptr);
1031 if (status < 0)
1032 return -19;
1033
1034 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
1035 if (i % 2 == 0) {
1036 expected_mask |= (uint64_t)1 << i;
1037 PREPARE_PACKET(mbufs[i], 0xadadadad);
1038 } else
1039 PREPARE_PACKET(mbufs[i], 0xadadadab);
1040
11fdf7f2 1041 rte_table_hash_cuckoo_ops.f_lookup(table, mbufs, -1,
7c673cae
FG
1042 &result_mask, (void **)entries);
1043 if (result_mask != expected_mask)
1044 return -20;
1045
1046 /* Free resources */
1047 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
1048 rte_pktmbuf_free(mbufs[i]);
1049
11fdf7f2 1050 status = rte_table_hash_cuckoo_ops.f_free(table);
7c673cae
FG
1051
1052 return 0;
1053}
1054