Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <stdint.h>
7 : : #include <stdlib.h>
8 : : #include <string.h>
9 : :
10 : : #include <rte_cycles.h>
11 : : #include <rte_random.h>
12 : : #include <rte_malloc.h>
13 : : #include <rte_memory.h>
14 : : #include <rte_fib6.h>
15 : :
16 : : #include "test.h"
17 : :
18 : : #include "test_lpm6_data.h"
19 : :
20 : : #define TEST_FIB_ASSERT(cond) do { \
21 : : if (!(cond)) { \
22 : : printf("Error at line %d:\n", __LINE__); \
23 : : return -1; \
24 : : } \
25 : : } while (0)
26 : :
27 : : #define ITERATIONS (1 << 10)
28 : : #define BATCH_SIZE 100000
29 : : #define NUMBER_TBL8S (1 << 16)
30 : :
31 : : static void
32 : 0 : print_route_distribution(const struct rules_tbl_entry *table, uint32_t n)
33 : : {
34 : : unsigned int i, j;
35 : :
36 : : printf("Route distribution per prefix width:\n");
37 : : printf("DEPTH QUANTITY (PERCENT)\n");
38 : : printf("---------------------------\n");
39 : :
40 : : /* Count depths. */
41 [ # # ]: 0 : for (i = 1; i <= 128; i++) {
42 : : unsigned int depth_counter = 0;
43 : : double percent_hits;
44 : :
45 [ # # ]: 0 : for (j = 0; j < n; j++)
46 [ # # ]: 0 : if (table[j].depth == (uint8_t) i)
47 : 0 : depth_counter++;
48 : :
49 : 0 : percent_hits = ((double)depth_counter)/((double)n) * 100;
50 : : printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits);
51 : : }
52 : : printf("\n");
53 : 0 : }
54 : :
55 : : static inline uint8_t
56 : : bits_in_nh(uint8_t nh_sz)
57 : : {
58 : : return 8 * (1 << nh_sz);
59 : : }
60 : :
61 : : static inline uint64_t
62 : : get_max_nh(uint8_t nh_sz)
63 : : {
64 : : return ((1ULL << (bits_in_nh(nh_sz) - 1)) - 1);
65 : : }
66 : :
67 : : static int
68 : 0 : test_fib6_perf(void)
69 : : {
70 : : struct rte_fib6 *fib = NULL;
71 : : struct rte_fib6_conf conf;
72 : : uint64_t begin, total_time;
73 : : unsigned int i, j;
74 : : uint64_t next_hop_add;
75 : : int status = 0;
76 : : int64_t count = 0;
77 : :
78 : 0 : struct rte_ipv6_addr *ip_batch = rte_calloc("ip_batch",
79 : : NUM_IPS_ENTRIES, sizeof(struct rte_ipv6_addr), 0);
80 [ # # ]: 0 : TEST_FIB_ASSERT(ip_batch != NULL);
81 : :
82 : 0 : uint64_t *next_hops = rte_calloc("next_hops",
83 : : NUM_IPS_ENTRIES, sizeof(uint64_t), 0);
84 [ # # ]: 0 : TEST_FIB_ASSERT(next_hops != NULL);
85 : :
86 : 0 : conf.type = RTE_FIB6_TRIE;
87 : 0 : conf.default_nh = 0;
88 : 0 : conf.max_routes = 1000000;
89 : 0 : conf.rib_ext_sz = 0;
90 : 0 : conf.trie.nh_sz = RTE_FIB6_TRIE_4B;
91 : 0 : conf.trie.num_tbl8 = RTE_MIN(get_max_nh(conf.trie.nh_sz), 1000000U);
92 : :
93 : : printf("No. routes = %u\n", (unsigned int) NUM_ROUTE_ENTRIES);
94 : :
95 : 0 : print_route_distribution(large_route_table,
96 : : (uint32_t)NUM_ROUTE_ENTRIES);
97 : :
98 : : /* Only generate IPv6 address of each item in large IPS table,
99 : : * here next_hop is not needed.
100 : : */
101 : 0 : generate_large_ips_table(0);
102 : :
103 : 0 : fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &conf);
104 [ # # ]: 0 : TEST_FIB_ASSERT(fib != NULL);
105 : :
106 : : /* Measure add. */
107 : : begin = rte_rdtsc();
108 : :
109 [ # # ]: 0 : for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
110 : 0 : next_hop_add = (i & ((1 << 14) - 1)) + 1;
111 [ # # ]: 0 : if (rte_fib6_add(fib, &large_route_table[i].ip,
112 : 0 : large_route_table[i].depth, next_hop_add) == 0)
113 : 0 : status++;
114 : : }
115 : : /* End Timer. */
116 : 0 : total_time = rte_rdtsc() - begin;
117 : :
118 : : printf("Unique added entries = %d\n", status);
119 : 0 : printf("Average FIB Add: %g cycles\n",
120 : 0 : (double)total_time / NUM_ROUTE_ENTRIES);
121 : :
122 : : /* Measure bulk Lookup */
123 : : total_time = 0;
124 : : count = 0;
125 : :
126 [ # # ]: 0 : for (i = 0; i < NUM_IPS_ENTRIES; i++)
127 : 0 : ip_batch[i] = large_ips_table[i].ip;
128 : :
129 [ # # ]: 0 : for (i = 0; i < ITERATIONS; i++) {
130 : :
131 : : /* Lookup per batch */
132 : : begin = rte_rdtsc();
133 : 0 : rte_fib6_lookup_bulk(fib, ip_batch, next_hops, NUM_IPS_ENTRIES);
134 : 0 : total_time += rte_rdtsc() - begin;
135 : :
136 [ # # ]: 0 : for (j = 0; j < NUM_IPS_ENTRIES; j++)
137 [ # # ]: 0 : if (next_hops[j] == 0)
138 : 0 : count++;
139 : : }
140 : 0 : printf("BULK FIB Lookup: %.1f cycles (fails = %.1f%%)\n",
141 : 0 : (double)total_time / ((double)ITERATIONS * BATCH_SIZE),
142 : 0 : (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
143 : :
144 : : /* Delete */
145 : : status = 0;
146 : : begin = rte_rdtsc();
147 : :
148 [ # # ]: 0 : for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
149 : : /* rte_fib_delete(fib, ip, depth) */
150 : 0 : status += rte_fib6_delete(fib, &large_route_table[i].ip,
151 : 0 : large_route_table[i].depth);
152 : : }
153 : :
154 : 0 : total_time = rte_rdtsc() - begin;
155 : :
156 : 0 : printf("Average FIB Delete: %g cycles\n",
157 : 0 : (double)total_time / NUM_ROUTE_ENTRIES);
158 : :
159 : 0 : rte_fib6_free(fib);
160 : :
161 : 0 : rte_free(next_hops);
162 : 0 : rte_free(ip_batch);
163 : :
164 : 0 : return 0;
165 : : }
166 : :
167 : 253 : REGISTER_PERF_TEST(fib6_perf_autotest, test_fib6_perf);
|