10d89a956SVladimir Medvedkin /* SPDX-License-Identifier: BSD-3-Clause 20d89a956SVladimir Medvedkin * Copyright(c) 2010-2014 Intel Corporation 30d89a956SVladimir Medvedkin */ 40d89a956SVladimir Medvedkin 50d89a956SVladimir Medvedkin #include <stdio.h> 60d89a956SVladimir Medvedkin #include <stdint.h> 70d89a956SVladimir Medvedkin #include <stdlib.h> 80d89a956SVladimir Medvedkin #include <string.h> 90d89a956SVladimir Medvedkin 100d89a956SVladimir Medvedkin #include <rte_cycles.h> 110d89a956SVladimir Medvedkin #include <rte_random.h> 120d89a956SVladimir Medvedkin #include <rte_memory.h> 13233b41c2SStephen Hemminger #include <rte_fib6.h> 140d89a956SVladimir Medvedkin 150d89a956SVladimir Medvedkin #include "test.h" 163c60274cSJie Zhou 170d89a956SVladimir Medvedkin #include "test_lpm6_data.h" 180d89a956SVladimir Medvedkin 190d89a956SVladimir Medvedkin #define TEST_FIB_ASSERT(cond) do { \ 200d89a956SVladimir Medvedkin if (!(cond)) { \ 210d89a956SVladimir Medvedkin printf("Error at line %d:\n", __LINE__); \ 220d89a956SVladimir Medvedkin return -1; \ 230d89a956SVladimir Medvedkin } \ 240d89a956SVladimir Medvedkin } while (0) 250d89a956SVladimir Medvedkin 260d89a956SVladimir Medvedkin #define ITERATIONS (1 << 10) 270d89a956SVladimir Medvedkin #define BATCH_SIZE 100000 280d89a956SVladimir Medvedkin #define NUMBER_TBL8S (1 << 16) 290d89a956SVladimir Medvedkin 300d89a956SVladimir Medvedkin static void 310d89a956SVladimir Medvedkin print_route_distribution(const struct rules_tbl_entry *table, uint32_t n) 320d89a956SVladimir Medvedkin { 330d89a956SVladimir Medvedkin unsigned int i, j; 340d89a956SVladimir Medvedkin 350d89a956SVladimir Medvedkin printf("Route distribution per prefix width:\n"); 360d89a956SVladimir Medvedkin printf("DEPTH QUANTITY (PERCENT)\n"); 370d89a956SVladimir Medvedkin printf("---------------------------\n"); 380d89a956SVladimir Medvedkin 390d89a956SVladimir Medvedkin /* Count depths. */ 400d89a956SVladimir Medvedkin for (i = 1; i <= 128; i++) { 410d89a956SVladimir Medvedkin unsigned int depth_counter = 0; 420d89a956SVladimir Medvedkin double percent_hits; 430d89a956SVladimir Medvedkin 440d89a956SVladimir Medvedkin for (j = 0; j < n; j++) 450d89a956SVladimir Medvedkin if (table[j].depth == (uint8_t) i) 460d89a956SVladimir Medvedkin depth_counter++; 470d89a956SVladimir Medvedkin 480d89a956SVladimir Medvedkin percent_hits = ((double)depth_counter)/((double)n) * 100; 490d89a956SVladimir Medvedkin printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits); 500d89a956SVladimir Medvedkin } 510d89a956SVladimir Medvedkin printf("\n"); 520d89a956SVladimir Medvedkin } 530d89a956SVladimir Medvedkin 540d89a956SVladimir Medvedkin static inline uint8_t 550d89a956SVladimir Medvedkin bits_in_nh(uint8_t nh_sz) 560d89a956SVladimir Medvedkin { 570d89a956SVladimir Medvedkin return 8 * (1 << nh_sz); 580d89a956SVladimir Medvedkin } 590d89a956SVladimir Medvedkin 600d89a956SVladimir Medvedkin static inline uint64_t 610d89a956SVladimir Medvedkin get_max_nh(uint8_t nh_sz) 620d89a956SVladimir Medvedkin { 630d89a956SVladimir Medvedkin return ((1ULL << (bits_in_nh(nh_sz) - 1)) - 1); 640d89a956SVladimir Medvedkin } 650d89a956SVladimir Medvedkin 660d89a956SVladimir Medvedkin static int 670d89a956SVladimir Medvedkin test_fib6_perf(void) 680d89a956SVladimir Medvedkin { 690d89a956SVladimir Medvedkin struct rte_fib6 *fib = NULL; 700d89a956SVladimir Medvedkin struct rte_fib6_conf conf; 710d89a956SVladimir Medvedkin uint64_t begin, total_time; 720d89a956SVladimir Medvedkin unsigned int i, j; 730d89a956SVladimir Medvedkin uint64_t next_hop_add; 740d89a956SVladimir Medvedkin int status = 0; 750d89a956SVladimir Medvedkin int64_t count = 0; 76*6cb10a9bSRobin Jarry struct rte_ipv6_addr ip_batch[NUM_IPS_ENTRIES]; 770d89a956SVladimir Medvedkin uint64_t next_hops[NUM_IPS_ENTRIES]; 780d89a956SVladimir Medvedkin 790d89a956SVladimir Medvedkin conf.type = RTE_FIB6_TRIE; 800d89a956SVladimir Medvedkin conf.default_nh = 0; 810d89a956SVladimir Medvedkin conf.max_routes = 1000000; 8211c5b9b5SVladimir Medvedkin conf.rib_ext_sz = 0; 830d89a956SVladimir Medvedkin conf.trie.nh_sz = RTE_FIB6_TRIE_4B; 840d89a956SVladimir Medvedkin conf.trie.num_tbl8 = RTE_MIN(get_max_nh(conf.trie.nh_sz), 1000000U); 850d89a956SVladimir Medvedkin 860d89a956SVladimir Medvedkin printf("No. routes = %u\n", (unsigned int) NUM_ROUTE_ENTRIES); 870d89a956SVladimir Medvedkin 880d89a956SVladimir Medvedkin print_route_distribution(large_route_table, 890d89a956SVladimir Medvedkin (uint32_t)NUM_ROUTE_ENTRIES); 900d89a956SVladimir Medvedkin 910d89a956SVladimir Medvedkin /* Only generate IPv6 address of each item in large IPS table, 920d89a956SVladimir Medvedkin * here next_hop is not needed. 930d89a956SVladimir Medvedkin */ 940d89a956SVladimir Medvedkin generate_large_ips_table(0); 950d89a956SVladimir Medvedkin 960d89a956SVladimir Medvedkin fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &conf); 970d89a956SVladimir Medvedkin TEST_FIB_ASSERT(fib != NULL); 980d89a956SVladimir Medvedkin 990d89a956SVladimir Medvedkin /* Measure add. */ 1000d89a956SVladimir Medvedkin begin = rte_rdtsc(); 1010d89a956SVladimir Medvedkin 1020d89a956SVladimir Medvedkin for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { 1030d89a956SVladimir Medvedkin next_hop_add = (i & ((1 << 14) - 1)) + 1; 104*6cb10a9bSRobin Jarry if (rte_fib6_add(fib, &large_route_table[i].ip, 1050d89a956SVladimir Medvedkin large_route_table[i].depth, next_hop_add) == 0) 1060d89a956SVladimir Medvedkin status++; 1070d89a956SVladimir Medvedkin } 1080d89a956SVladimir Medvedkin /* End Timer. */ 1090d89a956SVladimir Medvedkin total_time = rte_rdtsc() - begin; 1100d89a956SVladimir Medvedkin 1110d89a956SVladimir Medvedkin printf("Unique added entries = %d\n", status); 1120d89a956SVladimir Medvedkin printf("Average FIB Add: %g cycles\n", 1130d89a956SVladimir Medvedkin (double)total_time / NUM_ROUTE_ENTRIES); 1140d89a956SVladimir Medvedkin 1150d89a956SVladimir Medvedkin /* Measure bulk Lookup */ 1160d89a956SVladimir Medvedkin total_time = 0; 1170d89a956SVladimir Medvedkin count = 0; 1180d89a956SVladimir Medvedkin 1190d89a956SVladimir Medvedkin for (i = 0; i < NUM_IPS_ENTRIES; i++) 120*6cb10a9bSRobin Jarry ip_batch[i] = large_ips_table[i].ip; 1210d89a956SVladimir Medvedkin 1220d89a956SVladimir Medvedkin for (i = 0; i < ITERATIONS; i++) { 1230d89a956SVladimir Medvedkin 1240d89a956SVladimir Medvedkin /* Lookup per batch */ 1250d89a956SVladimir Medvedkin begin = rte_rdtsc(); 1260d89a956SVladimir Medvedkin rte_fib6_lookup_bulk(fib, ip_batch, next_hops, NUM_IPS_ENTRIES); 1270d89a956SVladimir Medvedkin total_time += rte_rdtsc() - begin; 1280d89a956SVladimir Medvedkin 1290d89a956SVladimir Medvedkin for (j = 0; j < NUM_IPS_ENTRIES; j++) 1300d89a956SVladimir Medvedkin if (next_hops[j] == 0) 1310d89a956SVladimir Medvedkin count++; 1320d89a956SVladimir Medvedkin } 1330d89a956SVladimir Medvedkin printf("BULK FIB Lookup: %.1f cycles (fails = %.1f%%)\n", 1340d89a956SVladimir Medvedkin (double)total_time / ((double)ITERATIONS * BATCH_SIZE), 1350d89a956SVladimir Medvedkin (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); 1360d89a956SVladimir Medvedkin 1370d89a956SVladimir Medvedkin /* Delete */ 1380d89a956SVladimir Medvedkin status = 0; 1390d89a956SVladimir Medvedkin begin = rte_rdtsc(); 1400d89a956SVladimir Medvedkin 1410d89a956SVladimir Medvedkin for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { 1420d89a956SVladimir Medvedkin /* rte_fib_delete(fib, ip, depth) */ 143*6cb10a9bSRobin Jarry status += rte_fib6_delete(fib, &large_route_table[i].ip, 1440d89a956SVladimir Medvedkin large_route_table[i].depth); 1450d89a956SVladimir Medvedkin } 1460d89a956SVladimir Medvedkin 1470d89a956SVladimir Medvedkin total_time = rte_rdtsc() - begin; 1480d89a956SVladimir Medvedkin 1490d89a956SVladimir Medvedkin printf("Average FIB Delete: %g cycles\n", 1500d89a956SVladimir Medvedkin (double)total_time / NUM_ROUTE_ENTRIES); 1510d89a956SVladimir Medvedkin 1520d89a956SVladimir Medvedkin rte_fib6_free(fib); 1530d89a956SVladimir Medvedkin 1540d89a956SVladimir Medvedkin return 0; 1550d89a956SVladimir Medvedkin } 1560d89a956SVladimir Medvedkin 157e0a8442cSBruce Richardson REGISTER_PERF_TEST(fib6_perf_autotest, test_fib6_perf); 158