1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Cavium, Inc 3 */ 4 5 #ifndef _EVT_OPTIONS_ 6 #define _EVT_OPTIONS_ 7 8 #include <stdio.h> 9 #include <stdbool.h> 10 11 #include <rte_common.h> 12 #include <rte_ethdev.h> 13 #include <rte_eventdev.h> 14 #include <rte_lcore.h> 15 16 #include "evt_common.h" 17 18 #define EVT_BOOL_FMT(x) ((x) ? "true" : "false") 19 20 #define EVT_VERBOSE ("verbose") 21 #define EVT_DEVICE ("dev") 22 #define EVT_TEST ("test") 23 #define EVT_PROD_LCORES ("plcores") 24 #define EVT_WORK_LCORES ("wlcores") 25 #define EVT_NB_FLOWS ("nb_flows") 26 #define EVT_SOCKET_ID ("socket_id") 27 #define EVT_POOL_SZ ("pool_sz") 28 #define EVT_WKR_DEQ_DEP ("worker_deq_depth") 29 #define EVT_NB_PKTS ("nb_pkts") 30 #define EVT_NB_STAGES ("nb_stages") 31 #define EVT_SCHED_TYPE_LIST ("stlist") 32 #define EVT_FWD_LATENCY ("fwd_latency") 33 #define EVT_QUEUE_PRIORITY ("queue_priority") 34 #define EVT_PROD_ETHDEV ("prod_type_ethdev") 35 #define EVT_PROD_TIMERDEV ("prod_type_timerdev") 36 #define EVT_PROD_TIMERDEV_BURST ("prod_type_timerdev_burst") 37 #define EVT_NB_TIMERS ("nb_timers") 38 #define EVT_NB_TIMER_ADPTRS ("nb_timer_adptrs") 39 #define EVT_TIMER_TICK_NSEC ("timer_tick_nsec") 40 #define EVT_MAX_TMO_NSEC ("max_tmo_nsec") 41 #define EVT_EXPIRY_NSEC ("expiry_nsec") 42 #define EVT_HELP ("help") 43 44 enum evt_prod_type { 45 EVT_PROD_TYPE_NONE, 46 EVT_PROD_TYPE_SYNT, /* Producer type Synthetic i.e. CPU. */ 47 EVT_PROD_TYPE_ETH_RX_ADPTR, /* Producer type Eth Rx Adapter. */ 48 EVT_PROD_TYPE_EVENT_TIMER_ADPTR, /* Producer type Timer Adapter. */ 49 EVT_PROD_TYPE_MAX, 50 }; 51 52 struct evt_options { 53 #define EVT_TEST_NAME_MAX_LEN 32 54 char test_name[EVT_TEST_NAME_MAX_LEN]; 55 bool plcores[RTE_MAX_LCORE]; 56 bool wlcores[RTE_MAX_LCORE]; 57 uint8_t sched_type_list[EVT_MAX_STAGES]; 58 uint32_t nb_flows; 59 int socket_id; 60 int pool_sz; 61 int nb_stages; 62 int verbose_level; 63 uint64_t nb_pkts; 64 uint8_t nb_timer_adptrs; 65 uint64_t nb_timers; 66 uint64_t timer_tick_nsec; 67 uint64_t optm_timer_tick_nsec; 68 uint64_t max_tmo_nsec; 69 uint64_t expiry_nsec; 70 uint16_t wkr_deq_dep; 71 uint8_t dev_id; 72 uint32_t fwd_latency:1; 73 uint32_t q_priority:1; 74 enum evt_prod_type prod_type; 75 uint8_t timdev_use_burst; 76 uint8_t timdev_cnt; 77 }; 78 79 void evt_options_default(struct evt_options *opt); 80 int evt_options_parse(struct evt_options *opt, int argc, char **argv); 81 void evt_options_dump(struct evt_options *opt); 82 83 /* options check helpers */ 84 static inline bool 85 evt_lcores_has_overlap(bool lcores[], int lcore) 86 { 87 if (lcores[lcore] == true) { 88 evt_err("lcore overlaps at %d", lcore); 89 return true; 90 } 91 92 return false; 93 } 94 95 static inline bool 96 evt_lcores_has_overlap_multi(bool lcoresx[], bool lcoresy[]) 97 { 98 int i; 99 100 for (i = 0; i < RTE_MAX_LCORE; i++) { 101 if (lcoresx[i] && lcoresy[i]) { 102 evt_err("lcores overlaps at %d", i); 103 return true; 104 } 105 } 106 return false; 107 } 108 109 static inline bool 110 evt_has_active_lcore(bool lcores[]) 111 { 112 int i; 113 114 for (i = 0; i < RTE_MAX_LCORE; i++) 115 if (lcores[i]) 116 return true; 117 return false; 118 } 119 120 static inline int 121 evt_nr_active_lcores(bool lcores[]) 122 { 123 int i; 124 int c = 0; 125 126 for (i = 0; i < RTE_MAX_LCORE; i++) 127 if (lcores[i]) 128 c++; 129 return c; 130 } 131 132 static inline int 133 evt_get_first_active_lcore(bool lcores[]) 134 { 135 int i; 136 137 for (i = 0; i < RTE_MAX_LCORE; i++) 138 if (lcores[i]) 139 return i; 140 return -1; 141 } 142 143 static inline bool 144 evt_has_disabled_lcore(bool lcores[]) 145 { 146 int i; 147 148 for (i = 0; i < RTE_MAX_LCORE; i++) 149 if ((lcores[i] == true) && !(rte_lcore_is_enabled(i))) 150 return true; 151 return false; 152 } 153 154 static inline bool 155 evt_has_invalid_stage(struct evt_options *opt) 156 { 157 if (!opt->nb_stages) { 158 evt_err("need minimum one stage, check --stlist"); 159 return true; 160 } 161 if (opt->nb_stages > EVT_MAX_STAGES) { 162 evt_err("requested changes are beyond EVT_MAX_STAGES=%d", 163 EVT_MAX_STAGES); 164 return true; 165 } 166 return false; 167 } 168 169 static inline bool 170 evt_has_invalid_sched_type(struct evt_options *opt) 171 { 172 int i; 173 174 for (i = 0; i < opt->nb_stages; i++) { 175 if (opt->sched_type_list[i] > RTE_SCHED_TYPE_PARALLEL) { 176 evt_err("invalid sched_type %d at %d", 177 opt->sched_type_list[i], i); 178 return true; 179 } 180 } 181 return false; 182 } 183 184 /* option dump helpers */ 185 static inline void 186 evt_dump_worker_lcores(struct evt_options *opt) 187 { 188 int c; 189 190 evt_dump_begin("worker lcores"); 191 for (c = 0; c < RTE_MAX_LCORE; c++) { 192 if (opt->wlcores[c]) 193 printf("%d ", c); 194 } 195 evt_dump_end; 196 } 197 198 static inline void 199 evt_dump_producer_lcores(struct evt_options *opt) 200 { 201 int c; 202 203 evt_dump_begin("producer lcores"); 204 for (c = 0; c < RTE_MAX_LCORE; c++) { 205 if (opt->plcores[c]) 206 printf("%d ", c); 207 } 208 evt_dump_end; 209 } 210 211 static inline void 212 evt_dump_nb_flows(struct evt_options *opt) 213 { 214 evt_dump("nb_flows", "%d", opt->nb_flows); 215 } 216 217 static inline void 218 evt_dump_worker_dequeue_depth(struct evt_options *opt) 219 { 220 evt_dump("worker deq depth", "%d", opt->wkr_deq_dep); 221 } 222 223 static inline void 224 evt_dump_nb_stages(struct evt_options *opt) 225 { 226 evt_dump("nb_stages", "%d", opt->nb_stages); 227 } 228 229 static inline void 230 evt_dump_fwd_latency(struct evt_options *opt) 231 { 232 evt_dump("fwd_latency", "%s", EVT_BOOL_FMT(opt->fwd_latency)); 233 } 234 235 static inline void 236 evt_dump_queue_priority(struct evt_options *opt) 237 { 238 evt_dump("queue_priority", "%s", EVT_BOOL_FMT(opt->q_priority)); 239 } 240 241 static inline const char* 242 evt_sched_type_2_str(uint8_t sched_type) 243 { 244 245 if (sched_type == RTE_SCHED_TYPE_ORDERED) 246 return "O"; 247 else if (sched_type == RTE_SCHED_TYPE_ATOMIC) 248 return "A"; 249 else if (sched_type == RTE_SCHED_TYPE_PARALLEL) 250 return "P"; 251 else 252 return "I"; 253 } 254 255 static inline void 256 evt_dump_sched_type_list(struct evt_options *opt) 257 { 258 int i; 259 260 evt_dump_begin("sched_type_list"); 261 for (i = 0; i < opt->nb_stages; i++) 262 printf("%s ", evt_sched_type_2_str(opt->sched_type_list[i])); 263 264 evt_dump_end; 265 } 266 267 #define EVT_PROD_MAX_NAME_LEN 50 268 static inline void 269 evt_dump_producer_type(struct evt_options *opt) 270 { 271 char name[EVT_PROD_MAX_NAME_LEN]; 272 273 switch (opt->prod_type) { 274 default: 275 case EVT_PROD_TYPE_SYNT: 276 snprintf(name, EVT_PROD_MAX_NAME_LEN, 277 "Synthetic producer lcores"); 278 break; 279 case EVT_PROD_TYPE_ETH_RX_ADPTR: 280 snprintf(name, EVT_PROD_MAX_NAME_LEN, 281 "Ethdev Rx Adapter producers"); 282 evt_dump("nb_ethdev", "%d", rte_eth_dev_count_avail()); 283 break; 284 case EVT_PROD_TYPE_EVENT_TIMER_ADPTR: 285 if (opt->timdev_use_burst) 286 snprintf(name, EVT_PROD_MAX_NAME_LEN, 287 "Event timer adapter burst mode producer"); 288 else 289 snprintf(name, EVT_PROD_MAX_NAME_LEN, 290 "Event timer adapter producer"); 291 evt_dump("nb_timer_adapters", "%d", opt->nb_timer_adptrs); 292 evt_dump("max_tmo_nsec", "%"PRIu64"", opt->max_tmo_nsec); 293 evt_dump("expiry_nsec", "%"PRIu64"", opt->expiry_nsec); 294 if (opt->optm_timer_tick_nsec) 295 evt_dump("optm_timer_tick_nsec", "%"PRIu64"", 296 opt->optm_timer_tick_nsec); 297 else 298 evt_dump("timer_tick_nsec", "%"PRIu64"", 299 opt->timer_tick_nsec); 300 break; 301 } 302 evt_dump("prod_type", "%s", name); 303 } 304 305 #endif /* _EVT_OPTIONS_ */ 306