1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk/env.h" 9 #include "spdk/event.h" 10 #include "spdk/string.h" 11 #include "spdk/thread.h" 12 #include "spdk/util.h" 13 14 #define MAX_NUM_POLLERS 1000 15 16 static int g_time_in_sec; 17 static int g_period_in_usec; 18 static int g_num_pollers; 19 20 static struct spdk_poller *g_timer; 21 static struct spdk_poller *g_pollers[MAX_NUM_POLLERS]; 22 static uint64_t g_run_count; 23 24 static struct spdk_thread_stats g_start_stats; 25 26 static int 27 poller_run(void *arg) 28 { 29 g_run_count++; 30 31 return SPDK_POLLER_BUSY; 32 } 33 34 static void 35 _poller_perf_end(void) 36 { 37 struct spdk_thread_stats end_stats; 38 uint64_t tsc_hz, busy_cyc, poller_cost_cyc, poller_cost_nsec; 39 int i; 40 41 spdk_thread_get_stats(&end_stats); 42 busy_cyc = end_stats.busy_tsc - g_start_stats.busy_tsc; 43 44 tsc_hz = spdk_get_ticks_hz(); 45 46 printf("\r ======================================\n"); 47 48 printf("\r busy:%" PRIu64 " (cyc)\n", busy_cyc); 49 printf("\r total_run_count: %" PRIu64 "\n", g_run_count); 50 printf("\r tsc_hz: %" PRIu64 " (cyc)\n", tsc_hz); 51 52 printf("\r ======================================\n"); 53 54 poller_cost_cyc = busy_cyc / g_run_count; 55 poller_cost_nsec = (poller_cost_cyc * SPDK_SEC_TO_NSEC) / tsc_hz; 56 57 printf("\r poller_cost: %" PRIu64 " (cyc), %" PRIu64 " (nsec)\n", 58 poller_cost_cyc, poller_cost_nsec); 59 60 spdk_poller_unregister(&g_timer); 61 62 for (i = 0; i < g_num_pollers; i++) { 63 spdk_poller_unregister(&g_pollers[i]); 64 } 65 66 spdk_app_stop(0); 67 } 68 69 static int 70 poller_perf_end(void *arg) 71 { 72 _poller_perf_end(); 73 74 return SPDK_POLLER_BUSY; 75 } 76 77 static void 78 poller_perf_start(void *arg1) 79 { 80 int i; 81 82 printf("Running %d pollers for %d seconds with %d microseconds period.\n", 83 g_num_pollers, g_time_in_sec, g_period_in_usec); 84 fflush(stdout); 85 86 for (i = 0; i < g_num_pollers; i++) { 87 g_pollers[i] = SPDK_POLLER_REGISTER(poller_run, NULL, g_period_in_usec); 88 } 89 90 spdk_thread_get_stats(&g_start_stats); 91 92 g_timer = SPDK_POLLER_REGISTER(poller_perf_end, NULL, g_time_in_sec * SPDK_SEC_TO_USEC); 93 } 94 95 static void 96 poller_perf_shutdown_cb(void) 97 { 98 _poller_perf_end(); 99 } 100 101 static int 102 poller_perf_parse_arg(int ch, char *arg) 103 { 104 int tmp; 105 106 tmp = spdk_strtol(optarg, 10); 107 if (tmp < 0) { 108 fprintf(stderr, "Parse failed for the option %c.\n", ch); 109 return tmp; 110 } 111 112 switch (ch) { 113 case 'b': 114 g_num_pollers = tmp; 115 break; 116 case 'l': 117 g_period_in_usec = tmp; 118 break; 119 case 't': 120 g_time_in_sec = tmp; 121 break; 122 default: 123 return -EINVAL; 124 } 125 126 return 0; 127 } 128 129 static void 130 poller_perf_usage(void) 131 { 132 printf(" -b <number> number of pollers\n"); 133 printf(" -l <period> poller period in usec\n"); 134 printf(" -t <time> run time in seconds\n"); 135 } 136 137 static int 138 poller_perf_verify_params(void) 139 { 140 if (g_num_pollers <= 0 || g_num_pollers > MAX_NUM_POLLERS) { 141 fprintf(stderr, "number of pollers must not be more than %d\n", MAX_NUM_POLLERS); 142 return -EINVAL; 143 } 144 145 if (g_period_in_usec < 0) { 146 fprintf(stderr, "period of poller cannot be negative\n"); 147 return -EINVAL; 148 } 149 150 if (g_time_in_sec <= 0) { 151 fprintf(stderr, "run time must be positive\n"); 152 return -EINVAL; 153 } 154 155 return 0; 156 } 157 158 int 159 main(int argc, char **argv) 160 { 161 struct spdk_app_opts opts; 162 int rc; 163 164 spdk_app_opts_init(&opts, sizeof(opts)); 165 opts.name = "poller_perf"; 166 opts.shutdown_cb = poller_perf_shutdown_cb; 167 168 rc = spdk_app_parse_args(argc, argv, &opts, "b:l:t:", NULL, 169 poller_perf_parse_arg, poller_perf_usage); 170 if (rc != SPDK_APP_PARSE_ARGS_SUCCESS) { 171 return rc; 172 } 173 174 rc = poller_perf_verify_params(); 175 if (rc != 0) { 176 return rc; 177 } 178 179 rc = spdk_app_start(&opts, poller_perf_start, NULL); 180 181 spdk_app_fini(); 182 183 return rc; 184 } 185