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