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