debuggers.hg

annotate tools/misc/xenpm.c @ 22848:6341fe0f4e5a

Added tag 4.1.0-rc2 for changeset 9dca60d88c63
author Keir Fraser <keir@xen.org>
date Tue Jan 25 14:06:55 2011 +0000 (2011-01-25)
parents 9fad5e5e2fc1
children
rev   line source
keir@18581 1 /*
keir@18581 2 * xenpm.c: list the power information of the available processors
keir@18581 3 * Copyright (c) 2008, Intel Corporation.
keir@18581 4 *
keir@18581 5 * This program is free software; you can redistribute it and/or modify it
keir@18581 6 * under the terms and conditions of the GNU General Public License,
keir@18581 7 * version 2, as published by the Free Software Foundation.
keir@18581 8 *
keir@18581 9 * This program is distributed in the hope it will be useful, but WITHOUT
keir@18581 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
keir@18581 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
keir@18581 12 * more details.
keir@18581 13 *
keir@18581 14 * You should have received a copy of the GNU General Public License along with
keir@18581 15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
keir@18581 16 * Place - Suite 330, Boston, MA 02111-1307 USA.
keir@18581 17 */
Ian@21839 18 #define MAX_NR_CPU 512
keir@18581 19
keir@18581 20 #include <stdio.h>
keir@18581 21 #include <stdlib.h>
keir@19041 22 #include <unistd.h>
keir@18964 23 #include <string.h>
keir@18581 24 #include <getopt.h>
keir@18581 25 #include <errno.h>
keir@19041 26 #include <signal.h>
keir@18581 27
keir@18581 28 #include <xenctrl.h>
keir@18581 29 #include <inttypes.h>
keir@19081 30 #include <sys/time.h>
keir@18581 31
keir@18964 32 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
keir@18964 33
keir@21169 34 #define CPUFREQ_TURBO_DISABLED -1
keir@21169 35 #define CPUFREQ_TURBO_UNSUPPORTED 0
keir@21169 36 #define CPUFREQ_TURBO_ENABLED 1
keir@21169 37
keir@21529 38 static xc_interface *xc_handle;
keir@19041 39 static int max_cpu_nr;
keir@19041 40
keir@18964 41 /* help message */
keir@18964 42 void show_help(void)
keir@18964 43 {
keir@18964 44 fprintf(stderr,
keir@19041 45 "xen power management control tool\n\n"
keir@19041 46 "usage: xenpm <command> [args]\n\n"
keir@19041 47 "xenpm command list:\n\n"
keir@19041 48 " get-cpuidle-states [cpuid] list cpu idle info of CPU <cpuid> or all\n"
keir@19041 49 " get-cpufreq-states [cpuid] list cpu freq info of CPU <cpuid> or all\n"
keir@19041 50 " get-cpufreq-para [cpuid] list cpu freq parameter of CPU <cpuid> or all\n"
keir@19041 51 " set-scaling-maxfreq [cpuid] <HZ> set max cpu frequency <HZ> on CPU <cpuid>\n"
keir@19041 52 " or all CPUs\n"
keir@19041 53 " set-scaling-minfreq [cpuid] <HZ> set min cpu frequency <HZ> on CPU <cpuid>\n"
keir@19041 54 " or all CPUs\n"
keir@19041 55 " set-scaling-speed [cpuid] <num> set scaling speed on CPU <cpuid> or all\n"
keir@19041 56 " it is used in userspace governor.\n"
keir@19041 57 " set-scaling-governor [cpuid] <gov> set scaling governor on CPU <cpuid> or all\n"
keir@19041 58 " as userspace/performance/powersave/ondemand\n"
keir@19041 59 " set-sampling-rate [cpuid] <num> set sampling rate on CPU <cpuid> or all\n"
keir@19041 60 " it is used in ondemand governor.\n"
keir@19041 61 " set-up-threshold [cpuid] <num> set up threshold on CPU <cpuid> or all\n"
keir@19041 62 " it is used in ondemand governor.\n"
keir@19393 63 " get-cpu-topology get thread/core/socket topology info\n"
keir@19450 64 " set-sched-smt enable|disable enable/disable scheduler smt power saving\n"
keir@19540 65 " set-vcpu-migration-delay <num> set scheduler vcpu migration delay in us\n"
keir@19540 66 " get-vcpu-migration-delay get scheduler vcpu migration delay\n"
keir@19478 67 " set-max-cstate <num> set the C-State limitation (<num> >= 0)\n"
keir@19432 68 " start [seconds] start collect Cx/Px statistics,\n"
keir@19432 69 " output after CTRL-C or SIGINT or several seconds.\n"
keir@21169 70 " enable-turbo-mode [cpuid] enable Turbo Mode for processors that support it.\n"
keir@21169 71 " disable-turbo-mode [cpuid] disable Turbo Mode for processors that support it.\n"
keir@19041 72 );
keir@18964 73 }
keir@18964 74 /* wrapper function */
keir@19041 75 void help_func(int argc, char *argv[])
keir@18964 76 {
keir@18964 77 show_help();
keir@18964 78 }
keir@18964 79
keir@19041 80 static void print_cxstat(int cpuid, struct xc_cx_stat *cxstat)
keir@18581 81 {
keir@19041 82 int i;
keir@18964 83
keir@18964 84 printf("cpu id : %d\n", cpuid);
keir@18964 85 printf("total C-states : %d\n", cxstat->nr);
keir@18964 86 printf("idle time(ms) : %"PRIu64"\n",
keir@18964 87 cxstat->idle_time/1000000UL);
keir@18964 88 for ( i = 0; i < cxstat->nr; i++ )
keir@18964 89 {
keir@18964 90 printf("C%d : transition [%020"PRIu64"]\n",
keir@18964 91 i, cxstat->triggers[i]);
keir@18964 92 printf(" residency [%020"PRIu64" ms]\n",
keir@18973 93 cxstat->residencies[i]/1000000UL);
keir@18964 94 }
Ian@21839 95 printf("pc3 : [%020"PRIu64" ms]\n"
Ian@21839 96 "pc6 : [%020"PRIu64" ms]\n"
Ian@21839 97 "pc7 : [%020"PRIu64" ms]\n",
Ian@21839 98 cxstat->pc3/1000000UL, cxstat->pc6/1000000UL, cxstat->pc7/1000000UL);
Ian@21839 99 printf("cc3 : [%020"PRIu64" ms]\n"
Ian@21839 100 "cc6 : [%020"PRIu64" ms]\n",
Ian@21839 101 cxstat->cc3/1000000UL, cxstat->cc6/1000000UL);
keir@19041 102 printf("\n");
keir@19041 103 }
keir@18964 104
keir@19041 105 /* show cpu idle information on CPU cpuid */
keir@21529 106 static int get_cxstat_by_cpuid(xc_interface *xc_handle, int cpuid, struct xc_cx_stat *cxstat)
keir@19041 107 {
keir@19041 108 int ret = 0;
keir@19041 109 int max_cx_num = 0;
keir@19041 110
keir@21529 111 ret = xc_pm_get_max_cx(xc_handle, cpuid, &max_cx_num);
keir@19041 112 if ( ret )
keir@19041 113 return errno;
keir@19041 114
keir@19041 115 if ( !cxstat )
keir@19041 116 return -EINVAL;
keir@18964 117
keir@19041 118 cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t));
keir@19041 119 if ( !cxstat->triggers )
keir@19041 120 return -ENOMEM;
keir@19041 121 cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t));
keir@19041 122 if ( !cxstat->residencies )
keir@19041 123 {
keir@19041 124 free(cxstat->triggers);
keir@19041 125 return -ENOMEM;
keir@19041 126 }
keir@19041 127
keir@21529 128 ret = xc_pm_get_cxstat(xc_handle, cpuid, cxstat);
keir@19041 129 if( ret )
keir@19041 130 {
keir@19041 131 int temp = errno;
keir@19041 132 free(cxstat->triggers);
keir@19041 133 free(cxstat->residencies);
keir@19041 134 cxstat->triggers = NULL;
keir@19041 135 cxstat->residencies = NULL;
keir@19041 136 return temp;
keir@19041 137 }
keir@19041 138
keir@18964 139 return 0;
keir@18964 140 }
keir@18964 141
keir@21529 142 static int show_max_cstate(xc_interface *xc_handle)
keir@19478 143 {
keir@19478 144 int ret = 0;
keir@19478 145 uint32_t value;
keir@19478 146
keir@21529 147 if ( (ret = xc_get_cpuidle_max_cstate(xc_handle, &value)) )
keir@19478 148 return ret;
keir@19478 149
keir@19478 150 printf("Max C-state: C%d\n\n", value);
keir@19478 151 return 0;
keir@19478 152 }
keir@19478 153
keir@21529 154 static int show_cxstat_by_cpuid(xc_interface *xc_handle, int cpuid)
keir@18964 155 {
keir@18964 156 int ret = 0;
keir@19041 157 struct xc_cx_stat cxstatinfo;
keir@19041 158
keir@21529 159 ret = get_cxstat_by_cpuid(xc_handle, cpuid, &cxstatinfo);
keir@19041 160 if ( ret )
keir@19041 161 return ret;
keir@19041 162
keir@19041 163 print_cxstat(cpuid, &cxstatinfo);
keir@19041 164
keir@19041 165 free(cxstatinfo.triggers);
keir@19041 166 free(cxstatinfo.residencies);
keir@19041 167 return 0;
keir@19041 168 }
keir@19041 169
keir@19041 170 void cxstat_func(int argc, char *argv[])
keir@19041 171 {
keir@19041 172 int cpuid = -1;
keir@19041 173
keir@19041 174 if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
keir@19041 175 cpuid = -1;
keir@19041 176
keir@19041 177 if ( cpuid >= max_cpu_nr )
keir@19041 178 cpuid = -1;
keir@18581 179
keir@21529 180 show_max_cstate(xc_handle);
keir@19478 181
keir@18964 182 if ( cpuid < 0 )
keir@18581 183 {
keir@19041 184 /* show cxstates on all cpus */
keir@19041 185 int i;
keir@19041 186 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 187 if ( show_cxstat_by_cpuid(xc_handle, i) == -ENODEV )
keir@19041 188 break;
keir@18964 189 }
keir@18964 190 else
keir@21529 191 show_cxstat_by_cpuid(xc_handle, cpuid);
keir@18964 192 }
keir@18964 193
keir@19041 194 static void print_pxstat(int cpuid, struct xc_px_stat *pxstat)
keir@18964 195 {
keir@19041 196 int i;
keir@18964 197
keir@18964 198 printf("cpu id : %d\n", cpuid);
keir@18964 199 printf("total P-states : %d\n", pxstat->total);
keir@18964 200 printf("usable P-states : %d\n", pxstat->usable);
keir@18964 201 printf("current frequency : %"PRIu64" MHz\n",
keir@18964 202 pxstat->pt[pxstat->cur].freq);
keir@18964 203 for ( i = 0; i < pxstat->total; i++ )
keir@18964 204 {
keir@18964 205 if ( pxstat->cur == i )
keir@18964 206 printf("*P%d", i);
keir@18964 207 else
keir@18964 208 printf("P%d ", i);
keir@18964 209 printf(" : freq [%04"PRIu64" MHz]\n",
keir@18964 210 pxstat->pt[i].freq);
keir@18964 211 printf(" transition [%020"PRIu64"]\n",
keir@18964 212 pxstat->pt[i].count);
keir@18964 213 printf(" residency [%020"PRIu64" ms]\n",
keir@18964 214 pxstat->pt[i].residency/1000000UL);
keir@18964 215 }
keir@19041 216 printf("\n");
keir@19041 217 }
keir@18964 218
keir@19041 219 /* show cpu frequency information on CPU cpuid */
keir@21529 220 static int get_pxstat_by_cpuid(xc_interface *xc_handle, int cpuid, struct xc_px_stat *pxstat)
keir@19041 221 {
keir@19041 222 int ret = 0;
keir@19041 223 int max_px_num = 0;
keir@19041 224
keir@21529 225 ret = xc_pm_get_max_px(xc_handle, cpuid, &max_px_num);
keir@19041 226 if ( ret )
keir@19041 227 return errno;
keir@19041 228
keir@19041 229 if ( !pxstat)
keir@19041 230 return -EINVAL;
keir@18964 231
keir@19041 232 pxstat->trans_pt = malloc(max_px_num * max_px_num *
keir@19041 233 sizeof(uint64_t));
keir@19041 234 if ( !pxstat->trans_pt )
keir@19041 235 return -ENOMEM;
keir@19041 236 pxstat->pt = malloc(max_px_num * sizeof(struct xc_px_val));
keir@19041 237 if ( !pxstat->pt )
keir@19041 238 {
keir@19041 239 free(pxstat->trans_pt);
keir@19041 240 return -ENOMEM;
keir@19041 241 }
keir@19041 242
keir@21529 243 ret = xc_pm_get_pxstat(xc_handle, cpuid, pxstat);
keir@19041 244 if( ret )
keir@19041 245 {
keir@19041 246 int temp = errno;
keir@19041 247 free(pxstat->trans_pt);
keir@19041 248 free(pxstat->pt);
keir@19041 249 pxstat->trans_pt = NULL;
keir@19041 250 pxstat->pt = NULL;
keir@19041 251 return temp;
keir@19041 252 }
keir@19041 253
keir@18964 254 return 0;
keir@18964 255 }
keir@18964 256
keir@19447 257 /* show cpu actual average freq information on CPU cpuid */
keir@21529 258 static int get_avgfreq_by_cpuid(xc_interface *xc_handle, int cpuid, int *avgfreq)
keir@19447 259 {
keir@19447 260 int ret = 0;
keir@19447 261
keir@21529 262 ret = xc_get_cpufreq_avgfreq(xc_handle, cpuid, avgfreq);
keir@19447 263 if ( ret )
keir@19447 264 {
keir@19447 265 return errno;
keir@19447 266 }
keir@19447 267
keir@19447 268 return 0;
keir@19447 269 }
keir@19447 270
keir@21529 271 static int show_pxstat_by_cpuid(xc_interface *xc_handle, int cpuid)
keir@18964 272 {
keir@18964 273 int ret = 0;
keir@19041 274 struct xc_px_stat pxstatinfo;
keir@19041 275
keir@21529 276 ret = get_pxstat_by_cpuid(xc_handle, cpuid, &pxstatinfo);
keir@19041 277 if ( ret )
keir@19041 278 return ret;
keir@19041 279
keir@19041 280 print_pxstat(cpuid, &pxstatinfo);
keir@19041 281
keir@19041 282 free(pxstatinfo.trans_pt);
keir@19041 283 free(pxstatinfo.pt);
keir@19041 284 return 0;
keir@19041 285 }
keir@19041 286
keir@19041 287 void pxstat_func(int argc, char *argv[])
keir@19041 288 {
keir@19041 289 int cpuid = -1;
keir@19041 290
keir@19041 291 if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
keir@19041 292 cpuid = -1;
keir@19041 293
keir@19041 294 if ( cpuid >= max_cpu_nr )
keir@19041 295 cpuid = -1;
keir@18964 296
keir@18964 297 if ( cpuid < 0 )
keir@18964 298 {
keir@19041 299 /* show pxstates on all cpus */
keir@19041 300 int i;
keir@19041 301 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 302 if ( show_pxstat_by_cpuid(xc_handle, i) == -ENODEV )
keir@19041 303 break;
keir@19041 304 }
keir@19041 305 else
keir@21529 306 show_pxstat_by_cpuid(xc_handle, cpuid);
keir@19041 307 }
keir@19041 308
keir@19041 309 static uint64_t usec_start, usec_end;
keir@19041 310 static struct xc_cx_stat *cxstat, *cxstat_start, *cxstat_end;
keir@19041 311 static struct xc_px_stat *pxstat, *pxstat_start, *pxstat_end;
keir@19447 312 static int *avgfreq;
keir@19041 313 static uint64_t *sum, *sum_cx, *sum_px;
keir@19041 314
keir@19041 315 static void signal_int_handler(int signo)
keir@19041 316 {
Ian@21839 317 int i, j, k, ret;
keir@19041 318 struct timeval tv;
keir@19041 319 int cx_cap = 0, px_cap = 0;
ian@22355 320 DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_core);
ian@22355 321 DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_socket);
ian@22355 322 DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_node);
Ian@21839 323 xc_topologyinfo_t info = { 0 };
keir@19041 324
ian@22355 325 cpu_to_core = xc_hypercall_buffer_alloc(xc_handle, cpu_to_core, sizeof(*cpu_to_core) * MAX_NR_CPU);
ian@22355 326 cpu_to_socket = xc_hypercall_buffer_alloc(xc_handle, cpu_to_socket, sizeof(*cpu_to_socket) * MAX_NR_CPU);
ian@22355 327 cpu_to_node = xc_hypercall_buffer_alloc(xc_handle, cpu_to_node, sizeof(*cpu_to_node) * MAX_NR_CPU);
ian@22355 328
ian@22355 329 if ( cpu_to_core == NULL || cpu_to_socket == NULL || cpu_to_node == NULL )
ian@22355 330 {
ian@22355 331 fprintf(stderr, "failed to allocate hypercall buffers\n");
ian@22355 332 goto out;
ian@22355 333 }
ian@22355 334
keir@19041 335 if ( gettimeofday(&tv, NULL) == -1 )
keir@19041 336 {
keir@19041 337 fprintf(stderr, "failed to get timeofday\n");
ian@22355 338 goto out ;
keir@19041 339 }
keir@19041 340 usec_end = tv.tv_sec * 1000000UL + tv.tv_usec;
keir@19041 341
keir@21529 342 if ( get_cxstat_by_cpuid(xc_handle, 0, NULL) != -ENODEV )
keir@19041 343 {
keir@19041 344 cx_cap = 1;
keir@19041 345 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 346 if ( !get_cxstat_by_cpuid(xc_handle, i, &cxstat_end[i]) )
keir@19041 347 for ( j = 0; j < cxstat_end[i].nr; j++ )
keir@19041 348 sum_cx[i] += cxstat_end[i].residencies[j] -
keir@19041 349 cxstat_start[i].residencies[j];
keir@19041 350 }
keir@19041 351
keir@21529 352 if ( get_pxstat_by_cpuid(xc_handle, 0, NULL) != -ENODEV )
keir@19041 353 {
keir@19041 354 px_cap = 1;
keir@19041 355 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 356 if ( !get_pxstat_by_cpuid(xc_handle, i , &pxstat_end[i]) )
keir@19041 357 for ( j = 0; j < pxstat_end[i].total; j++ )
keir@19041 358 sum_px[i] += pxstat_end[i].pt[j].residency -
keir@19041 359 pxstat_start[i].pt[j].residency;
keir@19041 360 }
keir@19041 361
keir@19447 362 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 363 get_avgfreq_by_cpuid(xc_handle, i, &avgfreq[i]);
keir@19447 364
keir@19041 365 printf("Elapsed time (ms): %"PRIu64"\n", (usec_end - usec_start) / 1000UL);
keir@19041 366 for ( i = 0; i < max_cpu_nr; i++ )
keir@19041 367 {
keir@19256 368 uint64_t res, triggers;
keir@19256 369 double avg_res;
keir@19256 370
keir@19256 371 printf("\nCPU%d:\tResidency(ms)\t\tAvg Res(ms)\n",i);
keir@19256 372 if ( cx_cap && sum_cx[i] > 0 )
keir@18964 373 {
keir@19041 374 for ( j = 0; j < cxstat_end[i].nr; j++ )
keir@19041 375 {
keir@19256 376 res = cxstat_end[i].residencies[j] -
keir@19256 377 cxstat_start[i].residencies[j];
keir@19256 378 triggers = cxstat_end[i].triggers[j] -
keir@19256 379 cxstat_start[i].triggers[j];
keir@19256 380 avg_res = (triggers==0) ? 0: (double)res/triggers/1000000.0;
keir@19256 381 printf(" C%d\t%"PRIu64"\t(%5.2f%%)\t%.2f\n", j, res/1000000UL,
keir@19256 382 100 * res / (double)sum_cx[i], avg_res );
keir@19041 383 }
keir@19256 384 printf("\n");
keir@18964 385 }
keir@19256 386 if ( px_cap && sum_px[i]>0 )
keir@18964 387 {
keir@19041 388 for ( j = 0; j < pxstat_end[i].total; j++ )
keir@18964 389 {
keir@19256 390 res = pxstat_end[i].pt[j].residency -
keir@19256 391 pxstat_start[i].pt[j].residency;
keir@19256 392 printf(" P%d\t%"PRIu64"\t(%5.2f%%)\n", j,
keir@19256 393 res / 1000000UL, 100UL * res / (double)sum_px[i]);
keir@18964 394 }
keir@18964 395 }
Ian@21839 396 }
Ian@21839 397
ian@22358 398 set_xen_guest_handle(info.cpu_to_core, cpu_to_core);
ian@22358 399 set_xen_guest_handle(info.cpu_to_socket, cpu_to_socket);
ian@22358 400 set_xen_guest_handle(info.cpu_to_node, cpu_to_node);
Ian@21839 401 info.max_cpu_index = MAX_NR_CPU - 1;
Ian@21839 402
Ian@21839 403 ret = xc_topologyinfo(xc_handle, &info);
Ian@21839 404 if ( !ret )
Ian@21839 405 {
Ian@21839 406 uint32_t socket_ids[MAX_NR_CPU];
Ian@21839 407 uint32_t core_ids[MAX_NR_CPU];
Ian@21839 408 uint32_t socket_nr = 0;
Ian@21839 409 uint32_t core_nr = 0;
Ian@21839 410
Ian@21839 411 if ( info.max_cpu_index > MAX_NR_CPU - 1 )
Ian@21839 412 info.max_cpu_index = MAX_NR_CPU - 1;
Ian@21839 413 /* check validity */
Ian@21839 414 for ( i = 0; i <= info.max_cpu_index; i++ )
Ian@21839 415 {
Ian@21839 416 if ( cpu_to_core[i] == INVALID_TOPOLOGY_ID ||
Ian@21839 417 cpu_to_socket[i] == INVALID_TOPOLOGY_ID )
Ian@21839 418 break;
Ian@21839 419 }
Ian@21839 420 if ( i > info.max_cpu_index )
Ian@21839 421 {
Ian@21839 422 /* find socket nr & core nr per socket */
Ian@21839 423 for ( i = 0; i <= info.max_cpu_index; i++ )
Ian@21839 424 {
Ian@21839 425 for ( j = 0; j < socket_nr; j++ )
Ian@21839 426 if ( cpu_to_socket[i] == socket_ids[j] )
Ian@21839 427 break;
Ian@21839 428 if ( j == socket_nr )
Ian@21839 429 {
Ian@21839 430 socket_ids[j] = cpu_to_socket[i];
Ian@21839 431 socket_nr++;
Ian@21839 432 }
Ian@21839 433
Ian@21839 434 for ( j = 0; j < core_nr; j++ )
Ian@21839 435 if ( cpu_to_core[i] == core_ids[j] )
Ian@21839 436 break;
Ian@21839 437 if ( j == core_nr )
Ian@21839 438 {
Ian@21839 439 core_ids[j] = cpu_to_core[i];
Ian@21839 440 core_nr++;
Ian@21839 441 }
Ian@21839 442 }
Ian@21839 443
Ian@21839 444 /* print out CC? and PC? */
Ian@21839 445 for ( i = 0; i < socket_nr; i++ )
Ian@21839 446 {
Ian@21839 447 uint64_t res;
Ian@21839 448 for ( j = 0; j <= info.max_cpu_index; j++ )
Ian@21839 449 {
Ian@21839 450 if ( cpu_to_socket[j] == socket_ids[i] )
Ian@21839 451 break;
Ian@21839 452 }
Ian@21839 453 printf("Socket %d\n", socket_ids[i]);
Ian@21839 454 res = cxstat_end[j].pc3 - cxstat_start[j].pc3;
Ian@21839 455 printf("\tPC3\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL,
Ian@21839 456 100UL * res / (double)sum_cx[j]);
Ian@21839 457 res = cxstat_end[j].pc6 - cxstat_start[j].pc6;
Ian@21839 458 printf("\tPC6\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL,
Ian@21839 459 100UL * res / (double)sum_cx[j]);
Ian@21839 460 res = cxstat_end[j].pc7 - cxstat_start[j].pc7;
Ian@21839 461 printf("\tPC7\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL,
Ian@21839 462 100UL * res / (double)sum_cx[j]);
Ian@21839 463 for ( k = 0; k < core_nr; k++ )
Ian@21839 464 {
Ian@21839 465 for ( j = 0; j <= info.max_cpu_index; j++ )
Ian@21839 466 {
Ian@21839 467 if ( cpu_to_socket[j] == socket_ids[i] &&
Ian@21839 468 cpu_to_core[j] == core_ids[k] )
Ian@21839 469 break;
Ian@21839 470 }
Ian@21839 471 printf("\t Core %d CPU %d\n", core_ids[k], j);
Ian@21839 472 res = cxstat_end[j].cc3 - cxstat_start[j].cc3;
Ian@21839 473 printf("\t\tCC3\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL,
Ian@21839 474 100UL * res / (double)sum_cx[j]);
Ian@21839 475 res = cxstat_end[j].cc6 - cxstat_start[j].cc6;
Ian@21839 476 printf("\t\tCC6\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL,
Ian@21839 477 100UL * res / (double)sum_cx[j]);
Ian@21839 478 printf("\n");
Ian@21839 479
Ian@21839 480 }
Ian@21839 481 }
Ian@21839 482 }
keir@19447 483 printf(" Avg freq\t%d\tKHz\n", avgfreq[i]);
keir@18964 484 }
keir@19041 485
keir@19041 486 /* some clean up and then exits */
keir@19041 487 for ( i = 0; i < 2 * max_cpu_nr; i++ )
keir@19041 488 {
keir@19041 489 free(cxstat[i].triggers);
keir@19041 490 free(cxstat[i].residencies);
keir@19041 491 free(pxstat[i].trans_pt);
keir@19041 492 free(pxstat[i].pt);
keir@19041 493 }
keir@19041 494 free(cxstat);
keir@19041 495 free(pxstat);
keir@19041 496 free(sum);
keir@19447 497 free(avgfreq);
ian@22355 498 out:
ian@22355 499 xc_hypercall_buffer_free(xc_handle, cpu_to_core);
ian@22355 500 xc_hypercall_buffer_free(xc_handle, cpu_to_socket);
ian@22355 501 xc_hypercall_buffer_free(xc_handle, cpu_to_node);
keir@21529 502 xc_interface_close(xc_handle);
keir@19041 503 exit(0);
keir@19041 504 }
keir@19041 505
keir@19041 506 void start_gather_func(int argc, char *argv[])
keir@19041 507 {
keir@19041 508 int i;
keir@19041 509 struct timeval tv;
keir@19432 510 int timeout = 0;
keir@19432 511
keir@19432 512 if ( argc == 1 )
keir@19432 513 {
keir@19432 514 sscanf(argv[0], "%d", &timeout);
keir@19432 515 if ( timeout <= 0 )
keir@19432 516 fprintf(stderr, "failed to set timeout seconds, falling back...\n");
keir@19432 517 else
keir@19432 518 printf("Timeout set to %d seconds\n", timeout);
keir@19432 519 }
keir@19041 520
keir@19041 521 if ( gettimeofday(&tv, NULL) == -1 )
keir@19041 522 {
keir@19041 523 fprintf(stderr, "failed to get timeofday\n");
keir@19041 524 return ;
keir@19041 525 }
keir@19041 526 usec_start = tv.tv_sec * 1000000UL + tv.tv_usec;
keir@18964 527
keir@19041 528 sum = malloc(sizeof(uint64_t) * 2 * max_cpu_nr);
keir@19041 529 if ( sum == NULL )
keir@19041 530 return ;
keir@19041 531 cxstat = malloc(sizeof(struct xc_cx_stat) * 2 * max_cpu_nr);
keir@19041 532 if ( cxstat == NULL )
keir@19041 533 {
keir@19041 534 free(sum);
keir@19041 535 return ;
keir@19041 536 }
keir@19041 537 pxstat = malloc(sizeof(struct xc_px_stat) * 2 * max_cpu_nr);
keir@19041 538 if ( pxstat == NULL )
keir@19041 539 {
keir@19041 540 free(sum);
keir@19041 541 free(cxstat);
keir@19041 542 return ;
keir@19041 543 }
keir@19447 544 avgfreq = malloc(sizeof(int) * max_cpu_nr);
keir@19447 545 if ( avgfreq == NULL )
keir@19447 546 {
keir@19447 547 free(sum);
keir@19447 548 free(cxstat);
keir@19447 549 free(pxstat);
keir@19447 550 return ;
keir@19447 551 }
keir@19041 552 memset(sum, 0, sizeof(uint64_t) * 2 * max_cpu_nr);
keir@19041 553 memset(cxstat, 0, sizeof(struct xc_cx_stat) * 2 * max_cpu_nr);
keir@19041 554 memset(pxstat, 0, sizeof(struct xc_px_stat) * 2 * max_cpu_nr);
keir@19447 555 memset(avgfreq, 0, sizeof(int) * max_cpu_nr);
keir@19041 556 sum_cx = sum;
keir@19041 557 sum_px = sum + max_cpu_nr;
keir@19041 558 cxstat_start = cxstat;
keir@19041 559 cxstat_end = cxstat + max_cpu_nr;
keir@19041 560 pxstat_start = pxstat;
keir@19041 561 pxstat_end = pxstat + max_cpu_nr;
keir@19041 562
keir@21529 563 if ( get_cxstat_by_cpuid(xc_handle, 0, NULL) == -ENODEV &&
keir@21529 564 get_pxstat_by_cpuid(xc_handle, 0, NULL) == -ENODEV )
keir@19041 565 {
keir@19041 566 fprintf(stderr, "Xen cpu idle and frequency is disabled!\n");
keir@19041 567 return ;
keir@19041 568 }
keir@19041 569
keir@19041 570 for ( i = 0; i < max_cpu_nr; i++ )
keir@19041 571 {
keir@21529 572 get_cxstat_by_cpuid(xc_handle, i, &cxstat_start[i]);
keir@21529 573 get_pxstat_by_cpuid(xc_handle, i, &pxstat_start[i]);
keir@21529 574 get_avgfreq_by_cpuid(xc_handle, i, &avgfreq[i]);
keir@19041 575 }
keir@19041 576
keir@19041 577 if (signal(SIGINT, signal_int_handler) == SIG_ERR)
keir@19041 578 {
keir@19041 579 fprintf(stderr, "failed to set signal int handler\n");
keir@19041 580 free(sum);
keir@19041 581 free(pxstat);
keir@19041 582 free(cxstat);
keir@19447 583 free(avgfreq);
keir@19041 584 return ;
keir@19041 585 }
keir@19432 586
keir@19432 587 if ( timeout > 0 )
keir@19432 588 {
keir@19432 589 if ( signal(SIGALRM, signal_int_handler) == SIG_ERR )
keir@19432 590 {
keir@19432 591 fprintf(stderr, "failed to set signal alarm handler\n");
keir@19432 592 free(sum);
keir@19432 593 free(pxstat);
keir@19432 594 free(cxstat);
keir@19447 595 free(avgfreq);
keir@19432 596 return ;
keir@19432 597 }
keir@19432 598 alarm(timeout);
keir@19432 599 }
keir@19432 600
keir@19432 601 printf("Start sampling, waiting for CTRL-C or SIGINT or SIGALARM signal ...\n");
keir@19041 602
keir@19041 603 pause();
keir@18964 604 }
keir@18964 605
keir@18964 606 /* print out parameters about cpu frequency */
keir@18964 607 static void print_cpufreq_para(int cpuid, struct xc_get_cpufreq_para *p_cpufreq)
keir@18964 608 {
keir@18964 609 int i;
keir@18964 610
keir@18964 611 printf("cpu id : %d\n", cpuid);
keir@18964 612
keir@18964 613 printf("affected_cpus :");
keir@18964 614 for ( i = 0; i < p_cpufreq->cpu_num; i++ )
keir@21370 615 printf(" %d", p_cpufreq->affected_cpus[i]);
keir@18964 616 printf("\n");
keir@18964 617
keir@18964 618 printf("cpuinfo frequency : max [%u] min [%u] cur [%u]\n",
keir@18964 619 p_cpufreq->cpuinfo_max_freq,
keir@18964 620 p_cpufreq->cpuinfo_min_freq,
keir@18964 621 p_cpufreq->cpuinfo_cur_freq);
keir@18964 622
keir@18964 623 printf("scaling_driver : %s\n", p_cpufreq->scaling_driver);
keir@18964 624
keir@18964 625 printf("scaling_avail_gov : %s\n",
keir@18964 626 p_cpufreq->scaling_available_governors);
keir@18964 627
keir@18964 628 printf("current_governor : %s\n", p_cpufreq->scaling_governor);
keir@18964 629 if ( !strncmp(p_cpufreq->scaling_governor,
keir@18964 630 "userspace", CPUFREQ_NAME_LEN) )
keir@18964 631 {
keir@18964 632 printf(" userspace specific :\n");
keir@18964 633 printf(" scaling_setspeed : %u\n",
keir@18964 634 p_cpufreq->u.userspace.scaling_setspeed);
keir@18964 635 }
keir@18964 636 else if ( !strncmp(p_cpufreq->scaling_governor,
keir@18964 637 "ondemand", CPUFREQ_NAME_LEN) )
keir@18964 638 {
keir@18964 639 printf(" ondemand specific :\n");
keir@18964 640 printf(" sampling_rate : max [%u] min [%u] cur [%u]\n",
keir@18964 641 p_cpufreq->u.ondemand.sampling_rate_max,
keir@18964 642 p_cpufreq->u.ondemand.sampling_rate_min,
keir@18964 643 p_cpufreq->u.ondemand.sampling_rate);
keir@18964 644 printf(" up_threshold : %u\n",
keir@18964 645 p_cpufreq->u.ondemand.up_threshold);
keir@18964 646 }
keir@18964 647
keir@18964 648 printf("scaling_avail_freq :");
keir@18964 649 for ( i = 0; i < p_cpufreq->freq_num; i++ )
keir@19041 650 if ( p_cpufreq->scaling_available_frequencies[i] ==
keir@19041 651 p_cpufreq->scaling_cur_freq )
keir@18964 652 printf(" *%d", p_cpufreq->scaling_available_frequencies[i]);
keir@18964 653 else
keir@18964 654 printf(" %d", p_cpufreq->scaling_available_frequencies[i]);
keir@18964 655 printf("\n");
keir@18964 656
keir@18964 657 printf("scaling frequency : max [%u] min [%u] cur [%u]\n",
keir@18964 658 p_cpufreq->scaling_max_freq,
keir@18964 659 p_cpufreq->scaling_min_freq,
keir@18964 660 p_cpufreq->scaling_cur_freq);
keir@21169 661 if (p_cpufreq->turbo_enabled != CPUFREQ_TURBO_UNSUPPORTED) {
keir@21169 662 printf("turbo mode : ");
keir@21169 663 if (p_cpufreq->turbo_enabled == CPUFREQ_TURBO_ENABLED)
keir@21169 664 printf("enabled\n");
keir@21169 665 else
keir@21169 666 printf("disabled\n");
keir@21169 667 }
keir@18964 668 printf("\n");
keir@18964 669 }
keir@18964 670
keir@18964 671 /* show cpu frequency parameters information on CPU cpuid */
keir@21529 672 static int show_cpufreq_para_by_cpuid(xc_interface *xc_handle, int cpuid)
keir@18964 673 {
keir@18964 674 int ret = 0;
keir@18964 675 struct xc_get_cpufreq_para cpufreq_para, *p_cpufreq = &cpufreq_para;
keir@18964 676
keir@18964 677 p_cpufreq->cpu_num = 0;
keir@18964 678 p_cpufreq->freq_num = 0;
keir@18964 679 p_cpufreq->gov_num = 0;
keir@18964 680 p_cpufreq->affected_cpus = NULL;
keir@18964 681 p_cpufreq->scaling_available_frequencies = NULL;
keir@18964 682 p_cpufreq->scaling_available_governors = NULL;
keir@21169 683 p_cpufreq->turbo_enabled = 0;
keir@18964 684
keir@18964 685 do
keir@18581 686 {
keir@18964 687 free(p_cpufreq->affected_cpus);
keir@18964 688 free(p_cpufreq->scaling_available_frequencies);
keir@18964 689 free(p_cpufreq->scaling_available_governors);
keir@18964 690
keir@18964 691 p_cpufreq->affected_cpus = NULL;
keir@18964 692 p_cpufreq->scaling_available_frequencies = NULL;
keir@18964 693 p_cpufreq->scaling_available_governors = NULL;
keir@18964 694
keir@18964 695 if (!(p_cpufreq->affected_cpus =
keir@18964 696 malloc(p_cpufreq->cpu_num * sizeof(uint32_t))))
keir@18964 697 {
keir@18964 698 fprintf(stderr,
keir@18964 699 "[CPU%d] failed to malloc for affected_cpus\n",
keir@18964 700 cpuid);
keir@18964 701 ret = -ENOMEM;
keir@18964 702 goto out;
keir@18964 703 }
keir@18964 704 if (!(p_cpufreq->scaling_available_frequencies =
keir@18964 705 malloc(p_cpufreq->freq_num * sizeof(uint32_t))))
keir@18964 706 {
keir@18964 707 fprintf(stderr,
keir@18964 708 "[CPU%d] failed to malloc for scaling_available_frequencies\n",
keir@18964 709 cpuid);
keir@18964 710 ret = -ENOMEM;
keir@18964 711 goto out;
keir@18964 712 }
keir@18964 713 if (!(p_cpufreq->scaling_available_governors =
keir@18964 714 malloc(p_cpufreq->gov_num * CPUFREQ_NAME_LEN * sizeof(char))))
keir@18964 715 {
keir@18964 716 fprintf(stderr,
keir@18964 717 "[CPU%d] failed to malloc for scaling_available_governors\n",
keir@18964 718 cpuid);
keir@18964 719 ret = -ENOMEM;
keir@18964 720 goto out;
keir@18964 721 }
keir@18964 722
keir@21529 723 ret = xc_get_cpufreq_para(xc_handle, cpuid, p_cpufreq);
keir@18964 724 } while ( ret && errno == EAGAIN );
keir@18964 725
keir@18964 726 if ( ret == 0 )
keir@18964 727 print_cpufreq_para(cpuid, p_cpufreq);
keir@18964 728 else if ( errno == ENODEV )
keir@18964 729 {
keir@18964 730 ret = -ENODEV;
keir@18964 731 fprintf(stderr, "Xen cpufreq is not enabled!\n");
keir@18964 732 }
keir@18964 733 else
keir@18964 734 fprintf(stderr,
keir@18964 735 "[CPU%d] failed to get cpufreq parameter\n",
keir@18964 736 cpuid);
keir@18964 737
keir@18964 738 out:
keir@18964 739 free(p_cpufreq->scaling_available_governors);
keir@18964 740 free(p_cpufreq->scaling_available_frequencies);
keir@18964 741 free(p_cpufreq->affected_cpus);
keir@18964 742
keir@18964 743 return ret;
keir@18964 744 }
keir@18964 745
keir@19041 746 void cpufreq_para_func(int argc, char *argv[])
keir@18964 747 {
keir@19041 748 int cpuid = -1;
keir@19041 749
keir@19041 750 if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
keir@19041 751 cpuid = -1;
keir@19041 752
keir@19041 753 if ( cpuid >= max_cpu_nr )
keir@19041 754 cpuid = -1;
keir@19041 755
keir@19041 756 if ( cpuid < 0 )
keir@19041 757 {
keir@19041 758 /* show cpu freqency information on all cpus */
keir@19041 759 int i;
keir@19041 760 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 761 if ( show_cpufreq_para_by_cpuid(xc_handle, i) == -ENODEV )
keir@19041 762 break;
keir@19041 763 }
keir@19041 764 else
keir@21529 765 show_cpufreq_para_by_cpuid(xc_handle, cpuid);
keir@19041 766 }
keir@19041 767
keir@19041 768 void scaling_max_freq_func(int argc, char *argv[])
keir@19041 769 {
keir@19041 770 int cpuid = -1, freq = -1;
keir@19041 771
keir@19041 772 if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
keir@19041 773 sscanf(argv[0], "%d", &cpuid) != 1)) ||
keir@19041 774 (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
keir@19041 775 argc == 0 )
keir@19041 776 {
keir@19041 777 fprintf(stderr, "failed to set scaling max freq\n");
keir@19041 778 return ;
keir@19041 779 }
keir@18964 780
keir@18964 781 if ( cpuid < 0 )
keir@18964 782 {
keir@19041 783 int i;
keir@19041 784 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 785 if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MAX_FREQ, freq) )
keir@19041 786 fprintf(stderr, "[CPU%d] failed to set scaling max freq\n", i);
keir@18964 787 }
keir@18964 788 else
keir@19041 789 {
keir@21529 790 if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MAX_FREQ, freq) )
keir@19041 791 fprintf(stderr, "failed to set scaling max freq\n");
keir@19041 792 }
keir@18964 793 }
keir@18964 794
keir@19041 795 void scaling_min_freq_func(int argc, char *argv[])
keir@18964 796 {
keir@19041 797 int cpuid = -1, freq = -1;
keir@19041 798
keir@19041 799 if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
keir@19041 800 sscanf(argv[0], "%d", &cpuid) != 1) ) ||
keir@19041 801 (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
keir@19041 802 argc == 0 )
keir@19041 803 {
keir@19041 804 fprintf(stderr, "failed to set scaling min freq\n");
keir@19041 805 return ;
keir@19041 806 }
keir@18964 807
keir@18964 808 if ( cpuid < 0 )
keir@18964 809 {
keir@19041 810 int i;
keir@19041 811 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 812 if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MIN_FREQ, freq) )
keir@19041 813 fprintf(stderr, "[CPU%d] failed to set scaling min freq\n", i);
keir@18964 814 }
keir@19041 815 else
keir@18964 816 {
keir@21529 817 if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MIN_FREQ, freq) )
keir@19041 818 fprintf(stderr, "failed to set scaling min freq\n");
keir@18964 819 }
keir@18964 820 }
keir@18964 821
keir@19041 822 void scaling_speed_func(int argc, char *argv[])
keir@18964 823 {
keir@19041 824 int cpuid = -1, speed = -1;
keir@19041 825
keir@19041 826 if ( (argc >= 2 && (sscanf(argv[1], "%d", &speed) != 1 ||
keir@19041 827 sscanf(argv[0], "%d", &cpuid) != 1) ) ||
keir@19041 828 (argc == 1 && sscanf(argv[0], "%d", &speed) != 1 ) ||
keir@19041 829 argc == 0 )
keir@19041 830 {
keir@19041 831 fprintf(stderr, "failed to set scaling speed\n");
keir@19041 832 return ;
keir@19041 833 }
keir@18964 834
keir@18964 835 if ( cpuid < 0 )
keir@18964 836 {
keir@19041 837 int i;
keir@19041 838 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 839 if ( xc_set_cpufreq_para(xc_handle, i, SCALING_SETSPEED, speed) )
keir@19041 840 fprintf(stderr, "[CPU%d] failed to set scaling speed\n", i);
keir@18964 841 }
keir@19041 842 else
keir@18964 843 {
keir@21529 844 if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_SETSPEED, speed) )
keir@19041 845 fprintf(stderr, "failed to set scaling speed\n");
keir@18964 846 }
keir@18964 847 }
keir@18964 848
keir@19041 849 void scaling_sampling_rate_func(int argc, char *argv[])
keir@18964 850 {
keir@19041 851 int cpuid = -1, rate = -1;
keir@19041 852
keir@19041 853 if ( (argc >= 2 && (sscanf(argv[1], "%d", &rate) != 1 ||
keir@19041 854 sscanf(argv[0], "%d", &cpuid) != 1) ) ||
keir@19041 855 (argc == 1 && sscanf(argv[0], "%d", &rate) != 1 ) ||
keir@19041 856 argc == 0 )
keir@19041 857 {
keir@19041 858 fprintf(stderr, "failed to set scaling sampling rate\n");
keir@19041 859 return ;
keir@19041 860 }
keir@18964 861
keir@18964 862 if ( cpuid < 0 )
keir@18964 863 {
keir@19041 864 int i;
keir@19041 865 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 866 if ( xc_set_cpufreq_para(xc_handle, i, SAMPLING_RATE, rate) )
keir@19041 867 fprintf(stderr,
keir@19041 868 "[CPU%d] failed to set scaling sampling rate\n", i);
keir@18964 869 }
keir@19041 870 else
keir@18964 871 {
keir@21529 872 if ( xc_set_cpufreq_para(xc_handle, cpuid, SAMPLING_RATE, rate) )
keir@19041 873 fprintf(stderr, "failed to set scaling sampling rate\n");
keir@18964 874 }
keir@18964 875 }
keir@18964 876
keir@19041 877 void scaling_up_threshold_func(int argc, char *argv[])
keir@18964 878 {
keir@19041 879 int cpuid = -1, threshold = -1;
keir@19041 880
keir@19041 881 if ( (argc >= 2 && (sscanf(argv[1], "%d", &threshold) != 1 ||
keir@19041 882 sscanf(argv[0], "%d", &cpuid) != 1) ) ||
keir@19041 883 (argc == 1 && sscanf(argv[0], "%d", &threshold) != 1 ) ||
keir@19041 884 argc == 0 )
keir@19041 885 {
keir@19041 886 fprintf(stderr, "failed to set up scaling threshold\n");
keir@19041 887 return ;
keir@19041 888 }
keir@18964 889
keir@18964 890 if ( cpuid < 0 )
keir@18964 891 {
keir@19041 892 int i;
keir@19041 893 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 894 if ( xc_set_cpufreq_para(xc_handle, i, UP_THRESHOLD, threshold) )
keir@19041 895 fprintf(stderr,
keir@19041 896 "[CPU%d] failed to set up scaling threshold\n", i);
keir@18964 897 }
keir@19041 898 else
keir@18964 899 {
keir@21529 900 if ( xc_set_cpufreq_para(xc_handle, cpuid, UP_THRESHOLD, threshold) )
keir@19041 901 fprintf(stderr, "failed to set up scaling threshold\n");
keir@18964 902 }
keir@18964 903 }
keir@18964 904
keir@19041 905 void scaling_governor_func(int argc, char *argv[])
keir@18964 906 {
keir@19041 907 int cpuid = -1;
keir@19041 908 char *name = NULL;
keir@19041 909
keir@19041 910 if ( argc >= 2 )
keir@19041 911 {
keir@19041 912 name = strdup(argv[1]);
keir@19041 913 if ( name == NULL )
keir@19041 914 goto out;
keir@19041 915 if ( sscanf(argv[0], "%d", &cpuid) != 1 )
keir@19041 916 {
keir@19041 917 free(name);
keir@19041 918 goto out;
keir@19041 919 }
keir@19041 920 }
keir@19041 921 else if ( argc > 0 )
keir@19041 922 {
keir@19041 923 name = strdup(argv[0]);
keir@19041 924 if ( name == NULL )
keir@19041 925 goto out;
keir@19041 926 }
keir@19041 927 else
keir@19041 928 goto out;
keir@18964 929
keir@18964 930 if ( cpuid < 0 )
keir@18964 931 {
keir@19041 932 int i;
keir@19041 933 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 934 if ( xc_set_cpufreq_gov(xc_handle, i, name) )
keir@19041 935 fprintf(stderr, "[CPU%d] failed to set governor name\n", i);
keir@18964 936 }
keir@19041 937 else
keir@18964 938 {
keir@21529 939 if ( xc_set_cpufreq_gov(xc_handle, cpuid, name) )
keir@19041 940 fprintf(stderr, "failed to set governor name\n");
keir@18964 941 }
keir@18964 942
keir@19041 943 free(name);
keir@19041 944 return ;
keir@19041 945 out:
keir@19041 946 fprintf(stderr, "failed to set governor name\n");
keir@18964 947 }
keir@18964 948
keir@19393 949 void cpu_topology_func(int argc, char *argv[])
keir@19393 950 {
ian@22355 951 DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_core);
ian@22355 952 DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_socket);
ian@22355 953 DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_node);
keir@21200 954 xc_topologyinfo_t info = { 0 };
keir@21200 955 int i;
keir@19393 956
ian@22355 957 cpu_to_core = xc_hypercall_buffer_alloc(xc_handle, cpu_to_core, sizeof(*cpu_to_core) * MAX_NR_CPU);
ian@22355 958 cpu_to_socket = xc_hypercall_buffer_alloc(xc_handle, cpu_to_socket, sizeof(*cpu_to_socket) * MAX_NR_CPU);
ian@22355 959 cpu_to_node = xc_hypercall_buffer_alloc(xc_handle, cpu_to_node, sizeof(*cpu_to_node) * MAX_NR_CPU);
ian@22355 960
ian@22355 961 if ( cpu_to_core == NULL || cpu_to_socket == NULL || cpu_to_node == NULL )
ian@22355 962 {
ian@22355 963 fprintf(stderr, "failed to allocate hypercall buffers\n");
ian@22355 964 goto out;
ian@22355 965 }
ian@22355 966
ian@22358 967 set_xen_guest_handle(info.cpu_to_core, cpu_to_core);
ian@22358 968 set_xen_guest_handle(info.cpu_to_socket, cpu_to_socket);
ian@22358 969 set_xen_guest_handle(info.cpu_to_node, cpu_to_node);
keir@21200 970 info.max_cpu_index = MAX_NR_CPU-1;
keir@21200 971
keir@21529 972 if ( xc_topologyinfo(xc_handle, &info) )
keir@19393 973 {
keir@21200 974 printf("Can not get Xen CPU topology: %d\n", errno);
ian@22355 975 goto out;
keir@19393 976 }
keir@19393 977
keir@21200 978 if ( info.max_cpu_index > (MAX_NR_CPU-1) )
keir@21200 979 info.max_cpu_index = MAX_NR_CPU-1;
keir@21200 980
keir@21200 981 printf("CPU\tcore\tsocket\tnode\n");
Ian@21838 982 for ( i = 0; i <= info.max_cpu_index; i++ )
keir@21200 983 {
keir@21200 984 if ( cpu_to_core[i] == INVALID_TOPOLOGY_ID )
keir@21200 985 continue;
keir@21200 986 printf("CPU%d\t %d\t %d\t %d\n",
keir@21200 987 i, cpu_to_core[i], cpu_to_socket[i], cpu_to_node[i]);
keir@21200 988 }
ian@22355 989 out:
ian@22355 990 xc_hypercall_buffer_free(xc_handle, cpu_to_core);
ian@22355 991 xc_hypercall_buffer_free(xc_handle, cpu_to_socket);
ian@22355 992 xc_hypercall_buffer_free(xc_handle, cpu_to_node);
keir@19393 993 }
keir@19393 994
keir@19450 995 void set_sched_smt_func(int argc, char *argv[])
keir@19450 996 {
keir@19450 997 int value, rc;
keir@19450 998
keir@19450 999 if (argc != 1){
keir@19450 1000 show_help();
keir@19450 1001 exit(-1);
keir@19450 1002 }
keir@19450 1003
keir@19450 1004 if ( !strncmp(argv[0], "disable", sizeof("disable")) )
keir@19450 1005 {
keir@19450 1006 value = 0;
keir@19450 1007 }
keir@19450 1008 else if ( !strncmp(argv[0], "enable", sizeof("enable")) )
keir@19450 1009 {
keir@19450 1010 value = 1;
keir@19450 1011 }
keir@19450 1012 else
keir@19450 1013 {
keir@19450 1014 show_help();
keir@19450 1015 exit(-1);
keir@19450 1016 }
keir@19450 1017
keir@21529 1018 rc = xc_set_sched_opt_smt(xc_handle, value);
keir@19450 1019 printf("%s sched_smt_power_savings %s\n", argv[0],
keir@19478 1020 rc? "failed":"succeeded" );
keir@19478 1021
keir@19478 1022 return;
keir@19478 1023 }
keir@19478 1024
keir@19540 1025 void set_vcpu_migration_delay_func(int argc, char *argv[])
keir@19540 1026 {
keir@19540 1027 int value;
keir@19540 1028 int rc;
keir@19540 1029
keir@19540 1030 if (argc != 1){
keir@19540 1031 show_help();
keir@19540 1032 exit(-1);
keir@19540 1033 }
keir@19540 1034
keir@19540 1035 value = atoi(argv[0]);
keir@19540 1036
keir@19540 1037 if (value < 0)
keir@19540 1038 {
keir@19540 1039 printf("Please try non-negative vcpu migration delay\n");
keir@19540 1040 exit(-1);
keir@19540 1041 }
keir@19540 1042
keir@21529 1043 rc = xc_set_vcpu_migration_delay(xc_handle, value);
keir@19540 1044 printf("%s to set vcpu migration delay to %d us\n",
keir@19540 1045 rc? "Fail":"Succeed", value );
keir@19540 1046
keir@19540 1047 return;
keir@19540 1048 }
keir@19540 1049
keir@19540 1050 void get_vcpu_migration_delay_func(int argc, char *argv[])
keir@19540 1051 {
keir@19540 1052 uint32_t value;
keir@19540 1053 int rc;
keir@19540 1054
keir@19540 1055 if (argc != 0){
keir@19540 1056 show_help();
keir@19540 1057 exit(-1);
keir@19540 1058 }
keir@19540 1059
keir@21529 1060 rc = xc_get_vcpu_migration_delay(xc_handle, &value);
keir@19540 1061 if (!rc)
keir@19540 1062 {
keir@19540 1063 printf("Schduler vcpu migration delay is %d us\n", value);
keir@19540 1064 }
keir@19540 1065 else
keir@19540 1066 {
keir@19540 1067 printf("Failed to get scheduler vcpu migration delay, errno=%d\n", errno);
keir@19540 1068 }
keir@19540 1069
keir@19540 1070 return;
keir@19540 1071 }
keir@19540 1072
keir@19478 1073 void set_max_cstate_func(int argc, char *argv[])
keir@19478 1074 {
keir@19478 1075 int value, rc;
keir@19478 1076
keir@19478 1077 if ( argc != 1 || sscanf(argv[0], "%d", &value) != 1 || value < 0 )
keir@19478 1078 {
keir@19478 1079 show_help();
keir@19478 1080 exit(-1);
keir@19478 1081 }
keir@19478 1082
keir@21529 1083 rc = xc_set_cpuidle_max_cstate(xc_handle, (uint32_t)value);
keir@19478 1084 printf("set max_cstate to C%d %s\n", value,
keir@19478 1085 rc? "failed":"succeeded" );
keir@19450 1086
keir@19450 1087 return;
keir@19450 1088 }
keir@19450 1089
keir@20954 1090 void enable_turbo_mode(int argc, char *argv[])
keir@20954 1091 {
keir@20954 1092 int cpuid = -1;
keir@20954 1093
keir@20954 1094 if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
keir@20954 1095 cpuid = -1;
keir@20954 1096
keir@20954 1097 if ( cpuid >= max_cpu_nr )
keir@20954 1098 cpuid = -1;
keir@20954 1099
keir@20954 1100 if ( cpuid < 0 )
keir@20954 1101 {
keir@20954 1102 /* enable turbo modes on all cpus,
keir@20954 1103 * only make effects on dbs governor */
keir@20954 1104 int i;
keir@20954 1105 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 1106 xc_enable_turbo(xc_handle, i);
keir@20954 1107 }
keir@20954 1108 else
keir@21529 1109 xc_enable_turbo(xc_handle, cpuid);
keir@20954 1110 }
keir@20954 1111
keir@20954 1112 void disable_turbo_mode(int argc, char *argv[])
keir@20954 1113 {
keir@20954 1114 int cpuid = -1;
keir@20954 1115
keir@20954 1116 if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
keir@20954 1117 cpuid = -1;
keir@20954 1118
keir@20954 1119 if ( cpuid >= max_cpu_nr )
keir@20954 1120 cpuid = -1;
keir@20954 1121
keir@20954 1122 if ( cpuid < 0 )
keir@20954 1123 {
keir@20954 1124 /* disable turbo modes on all cpus,
keir@20954 1125 * only make effects on dbs governor */
keir@20954 1126 int i;
keir@20954 1127 for ( i = 0; i < max_cpu_nr; i++ )
keir@21529 1128 xc_disable_turbo(xc_handle, i);
keir@20954 1129 }
keir@20954 1130 else
keir@21529 1131 xc_disable_turbo(xc_handle, cpuid);
keir@20954 1132 }
keir@20954 1133
keir@18964 1134 struct {
keir@18964 1135 const char *name;
keir@19041 1136 void (*function)(int argc, char *argv[]);
keir@18964 1137 } main_options[] = {
keir@18964 1138 { "help", help_func },
keir@19041 1139 { "get-cpuidle-states", cxstat_func },
keir@19041 1140 { "get-cpufreq-states", pxstat_func },
keir@19041 1141 { "start", start_gather_func },
keir@18964 1142 { "get-cpufreq-para", cpufreq_para_func },
keir@18964 1143 { "set-scaling-maxfreq", scaling_max_freq_func },
keir@18964 1144 { "set-scaling-minfreq", scaling_min_freq_func },
keir@19041 1145 { "set-scaling-governor", scaling_governor_func },
keir@18964 1146 { "set-scaling-speed", scaling_speed_func },
keir@18964 1147 { "set-sampling-rate", scaling_sampling_rate_func },
keir@18964 1148 { "set-up-threshold", scaling_up_threshold_func },
keir@19393 1149 { "get-cpu-topology", cpu_topology_func},
keir@19450 1150 { "set-sched-smt", set_sched_smt_func},
keir@19540 1151 { "get-vcpu-migration-delay", get_vcpu_migration_delay_func},
keir@19540 1152 { "set-vcpu-migration-delay", set_vcpu_migration_delay_func},
keir@19478 1153 { "set-max-cstate", set_max_cstate_func},
keir@20954 1154 { "enable-turbo-mode", enable_turbo_mode },
keir@20954 1155 { "disable-turbo-mode", disable_turbo_mode },
keir@18964 1156 };
keir@18964 1157
keir@18964 1158 int main(int argc, char *argv[])
keir@18964 1159 {
keir@19041 1160 int i, ret = 0;
keir@19041 1161 xc_physinfo_t physinfo = { 0 };
keir@18964 1162 int nr_matches = 0;
keir@18964 1163 int matches_main_options[ARRAY_SIZE(main_options)];
keir@18964 1164
keir@18964 1165 if ( argc < 2 )
keir@18964 1166 {
keir@18964 1167 show_help();
keir@19041 1168 return 0;
keir@18581 1169 }
keir@18581 1170
keir@21529 1171 xc_handle = xc_interface_open(0,0,0);
keir@21529 1172 if ( !xc_handle )
keir@18581 1173 {
keir@18581 1174 fprintf(stderr, "failed to get the handler\n");
keir@19041 1175 return 0;
keir@18581 1176 }
keir@18581 1177
keir@21529 1178 ret = xc_physinfo(xc_handle, &physinfo);
keir@19041 1179 if ( ret )
keir@19041 1180 {
keir@19041 1181 fprintf(stderr, "failed to get the processor information\n");
keir@21529 1182 xc_interface_close(xc_handle);
keir@19041 1183 return 0;
keir@19041 1184 }
keir@19041 1185 max_cpu_nr = physinfo.nr_cpus;
keir@19041 1186
keir@19041 1187 /* calculate how many options match with user's input */
keir@18964 1188 for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
keir@18964 1189 if ( !strncmp(main_options[i].name, argv[1], strlen(argv[1])) )
keir@18964 1190 matches_main_options[nr_matches++] = i;
keir@18581 1191
keir@18964 1192 if ( nr_matches > 1 )
keir@18581 1193 {
keir@18964 1194 fprintf(stderr, "Ambigious options: ");
keir@18964 1195 for ( i = 0; i < nr_matches; i++ )
keir@18964 1196 fprintf(stderr, " %s", main_options[matches_main_options[i]].name);
keir@18964 1197 fprintf(stderr, "\n");
keir@18964 1198 }
keir@18964 1199 else if ( nr_matches == 1 )
keir@19041 1200 /* dispatch to the corresponding function handler */
keir@19041 1201 main_options[matches_main_options[0]].function(argc - 2, argv + 2);
keir@18964 1202 else
keir@18964 1203 show_help();
keir@18581 1204
keir@21529 1205 xc_interface_close(xc_handle);
keir@19041 1206 return 0;
keir@18581 1207 }
keir@18581 1208