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_DEQ_TMO_NSEC ("deq_tmo_nsec") 35 #define EVT_PROD_ETHDEV ("prod_type_ethdev") 36 #define EVT_PROD_TIMERDEV ("prod_type_timerdev") 37 #define EVT_PROD_TIMERDEV_BURST ("prod_type_timerdev_burst") 38 #define EVT_NB_TIMERS ("nb_timers") 39 #define EVT_NB_TIMER_ADPTRS ("nb_timer_adptrs") 40 #define EVT_TIMER_TICK_NSEC ("timer_tick_nsec") 41 #define EVT_MAX_TMO_NSEC ("max_tmo_nsec") 42 #define EVT_EXPIRY_NSEC ("expiry_nsec") 43 #define EVT_MBUF_SZ ("mbuf_sz") 44 #define EVT_MAX_PKT_SZ ("max_pkt_sz") 45 #define EVT_NB_ETH_QUEUES ("nb_eth_queues") 46 #define EVT_ENA_VECTOR ("enable_vector") 47 #define EVT_VECTOR_SZ ("vector_size") 48 #define EVT_VECTOR_TMO ("vector_tmo_ns") 49 #define EVT_HELP ("help") 50 51 void evt_options_default(struct evt_options *opt); 52 int evt_options_parse(struct evt_options *opt, int argc, char **argv); 53 void evt_options_dump(struct evt_options *opt); 54 55 /* options check helpers */ 56 static inline bool 57 evt_lcores_has_overlap(bool lcores[], int lcore) 58 { 59 if (lcores[lcore] == true) { 60 evt_err("lcore overlaps at %d", lcore); 61 return true; 62 } 63 64 return false; 65 } 66 67 static inline bool 68 evt_lcores_has_overlap_multi(bool lcoresx[], bool lcoresy[]) 69 { 70 int i; 71 72 for (i = 0; i < RTE_MAX_LCORE; i++) { 73 if (lcoresx[i] && lcoresy[i]) { 74 evt_err("lcores overlaps at %d", i); 75 return true; 76 } 77 } 78 return false; 79 } 80 81 static inline bool 82 evt_has_active_lcore(bool lcores[]) 83 { 84 int i; 85 86 for (i = 0; i < RTE_MAX_LCORE; i++) 87 if (lcores[i]) 88 return true; 89 return false; 90 } 91 92 static inline int 93 evt_nr_active_lcores(bool lcores[]) 94 { 95 int i; 96 int c = 0; 97 98 for (i = 0; i < RTE_MAX_LCORE; i++) 99 if (lcores[i]) 100 c++; 101 return c; 102 } 103 104 static inline int 105 evt_get_first_active_lcore(bool lcores[]) 106 { 107 int i; 108 109 for (i = 0; i < RTE_MAX_LCORE; i++) 110 if (lcores[i]) 111 return i; 112 return -1; 113 } 114 115 static inline bool 116 evt_has_disabled_lcore(bool lcores[]) 117 { 118 int i; 119 120 for (i = 0; i < RTE_MAX_LCORE; i++) 121 if ((lcores[i] == true) && !(rte_lcore_is_enabled(i))) 122 return true; 123 return false; 124 } 125 126 static inline bool 127 evt_has_invalid_stage(struct evt_options *opt) 128 { 129 if (!opt->nb_stages) { 130 evt_err("need minimum one stage, check --stlist"); 131 return true; 132 } 133 if (opt->nb_stages > EVT_MAX_STAGES) { 134 evt_err("requested changes are beyond EVT_MAX_STAGES=%d", 135 EVT_MAX_STAGES); 136 return true; 137 } 138 return false; 139 } 140 141 static inline bool 142 evt_has_invalid_sched_type(struct evt_options *opt) 143 { 144 int i; 145 146 for (i = 0; i < opt->nb_stages; i++) { 147 if (opt->sched_type_list[i] > RTE_SCHED_TYPE_PARALLEL) { 148 evt_err("invalid sched_type %d at %d", 149 opt->sched_type_list[i], i); 150 return true; 151 } 152 } 153 return false; 154 } 155 156 /* option dump helpers */ 157 static inline void 158 evt_dump_worker_lcores(struct evt_options *opt) 159 { 160 int c; 161 162 evt_dump_begin("worker lcores"); 163 for (c = 0; c < RTE_MAX_LCORE; c++) { 164 if (opt->wlcores[c]) 165 printf("%d ", c); 166 } 167 evt_dump_end; 168 } 169 170 static inline void 171 evt_dump_producer_lcores(struct evt_options *opt) 172 { 173 int c; 174 175 evt_dump_begin("producer lcores"); 176 for (c = 0; c < RTE_MAX_LCORE; c++) { 177 if (opt->plcores[c]) 178 printf("%d ", c); 179 } 180 evt_dump_end; 181 } 182 183 static inline void 184 evt_dump_nb_flows(struct evt_options *opt) 185 { 186 evt_dump("nb_flows", "%d", opt->nb_flows); 187 } 188 189 static inline void 190 evt_dump_worker_dequeue_depth(struct evt_options *opt) 191 { 192 evt_dump("worker deq depth", "%d", opt->wkr_deq_dep); 193 } 194 195 static inline void 196 evt_dump_nb_stages(struct evt_options *opt) 197 { 198 evt_dump("nb_stages", "%d", opt->nb_stages); 199 } 200 201 static inline void 202 evt_dump_fwd_latency(struct evt_options *opt) 203 { 204 evt_dump("fwd_latency", "%s", EVT_BOOL_FMT(opt->fwd_latency)); 205 } 206 207 static inline void 208 evt_dump_queue_priority(struct evt_options *opt) 209 { 210 evt_dump("queue_priority", "%s", EVT_BOOL_FMT(opt->q_priority)); 211 } 212 213 static inline const char* 214 evt_sched_type_2_str(uint8_t sched_type) 215 { 216 217 if (sched_type == RTE_SCHED_TYPE_ORDERED) 218 return "O"; 219 else if (sched_type == RTE_SCHED_TYPE_ATOMIC) 220 return "A"; 221 else if (sched_type == RTE_SCHED_TYPE_PARALLEL) 222 return "P"; 223 else 224 return "I"; 225 } 226 227 static inline void 228 evt_dump_sched_type_list(struct evt_options *opt) 229 { 230 int i; 231 232 evt_dump_begin("sched_type_list"); 233 for (i = 0; i < opt->nb_stages; i++) 234 printf("%s ", evt_sched_type_2_str(opt->sched_type_list[i])); 235 236 evt_dump_end; 237 } 238 239 static inline const char * 240 evt_prod_id_to_name(enum evt_prod_type prod_type) 241 { 242 switch (prod_type) { 243 default: 244 case EVT_PROD_TYPE_SYNT: 245 return "Synthetic producer lcores"; 246 case EVT_PROD_TYPE_ETH_RX_ADPTR: 247 return "Ethdev Rx Adapter"; 248 case EVT_PROD_TYPE_EVENT_TIMER_ADPTR: 249 return "Event timer adapter"; 250 } 251 252 return ""; 253 } 254 255 #define EVT_PROD_MAX_NAME_LEN 50 256 static inline void 257 evt_dump_producer_type(struct evt_options *opt) 258 { 259 char name[EVT_PROD_MAX_NAME_LEN]; 260 261 switch (opt->prod_type) { 262 default: 263 case EVT_PROD_TYPE_SYNT: 264 snprintf(name, EVT_PROD_MAX_NAME_LEN, 265 "Synthetic producer lcores"); 266 break; 267 case EVT_PROD_TYPE_ETH_RX_ADPTR: 268 snprintf(name, EVT_PROD_MAX_NAME_LEN, 269 "Ethdev Rx Adapter producers"); 270 evt_dump("nb_ethdev", "%d", rte_eth_dev_count_avail()); 271 break; 272 case EVT_PROD_TYPE_EVENT_TIMER_ADPTR: 273 if (opt->timdev_use_burst) 274 snprintf(name, EVT_PROD_MAX_NAME_LEN, 275 "Event timer adapter burst mode producer"); 276 else 277 snprintf(name, EVT_PROD_MAX_NAME_LEN, 278 "Event timer adapter producer"); 279 evt_dump("nb_timer_adapters", "%d", opt->nb_timer_adptrs); 280 evt_dump("max_tmo_nsec", "%"PRIu64"", opt->max_tmo_nsec); 281 evt_dump("expiry_nsec", "%"PRIu64"", opt->expiry_nsec); 282 if (opt->optm_timer_tick_nsec) 283 evt_dump("optm_timer_tick_nsec", "%"PRIu64"", 284 opt->optm_timer_tick_nsec); 285 else 286 evt_dump("timer_tick_nsec", "%"PRIu64"", 287 opt->timer_tick_nsec); 288 break; 289 } 290 evt_dump("prod_type", "%s", name); 291 } 292 293 #endif /* _EVT_OPTIONS_ */ 294