1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2018 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <string.h> 7 8 #include <rte_common.h> 9 #include <rte_memory.h> 10 #include <rte_lcore.h> 11 #include <rte_power.h> 12 #include <rte_string_fns.h> 13 14 #include "perf_core.h" 15 #include "main.h" 16 17 18 static uint16_t hp_lcores[RTE_MAX_LCORE]; 19 static uint16_t nb_hp_lcores; 20 21 struct perf_lcore_params { 22 uint16_t port_id; 23 uint8_t queue_id; 24 uint8_t high_perf; 25 uint8_t lcore_idx; 26 } __rte_cache_aligned; 27 28 static struct perf_lcore_params prf_lc_prms[MAX_LCORE_PARAMS]; 29 static uint16_t nb_prf_lc_prms; 30 31 int 32 update_lcore_params(void) 33 { 34 uint8_t non_perf_lcores[RTE_MAX_LCORE]; 35 uint16_t nb_non_perf_lcores = 0; 36 int i, j, ret; 37 38 /* if perf-config option was not used do nothing */ 39 if (nb_prf_lc_prms == 0) 40 return 0; 41 42 /* if high-perf-cores option was not used query every available core */ 43 if (nb_hp_lcores == 0) { 44 for (i = 0; i < RTE_MAX_LCORE; i++) { 45 if (rte_lcore_is_enabled(i)) { 46 struct rte_power_core_capabilities caps; 47 ret = rte_power_get_capabilities(i, &caps); 48 if (ret == 0 && caps.turbo) { 49 hp_lcores[nb_hp_lcores] = i; 50 nb_hp_lcores++; 51 } 52 } 53 } 54 } 55 56 /* create a list on non high performance cores*/ 57 for (i = 0; i < RTE_MAX_LCORE; i++) { 58 if (rte_lcore_is_enabled(i)) { 59 int hp = 0; 60 for (j = 0; j < nb_hp_lcores; j++) { 61 if (hp_lcores[j] == i) { 62 hp = 1; 63 break; 64 } 65 } 66 if (!hp) 67 non_perf_lcores[nb_non_perf_lcores++] = i; 68 } 69 } 70 71 /* update the lcore config */ 72 for (i = 0; i < nb_prf_lc_prms; i++) { 73 int lcore = -1; 74 if (prf_lc_prms[i].high_perf) { 75 if (prf_lc_prms[i].lcore_idx < nb_hp_lcores) 76 lcore = hp_lcores[prf_lc_prms[i].lcore_idx]; 77 } else { 78 if (prf_lc_prms[i].lcore_idx < nb_non_perf_lcores) 79 lcore = 80 non_perf_lcores[prf_lc_prms[i].lcore_idx]; 81 } 82 83 if (lcore < 0) { 84 printf("Performance cores configuration error\n"); 85 return -1; 86 } 87 88 lcore_params_array[i].lcore_id = lcore; 89 lcore_params_array[i].queue_id = prf_lc_prms[i].queue_id; 90 lcore_params_array[i].port_id = prf_lc_prms[i].port_id; 91 } 92 93 lcore_params = lcore_params_array; 94 nb_lcore_params = nb_prf_lc_prms; 95 96 printf("Updated performance core configuration\n"); 97 for (i = 0; i < nb_prf_lc_prms; i++) 98 printf("\t(%d,%d,%d)\n", lcore_params[i].port_id, 99 lcore_params[i].queue_id, 100 lcore_params[i].lcore_id); 101 102 return 0; 103 } 104 105 int 106 parse_perf_config(const char *q_arg) 107 { 108 char s[256]; 109 const char *p, *p0 = q_arg; 110 char *end; 111 enum fieldnames { 112 FLD_PORT = 0, 113 FLD_QUEUE, 114 FLD_LCORE_HP, 115 FLD_LCORE_IDX, 116 _NUM_FLD 117 }; 118 unsigned long int_fld[_NUM_FLD]; 119 char *str_fld[_NUM_FLD]; 120 int i; 121 unsigned int size; 122 123 nb_prf_lc_prms = 0; 124 125 while ((p = strchr(p0, '(')) != NULL) { 126 ++p; 127 p0 = strchr(p, ')'); 128 if (p0 == NULL) 129 return -1; 130 131 size = p0 - p; 132 if (size >= sizeof(s)) 133 return -1; 134 135 snprintf(s, sizeof(s), "%.*s", size, p); 136 if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != 137 _NUM_FLD) 138 return -1; 139 for (i = 0; i < _NUM_FLD; i++) { 140 errno = 0; 141 int_fld[i] = strtoul(str_fld[i], &end, 0); 142 if (errno != 0 || end == str_fld[i] || int_fld[i] > 255) 143 return -1; 144 } 145 if (nb_prf_lc_prms >= MAX_LCORE_PARAMS) { 146 printf("exceeded max number of lcore params: %hu\n", 147 nb_prf_lc_prms); 148 return -1; 149 } 150 prf_lc_prms[nb_prf_lc_prms].port_id = 151 (uint8_t)int_fld[FLD_PORT]; 152 prf_lc_prms[nb_prf_lc_prms].queue_id = 153 (uint8_t)int_fld[FLD_QUEUE]; 154 prf_lc_prms[nb_prf_lc_prms].high_perf = 155 !!(uint8_t)int_fld[FLD_LCORE_HP]; 156 prf_lc_prms[nb_prf_lc_prms].lcore_idx = 157 (uint8_t)int_fld[FLD_LCORE_IDX]; 158 ++nb_prf_lc_prms; 159 } 160 161 return 0; 162 } 163 164 int 165 parse_perf_core_list(const char *corelist) 166 { 167 int i, idx = 0; 168 unsigned int count = 0; 169 char *end = NULL; 170 int min, max; 171 172 if (corelist == NULL) { 173 printf("invalid core list\n"); 174 return -1; 175 } 176 177 178 /* Remove all blank characters ahead and after */ 179 while (isblank(*corelist)) 180 corelist++; 181 i = strlen(corelist); 182 while ((i > 0) && isblank(corelist[i - 1])) 183 i--; 184 185 /* Get list of cores */ 186 min = RTE_MAX_LCORE; 187 do { 188 while (isblank(*corelist)) 189 corelist++; 190 if (*corelist == '\0') 191 return -1; 192 errno = 0; 193 idx = strtoul(corelist, &end, 10); 194 if (errno || end == NULL) 195 return -1; 196 while (isblank(*end)) 197 end++; 198 if (*end == '-') { 199 min = idx; 200 } else if ((*end == ',') || (*end == '\0')) { 201 max = idx; 202 if (min == RTE_MAX_LCORE) 203 min = idx; 204 for (idx = min; idx <= max; idx++) { 205 hp_lcores[count] = idx; 206 count++; 207 } 208 min = RTE_MAX_LCORE; 209 } else { 210 printf("invalid core list\n"); 211 return -1; 212 } 213 corelist = end + 1; 214 } while (*end != '\0'); 215 216 if (count == 0) { 217 printf("invalid core list\n"); 218 return -1; 219 } 220 221 nb_hp_lcores = count; 222 223 printf("Configured %d high performance cores\n", nb_hp_lcores); 224 for (i = 0; i < nb_hp_lcores; i++) 225 printf("\tHigh performance core %d %d\n", 226 i, hp_lcores[i]); 227 228 return 0; 229 } 230