ia64/xen-unstable
changeset 18936:a76b4e00e186
xenpm: add cpu frequency control interface, through which user can
tune the parameters manually.
Now, xenpm can be invoked with the following options:
Usage:
xenpm get-cpuidle-states [cpuid]: list cpu idle information on
CPU cpuid or all CPUs.
xenpm get-cpufreq-states [cpuid]: list cpu frequency
information on CPU cpuid or all CPUs.
xenpm get-cpufreq-para [cpuid]: list cpu frequency information
on CPU cpuid or all CPUs.
xenpm set-scaling-maxfreq <cpuid> <HZ>: set max cpu frequency
<HZ> on CPU <cpuid>.
xenpm set-scaling-minfreq <cpuid> <HZ>: set min cpu frequency
<HZ> on CPU <cpuid>.
xenpm set-scaling-governor <cpuid> <name>: set scaling governor
on CPU <cpuid>.
xenpm set-scaling-speed <cpuid> <num>: set scaling speed on CPU
<cpuid>.
xenpm set-sampling-rate <cpuid> <num>: set sampling rate on CPU
<cpuid>.
xenpm set-up-threshold <cpuid> <num>: set up threshold on CPU
<cpuid>.
To ease the use of this tool, the shortcut option is supported,
i.e. `xenpm get-cpui' is equal to `xenpm get-cpuidle-states'.
Signed-off-by: Guanqun Lu <guanqun.lu@intel.com>
tune the parameters manually.
Now, xenpm can be invoked with the following options:
Usage:
xenpm get-cpuidle-states [cpuid]: list cpu idle information on
CPU cpuid or all CPUs.
xenpm get-cpufreq-states [cpuid]: list cpu frequency
information on CPU cpuid or all CPUs.
xenpm get-cpufreq-para [cpuid]: list cpu frequency information
on CPU cpuid or all CPUs.
xenpm set-scaling-maxfreq <cpuid> <HZ>: set max cpu frequency
<HZ> on CPU <cpuid>.
xenpm set-scaling-minfreq <cpuid> <HZ>: set min cpu frequency
<HZ> on CPU <cpuid>.
xenpm set-scaling-governor <cpuid> <name>: set scaling governor
on CPU <cpuid>.
xenpm set-scaling-speed <cpuid> <num>: set scaling speed on CPU
<cpuid>.
xenpm set-sampling-rate <cpuid> <num>: set sampling rate on CPU
<cpuid>.
xenpm set-up-threshold <cpuid> <num>: set up threshold on CPU
<cpuid>.
To ease the use of this tool, the shortcut option is supported,
i.e. `xenpm get-cpui' is equal to `xenpm get-cpuidle-states'.
Signed-off-by: Guanqun Lu <guanqun.lu@intel.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Tue Dec 16 13:14:25 2008 +0000 (2008-12-16) |
parents | fd720db48675 |
children | 22e3666ee483 |
files | tools/misc/xenpm.c |
line diff
1.1 --- a/tools/misc/xenpm.c Tue Dec 16 12:04:13 2008 +0000 1.2 +++ b/tools/misc/xenpm.c Tue Dec 16 13:14:25 2008 +0000 1.3 @@ -16,199 +16,591 @@ 1.4 * Place - Suite 330, Boston, MA 02111-1307 USA. 1.5 */ 1.6 1.7 +/* to eliminate warning on `strndup' */ 1.8 +#define _GNU_SOURCE 1.9 + 1.10 #include <stdio.h> 1.11 #include <stdlib.h> 1.12 +#include <string.h> 1.13 #include <getopt.h> 1.14 #include <errno.h> 1.15 1.16 #include <xenctrl.h> 1.17 #include <inttypes.h> 1.18 1.19 -int main(int argc, char **argv) 1.20 +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) 1.21 + 1.22 +/* help message */ 1.23 +void show_help(void) 1.24 +{ 1.25 + fprintf(stderr, 1.26 + "Usage:\n" 1.27 + " xenpm get-cpuidle-states [cpuid]: list cpu idle information on CPU cpuid or all CPUs.\n" 1.28 + " xenpm get-cpufreq-states [cpuid]: list cpu frequency information on CPU cpuid or all CPUs.\n" 1.29 + " xenpm get-cpufreq-para [cpuid]: list cpu frequency information on CPU cpuid or all CPUs.\n" 1.30 + " xenpm set-scaling-maxfreq <cpuid> <HZ>: set max cpu frequency <HZ> on CPU <cpuid>.\n" 1.31 + " xenpm set-scaling-minfreq <cpuid> <HZ>: set min cpu frequency <HZ> on CPU <cpuid>.\n" 1.32 + " xenpm set-scaling-governor <cpuid> <name>: set scaling governor on CPU <cpuid>.\n" 1.33 + " xenpm set-scaling-speed <cpuid> <num>: set scaling speed on CPU <cpuid>.\n" 1.34 + " xenpm set-sampling-rate <cpuid> <num>: set sampling rate on CPU <cpuid>.\n" 1.35 + " xenpm set-up-threshold <cpuid> <num>: set up threshold on CPU <cpuid>.\n"); 1.36 +} 1.37 + 1.38 +/* wrapper function */ 1.39 +int help_func(int xc_fd, int cpuid, uint32_t value) 1.40 +{ 1.41 + show_help(); 1.42 + return 0; 1.43 +} 1.44 + 1.45 +/* show cpu idle information on CPU cpuid */ 1.46 +static int show_cx_cpuid(int xc_fd, int cpuid) 1.47 { 1.48 - int xc_fd; 1.49 - int i, j, ret = 0; 1.50 - int cinfo = 0, pinfo = 0; 1.51 - int ch; 1.52 + int i, ret = 0; 1.53 + int max_cx_num = 0; 1.54 + struct xc_cx_stat cxstatinfo, *cxstat = &cxstatinfo; 1.55 + 1.56 + ret = xc_pm_get_max_cx(xc_fd, cpuid, &max_cx_num); 1.57 + if ( ret ) 1.58 + { 1.59 + if ( errno == ENODEV ) 1.60 + { 1.61 + fprintf(stderr, "Xen cpuidle is not enabled!\n"); 1.62 + return -ENODEV; 1.63 + } 1.64 + else 1.65 + { 1.66 + fprintf(stderr, "[CPU%d] failed to get max C-state\n", cpuid); 1.67 + return -EINVAL; 1.68 + } 1.69 + } 1.70 + 1.71 + cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t)); 1.72 + if ( !cxstat->triggers ) 1.73 + { 1.74 + fprintf(stderr, "[CPU%d] failed to malloc for C-states triggers\n", cpuid); 1.75 + return -ENOMEM; 1.76 + } 1.77 + cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t)); 1.78 + if ( !cxstat->residencies ) 1.79 + { 1.80 + fprintf(stderr, "[CPU%d] failed to malloc for C-states residencies\n", cpuid); 1.81 + free(cxstat->triggers); 1.82 + return -ENOMEM; 1.83 + } 1.84 + 1.85 + ret = xc_pm_get_cxstat(xc_fd, cpuid, cxstat); 1.86 + if( ret ) 1.87 + { 1.88 + fprintf(stderr, "[CPU%d] failed to get C-states statistics " 1.89 + "information\n", cpuid); 1.90 + free(cxstat->triggers); 1.91 + free(cxstat->residencies); 1.92 + return -EINVAL; 1.93 + } 1.94 + 1.95 + printf("cpu id : %d\n", cpuid); 1.96 + printf("total C-states : %d\n", cxstat->nr); 1.97 + printf("idle time(ms) : %"PRIu64"\n", 1.98 + cxstat->idle_time/1000000UL); 1.99 + for ( i = 0; i < cxstat->nr; i++ ) 1.100 + { 1.101 + printf("C%d : transition [%020"PRIu64"]\n", 1.102 + i, cxstat->triggers[i]); 1.103 + printf(" residency [%020"PRIu64" ms]\n", 1.104 + cxstat->residencies[i]*1000000UL/3579/1000000UL); 1.105 + } 1.106 + 1.107 + free(cxstat->triggers); 1.108 + free(cxstat->residencies); 1.109 + 1.110 + printf("\n"); 1.111 + return 0; 1.112 +} 1.113 + 1.114 +int cxstates_func(int xc_fd, int cpuid, uint32_t value) 1.115 +{ 1.116 + int ret = 0; 1.117 xc_physinfo_t physinfo = { 0 }; 1.118 1.119 - while ( (ch = getopt(argc, argv, "cp")) != -1 ) 1.120 + if ( cpuid < 0 ) 1.121 { 1.122 - switch ( ch ) 1.123 + /* show cxstates on all cpu */ 1.124 + ret = xc_physinfo(xc_fd, &physinfo); 1.125 + if ( ret ) 1.126 + { 1.127 + fprintf(stderr, "failed to get the processor information\n"); 1.128 + } 1.129 + else 1.130 { 1.131 - case 'c': 1.132 - cinfo = 1; 1.133 - break; 1.134 - case 'p': 1.135 - pinfo = 1; 1.136 - break; 1.137 - default: 1.138 - fprintf(stderr, "%s [-p] [-c]\n", argv[0]); 1.139 - return -1; 1.140 + int i; 1.141 + for ( i = 0; i < physinfo.nr_cpus; i++ ) 1.142 + { 1.143 + if ( (ret = show_cx_cpuid(xc_fd, i)) == -ENODEV ) 1.144 + break; 1.145 + } 1.146 + } 1.147 + } 1.148 + else 1.149 + ret = show_cx_cpuid(xc_fd, cpuid); 1.150 + 1.151 + return ret; 1.152 +} 1.153 + 1.154 +/* show cpu frequency information on CPU cpuid */ 1.155 +static int show_px_cpuid(int xc_fd, int cpuid) 1.156 +{ 1.157 + int i, ret = 0; 1.158 + int max_px_num = 0; 1.159 + struct xc_px_stat pxstatinfo, *pxstat = &pxstatinfo; 1.160 + 1.161 + ret = xc_pm_get_max_px(xc_fd, cpuid, &max_px_num); 1.162 + if ( ret ) 1.163 + { 1.164 + if ( errno == ENODEV ) 1.165 + { 1.166 + printf("Xen cpufreq is not enabled!\n"); 1.167 + return -ENODEV; 1.168 + } 1.169 + else 1.170 + { 1.171 + fprintf(stderr, "[CPU%d] failed to get max P-state\n", cpuid); 1.172 + return -EINVAL; 1.173 } 1.174 } 1.175 1.176 - if ( !cinfo && !pinfo ) 1.177 + pxstat->trans_pt = malloc(max_px_num * max_px_num * 1.178 + sizeof(uint64_t)); 1.179 + if ( !pxstat->trans_pt ) 1.180 + { 1.181 + fprintf(stderr, "[CPU%d] failed to malloc for P-states transition table\n", cpuid); 1.182 + return -ENOMEM; 1.183 + } 1.184 + pxstat->pt = malloc(max_px_num * sizeof(struct xc_px_val)); 1.185 + if ( !pxstat->pt ) 1.186 + { 1.187 + fprintf(stderr, "[CPU%d] failed to malloc for P-states table\n", cpuid); 1.188 + free(pxstat->trans_pt); 1.189 + return -ENOMEM; 1.190 + } 1.191 + 1.192 + ret = xc_pm_get_pxstat(xc_fd, cpuid, pxstat); 1.193 + if( ret ) 1.194 + { 1.195 + fprintf(stderr, "[CPU%d] failed to get P-states statistics information\n", cpuid); 1.196 + free(pxstat->trans_pt); 1.197 + free(pxstat->pt); 1.198 + return -ENOMEM; 1.199 + } 1.200 + 1.201 + printf("cpu id : %d\n", cpuid); 1.202 + printf("total P-states : %d\n", pxstat->total); 1.203 + printf("usable P-states : %d\n", pxstat->usable); 1.204 + printf("current frequency : %"PRIu64" MHz\n", 1.205 + pxstat->pt[pxstat->cur].freq); 1.206 + for ( i = 0; i < pxstat->total; i++ ) 1.207 + { 1.208 + if ( pxstat->cur == i ) 1.209 + printf("*P%d", i); 1.210 + else 1.211 + printf("P%d ", i); 1.212 + printf(" : freq [%04"PRIu64" MHz]\n", 1.213 + pxstat->pt[i].freq); 1.214 + printf(" transition [%020"PRIu64"]\n", 1.215 + pxstat->pt[i].count); 1.216 + printf(" residency [%020"PRIu64" ms]\n", 1.217 + pxstat->pt[i].residency/1000000UL); 1.218 + } 1.219 + 1.220 + free(pxstat->trans_pt); 1.221 + free(pxstat->pt); 1.222 + 1.223 + printf("\n"); 1.224 + return 0; 1.225 +} 1.226 + 1.227 +int pxstates_func(int xc_fd, int cpuid, uint32_t value) 1.228 +{ 1.229 + int ret = 0; 1.230 + xc_physinfo_t physinfo = { 0 }; 1.231 + 1.232 + if ( cpuid < 0 ) 1.233 + { 1.234 + ret = xc_physinfo(xc_fd, &physinfo); 1.235 + if ( ret ) 1.236 + { 1.237 + fprintf(stderr, "failed to get the processor information\n"); 1.238 + } 1.239 + else 1.240 + { 1.241 + int i; 1.242 + for ( i = 0; i < physinfo.nr_cpus; i++ ) 1.243 + { 1.244 + if ( (ret = show_px_cpuid(xc_fd, i)) == -ENODEV ) 1.245 + break; 1.246 + } 1.247 + } 1.248 + } 1.249 + else 1.250 + ret = show_px_cpuid(xc_fd, cpuid); 1.251 + 1.252 + return ret; 1.253 +} 1.254 + 1.255 +/* print out parameters about cpu frequency */ 1.256 +static void print_cpufreq_para(int cpuid, struct xc_get_cpufreq_para *p_cpufreq) 1.257 +{ 1.258 + int i; 1.259 + 1.260 + printf("cpu id : %d\n", cpuid); 1.261 + 1.262 + printf("affected_cpus :"); 1.263 + for ( i = 0; i < p_cpufreq->cpu_num; i++ ) 1.264 + if ( i == cpuid ) 1.265 + printf(" *%d", p_cpufreq->affected_cpus[i]); 1.266 + else 1.267 + printf(" %d", p_cpufreq->affected_cpus[i]); 1.268 + printf("\n"); 1.269 + 1.270 + printf("cpuinfo frequency : max [%u] min [%u] cur [%u]\n", 1.271 + p_cpufreq->cpuinfo_max_freq, 1.272 + p_cpufreq->cpuinfo_min_freq, 1.273 + p_cpufreq->cpuinfo_cur_freq); 1.274 + 1.275 + printf("scaling_driver : %s\n", p_cpufreq->scaling_driver); 1.276 + 1.277 + printf("scaling_avail_gov : %s\n", 1.278 + p_cpufreq->scaling_available_governors); 1.279 + 1.280 + printf("current_governor : %s\n", p_cpufreq->scaling_governor); 1.281 + if ( !strncmp(p_cpufreq->scaling_governor, 1.282 + "userspace", CPUFREQ_NAME_LEN) ) 1.283 + { 1.284 + printf(" userspace specific :\n"); 1.285 + printf(" scaling_setspeed : %u\n", 1.286 + p_cpufreq->u.userspace.scaling_setspeed); 1.287 + } 1.288 + else if ( !strncmp(p_cpufreq->scaling_governor, 1.289 + "ondemand", CPUFREQ_NAME_LEN) ) 1.290 + { 1.291 + printf(" ondemand specific :\n"); 1.292 + printf(" sampling_rate : max [%u] min [%u] cur [%u]\n", 1.293 + p_cpufreq->u.ondemand.sampling_rate_max, 1.294 + p_cpufreq->u.ondemand.sampling_rate_min, 1.295 + p_cpufreq->u.ondemand.sampling_rate); 1.296 + printf(" up_threshold : %u\n", 1.297 + p_cpufreq->u.ondemand.up_threshold); 1.298 + } 1.299 + 1.300 + printf("scaling_avail_freq :"); 1.301 + for ( i = 0; i < p_cpufreq->freq_num; i++ ) 1.302 + if ( p_cpufreq->scaling_available_frequencies[i] == p_cpufreq->scaling_cur_freq ) 1.303 + printf(" *%d", p_cpufreq->scaling_available_frequencies[i]); 1.304 + else 1.305 + printf(" %d", p_cpufreq->scaling_available_frequencies[i]); 1.306 + printf("\n"); 1.307 + 1.308 + printf("scaling frequency : max [%u] min [%u] cur [%u]\n", 1.309 + p_cpufreq->scaling_max_freq, 1.310 + p_cpufreq->scaling_min_freq, 1.311 + p_cpufreq->scaling_cur_freq); 1.312 + printf("\n"); 1.313 +} 1.314 + 1.315 +/* show cpu frequency parameters information on CPU cpuid */ 1.316 +static int show_cpufreq_para_cpuid(int xc_fd, int cpuid) 1.317 +{ 1.318 + int ret = 0; 1.319 + struct xc_get_cpufreq_para cpufreq_para, *p_cpufreq = &cpufreq_para; 1.320 + 1.321 + p_cpufreq->cpu_num = 0; 1.322 + p_cpufreq->freq_num = 0; 1.323 + p_cpufreq->gov_num = 0; 1.324 + p_cpufreq->affected_cpus = NULL; 1.325 + p_cpufreq->scaling_available_frequencies = NULL; 1.326 + p_cpufreq->scaling_available_governors = NULL; 1.327 + 1.328 + do 1.329 { 1.330 - cinfo = 1; 1.331 - pinfo = 1; 1.332 + free(p_cpufreq->affected_cpus); 1.333 + free(p_cpufreq->scaling_available_frequencies); 1.334 + free(p_cpufreq->scaling_available_governors); 1.335 + 1.336 + p_cpufreq->affected_cpus = NULL; 1.337 + p_cpufreq->scaling_available_frequencies = NULL; 1.338 + p_cpufreq->scaling_available_governors = NULL; 1.339 + 1.340 + if (!(p_cpufreq->affected_cpus = 1.341 + malloc(p_cpufreq->cpu_num * sizeof(uint32_t)))) 1.342 + { 1.343 + fprintf(stderr, 1.344 + "[CPU%d] failed to malloc for affected_cpus\n", 1.345 + cpuid); 1.346 + ret = -ENOMEM; 1.347 + goto out; 1.348 + } 1.349 + if (!(p_cpufreq->scaling_available_frequencies = 1.350 + malloc(p_cpufreq->freq_num * sizeof(uint32_t)))) 1.351 + { 1.352 + fprintf(stderr, 1.353 + "[CPU%d] failed to malloc for scaling_available_frequencies\n", 1.354 + cpuid); 1.355 + ret = -ENOMEM; 1.356 + goto out; 1.357 + } 1.358 + if (!(p_cpufreq->scaling_available_governors = 1.359 + malloc(p_cpufreq->gov_num * CPUFREQ_NAME_LEN * sizeof(char)))) 1.360 + { 1.361 + fprintf(stderr, 1.362 + "[CPU%d] failed to malloc for scaling_available_governors\n", 1.363 + cpuid); 1.364 + ret = -ENOMEM; 1.365 + goto out; 1.366 + } 1.367 + 1.368 + ret = xc_get_cpufreq_para(xc_fd, cpuid, p_cpufreq); 1.369 + } while ( ret && errno == EAGAIN ); 1.370 + 1.371 + if ( ret == 0 ) 1.372 + print_cpufreq_para(cpuid, p_cpufreq); 1.373 + else if ( errno == ENODEV ) 1.374 + { 1.375 + ret = -ENODEV; 1.376 + fprintf(stderr, "Xen cpufreq is not enabled!\n"); 1.377 + } 1.378 + else 1.379 + fprintf(stderr, 1.380 + "[CPU%d] failed to get cpufreq parameter\n", 1.381 + cpuid); 1.382 + 1.383 +out: 1.384 + free(p_cpufreq->scaling_available_governors); 1.385 + free(p_cpufreq->scaling_available_frequencies); 1.386 + free(p_cpufreq->affected_cpus); 1.387 + 1.388 + return ret; 1.389 +} 1.390 + 1.391 +int cpufreq_para_func(int xc_fd, int cpuid, uint32_t value) 1.392 +{ 1.393 + int ret = 0; 1.394 + xc_physinfo_t physinfo = { 0 }; 1.395 + 1.396 + if ( cpuid < 0 ) 1.397 + { 1.398 + ret = xc_physinfo(xc_fd, &physinfo); 1.399 + if ( ret ) 1.400 + { 1.401 + fprintf(stderr, "failed to get the processor information\n"); 1.402 + } 1.403 + else 1.404 + { 1.405 + int i; 1.406 + for ( i = 0; i < physinfo.nr_cpus; i++ ) 1.407 + { 1.408 + if ( (ret = show_cpufreq_para_cpuid(xc_fd, i)) == -ENODEV ) 1.409 + break; 1.410 + } 1.411 + } 1.412 + } 1.413 + else 1.414 + ret = show_cpufreq_para_cpuid(xc_fd, cpuid); 1.415 + 1.416 + return ret; 1.417 +} 1.418 + 1.419 +int scaling_max_freq_func(int xc_fd, int cpuid, uint32_t value) 1.420 +{ 1.421 + int ret = 0; 1.422 + 1.423 + if ( cpuid < 0 ) 1.424 + { 1.425 + show_help(); 1.426 + return -EINVAL; 1.427 + } 1.428 + 1.429 + ret = xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MAX_FREQ, value); 1.430 + if ( ret ) 1.431 + { 1.432 + fprintf(stderr, "[CPU%d] failed to set scaling max freq\n", cpuid); 1.433 + } 1.434 + 1.435 + return ret; 1.436 +} 1.437 + 1.438 +int scaling_min_freq_func(int xc_fd, int cpuid, uint32_t value) 1.439 +{ 1.440 + int ret; 1.441 + 1.442 + if ( cpuid < 0 ) 1.443 + { 1.444 + show_help(); 1.445 + return -EINVAL; 1.446 + } 1.447 + 1.448 + ret = xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MIN_FREQ, value); 1.449 + if ( ret ) 1.450 + { 1.451 + fprintf(stderr, "[CPU%d] failed to set scaling min freq\n", cpuid); 1.452 + } 1.453 + 1.454 + return ret; 1.455 +} 1.456 + 1.457 +int scaling_speed_func(int xc_fd, int cpuid, uint32_t value) 1.458 +{ 1.459 + int ret; 1.460 + 1.461 + if ( cpuid < 0 ) 1.462 + { 1.463 + show_help(); 1.464 + return -EINVAL; 1.465 + } 1.466 + 1.467 + ret = xc_set_cpufreq_para(xc_fd, cpuid, SCALING_SETSPEED, value); 1.468 + if ( ret ) 1.469 + { 1.470 + fprintf(stderr, "[CPU%d] failed to set scaling speed\n", cpuid); 1.471 + } 1.472 + 1.473 + return ret; 1.474 +} 1.475 + 1.476 +int scaling_sampling_rate_func(int xc_fd, int cpuid, uint32_t value) 1.477 +{ 1.478 + int ret; 1.479 + 1.480 + if ( cpuid < 0 ) 1.481 + { 1.482 + show_help(); 1.483 + return -EINVAL; 1.484 + } 1.485 + 1.486 + ret = xc_set_cpufreq_para(xc_fd, cpuid, SAMPLING_RATE, value); 1.487 + if ( ret ) 1.488 + { 1.489 + fprintf(stderr, "[CPU%d] failed to set scaling sampling rate\n", cpuid); 1.490 + } 1.491 + 1.492 + return ret; 1.493 +} 1.494 + 1.495 +int scaling_up_threshold_func(int xc_fd, int cpuid, uint32_t value) 1.496 +{ 1.497 + int ret; 1.498 + 1.499 + if ( cpuid < 0 ) 1.500 + { 1.501 + show_help(); 1.502 + return -EINVAL; 1.503 + } 1.504 + 1.505 + ret = xc_set_cpufreq_para(xc_fd, cpuid, UP_THRESHOLD, value); 1.506 + if ( ret ) 1.507 + { 1.508 + fprintf(stderr, "[CPU%d] failed to set scaling threshold\n", cpuid); 1.509 + } 1.510 + 1.511 + return ret; 1.512 +} 1.513 + 1.514 +int scaling_governor_func(int xc_fd, int cpuid, char *name) 1.515 +{ 1.516 + int ret = 0; 1.517 + 1.518 + if ( cpuid < 0 ) 1.519 + { 1.520 + show_help(); 1.521 + return -EINVAL; 1.522 + } 1.523 + 1.524 + ret = xc_set_cpufreq_gov(xc_fd, cpuid, name); 1.525 + if ( ret ) 1.526 + { 1.527 + fprintf(stderr, "failed to set cpufreq governor to %s\n", name); 1.528 + } 1.529 + 1.530 + return ret; 1.531 +} 1.532 + 1.533 +struct { 1.534 + const char *name; 1.535 + int (*function)(int xc_fd, int cpuid, uint32_t value); 1.536 +} main_options[] = { 1.537 + { "help", help_func }, 1.538 + { "get-cpuidle-states", cxstates_func }, 1.539 + { "get-cpufreq-states", pxstates_func }, 1.540 + { "get-cpufreq-para", cpufreq_para_func }, 1.541 + { "set-scaling-maxfreq", scaling_max_freq_func }, 1.542 + { "set-scaling-minfreq", scaling_min_freq_func }, 1.543 + { "set-scaling-governor", NULL }, 1.544 + { "set-scaling-speed", scaling_speed_func }, 1.545 + { "set-sampling-rate", scaling_sampling_rate_func }, 1.546 + { "set-up-threshold", scaling_up_threshold_func }, 1.547 +}; 1.548 + 1.549 +int main(int argc, char *argv[]) 1.550 +{ 1.551 + int i, ret = -EINVAL; 1.552 + int xc_fd; 1.553 + int cpuid = -1; 1.554 + uint32_t value = 0; 1.555 + int nr_matches = 0; 1.556 + int matches_main_options[ARRAY_SIZE(main_options)]; 1.557 + 1.558 + if ( argc < 2 ) 1.559 + { 1.560 + show_help(); 1.561 + return ret; 1.562 + } 1.563 + 1.564 + if ( argc > 2 ) 1.565 + { 1.566 + if ( sscanf(argv[2], "%d", &cpuid) != 1 ) 1.567 + cpuid = -1; 1.568 } 1.569 1.570 xc_fd = xc_interface_open(); 1.571 if ( xc_fd < 0 ) 1.572 { 1.573 fprintf(stderr, "failed to get the handler\n"); 1.574 - return xc_fd; 1.575 - } 1.576 - 1.577 - ret = xc_physinfo(xc_fd, &physinfo); 1.578 - if ( ret ) 1.579 - { 1.580 - fprintf(stderr, "failed to get the processor information\n"); 1.581 - xc_interface_close(xc_fd); 1.582 - return ret; 1.583 } 1.584 1.585 - /* print out the C state information */ 1.586 - if ( cinfo ) 1.587 + for ( i = 0; i < ARRAY_SIZE(main_options); i++ ) 1.588 { 1.589 - int max_cx_num = 0; 1.590 - struct xc_cx_stat cxstatinfo, *cxstat = &cxstatinfo; 1.591 - 1.592 - for ( i = 0; i < physinfo.nr_cpus; i++ ) 1.593 + if ( !strncmp(main_options[i].name, argv[1], strlen(argv[1])) ) 1.594 { 1.595 - ret = xc_pm_get_max_cx(xc_fd, i, &max_cx_num); 1.596 - if ( ret ) 1.597 - { 1.598 - if ( errno == ENODEV ) 1.599 - { 1.600 - fprintf(stderr, "Xen cpuidle is not enabled!\n"); 1.601 - break; 1.602 - } 1.603 - else 1.604 - { 1.605 - fprintf(stderr, "[CPU%d] failed to get max C-state\n", i); 1.606 - continue; 1.607 - } 1.608 - } 1.609 - 1.610 - cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t)); 1.611 - if ( !cxstat->triggers ) 1.612 - { 1.613 - fprintf(stderr, "failed to malloc for C-states triggers\n"); 1.614 - break; 1.615 - } 1.616 - cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t)); 1.617 - if ( !cxstat->residencies ) 1.618 - { 1.619 - fprintf(stderr, "failed to malloc for C-states residencies\n"); 1.620 - free(cxstat->triggers); 1.621 - break; 1.622 - } 1.623 - 1.624 - ret = xc_pm_get_cxstat(xc_fd, i, cxstat); 1.625 - if( ret ) 1.626 - { 1.627 - fprintf(stderr, "[CPU%d] failed to get C-states statistics " 1.628 - "information\n", i); 1.629 - free(cxstat->triggers); 1.630 - free(cxstat->residencies); 1.631 - continue; 1.632 - } 1.633 - 1.634 - printf("cpu id : %d\n", i); 1.635 - printf("total C-states : %d\n", cxstat->nr); 1.636 - printf("idle time(ms) : %"PRIu64"\n", 1.637 - cxstat->idle_time/1000000UL); 1.638 - for ( j = 0; j < cxstat->nr; j++ ) 1.639 - { 1.640 - printf("C%d : transition [%020"PRIu64"]\n", 1.641 - j, cxstat->triggers[j]); 1.642 - printf(" residency [%020"PRIu64" ms]\n", 1.643 - cxstat->residencies[j]*1000000UL/3579/1000000UL); 1.644 - } 1.645 - 1.646 - free(cxstat->triggers); 1.647 - free(cxstat->residencies); 1.648 - 1.649 - printf("\n"); 1.650 + matches_main_options[nr_matches++] = i; 1.651 } 1.652 } 1.653 1.654 - /* print out P state information */ 1.655 - if ( pinfo ) 1.656 + if ( nr_matches > 1 ) 1.657 { 1.658 - int max_px_num = 0; 1.659 - struct xc_px_stat pxstatinfo, *pxstat = &pxstatinfo; 1.660 - 1.661 - for ( i = 0; i < physinfo.nr_cpus; i++ ) 1.662 + fprintf(stderr, "Ambigious options: "); 1.663 + for ( i = 0; i < nr_matches; i++ ) 1.664 + fprintf(stderr, " %s", main_options[matches_main_options[i]].name); 1.665 + fprintf(stderr, "\n"); 1.666 + } 1.667 + else if ( nr_matches == 1 ) 1.668 + { 1.669 + if ( !strcmp("set-scaling-governor", main_options[matches_main_options[0]].name) ) 1.670 { 1.671 - ret = xc_pm_get_max_px(xc_fd, i, &max_px_num); 1.672 - if ( ret ) 1.673 - { 1.674 - if ( errno == ENODEV ) 1.675 - { 1.676 - printf("Xen cpufreq is not enabled!\n"); 1.677 - break; 1.678 - } 1.679 - else 1.680 - { 1.681 - fprintf(stderr, "[CPU%d] failed to get max P-state\n", i); 1.682 - continue; 1.683 - } 1.684 - } 1.685 - 1.686 - pxstat->trans_pt = malloc(max_px_num * max_px_num * 1.687 - sizeof(uint64_t)); 1.688 - if ( !pxstat->trans_pt ) 1.689 - { 1.690 - fprintf(stderr, "failed to malloc for P-states " 1.691 - "transition table\n"); 1.692 - break; 1.693 - } 1.694 - pxstat->pt = malloc(max_px_num * sizeof(struct xc_px_val)); 1.695 - if ( !pxstat->pt ) 1.696 + char *name = strdup(argv[3]); 1.697 + ret = scaling_governor_func(xc_fd, cpuid, name); 1.698 + free(name); 1.699 + } 1.700 + else 1.701 + { 1.702 + if ( argc > 3 ) 1.703 { 1.704 - fprintf(stderr, "failed to malloc for P-states table\n"); 1.705 - free(pxstat->trans_pt); 1.706 - break; 1.707 - } 1.708 - 1.709 - ret = xc_pm_get_pxstat(xc_fd, i, pxstat); 1.710 - if( ret ) 1.711 - { 1.712 - fprintf(stderr, "[CPU%d] failed to get P-states " 1.713 - "statistics information\n", i); 1.714 - free(pxstat->trans_pt); 1.715 - free(pxstat->pt); 1.716 - continue; 1.717 + if ( sscanf(argv[3], "%d", &value) != 1 ) 1.718 + value = 0; 1.719 } 1.720 - 1.721 - printf("cpu id : %d\n", i); 1.722 - printf("total P-states : %d\n", pxstat->total); 1.723 - printf("usable P-states : %d\n", pxstat->usable); 1.724 - printf("current frequency : %"PRIu64" MHz\n", 1.725 - pxstat->pt[pxstat->cur].freq); 1.726 - for ( j = 0; j < pxstat->total; j++ ) 1.727 - { 1.728 - if ( pxstat->cur == j ) 1.729 - printf("*P%d", j); 1.730 - else 1.731 - printf("P%d ", j); 1.732 - printf(" : freq [%04"PRIu64" MHz]\n", 1.733 - pxstat->pt[j].freq); 1.734 - printf(" transition [%020"PRIu64"]\n", 1.735 - pxstat->pt[j].count); 1.736 - printf(" residency [%020"PRIu64" ms]\n", 1.737 - pxstat->pt[j].residency/1000000UL); 1.738 - } 1.739 - 1.740 - free(pxstat->trans_pt); 1.741 - free(pxstat->pt); 1.742 - 1.743 - printf("\n"); 1.744 + ret = main_options[matches_main_options[0]].function(xc_fd, cpuid, value); 1.745 } 1.746 } 1.747 + else 1.748 + show_help(); 1.749 1.750 xc_interface_close(xc_fd); 1.751 return ret;