#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
+#include <signal.h>
#include <xenctrl.h>
#include <inttypes.h>
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+static int xc_fd;
+static int max_cpu_nr;
+
/* help message */
void show_help(void)
{
fprintf(stderr,
- "Usage:\n"
- " xenpm get-cpuidle-states [cpuid]: list cpu idle information on CPU cpuid or all CPUs.\n"
- " xenpm get-cpufreq-states [cpuid]: list cpu frequency information on CPU cpuid or all CPUs.\n"
- " xenpm get-cpufreq-para [cpuid]: list cpu frequency information on CPU cpuid or all CPUs.\n"
- " xenpm set-scaling-maxfreq <cpuid> <HZ>: set max cpu frequency <HZ> on CPU <cpuid>.\n"
- " xenpm set-scaling-minfreq <cpuid> <HZ>: set min cpu frequency <HZ> on CPU <cpuid>.\n"
- " xenpm set-scaling-governor <cpuid> <name>: set scaling governor on CPU <cpuid>.\n"
- " xenpm set-scaling-speed <cpuid> <num>: set scaling speed on CPU <cpuid>.\n"
- " xenpm set-sampling-rate <cpuid> <num>: set sampling rate on CPU <cpuid>.\n"
- " xenpm set-up-threshold <cpuid> <num>: set up threshold on CPU <cpuid>.\n");
+ "xen power management control tool\n\n"
+ "usage: xenpm <command> [args]\n\n"
+ "xenpm command list:\n\n"
+ " get-cpuidle-states [cpuid] list cpu idle info of CPU <cpuid> or all\n"
+ " get-cpufreq-states [cpuid] list cpu freq info of CPU <cpuid> or all\n"
+ " get-cpufreq-para [cpuid] list cpu freq parameter of CPU <cpuid> or all\n"
+ " set-scaling-maxfreq [cpuid] <HZ> set max cpu frequency <HZ> on CPU <cpuid>\n"
+ " or all CPUs\n"
+ " set-scaling-minfreq [cpuid] <HZ> set min cpu frequency <HZ> on CPU <cpuid>\n"
+ " or all CPUs\n"
+ " set-scaling-speed [cpuid] <num> set scaling speed on CPU <cpuid> or all\n"
+ " it is used in userspace governor.\n"
+ " set-scaling-governor [cpuid] <gov> set scaling governor on CPU <cpuid> or all\n"
+ " as userspace/performance/powersave/ondemand\n"
+ " set-sampling-rate [cpuid] <num> set sampling rate on CPU <cpuid> or all\n"
+ " it is used in ondemand governor.\n"
+ " set-up-threshold [cpuid] <num> set up threshold on CPU <cpuid> or all\n"
+ " it is used in ondemand governor.\n"
+ " start start collect Cx/Px statistics,\n"
+ " output after CTRL-C or SIGINT.\n"
+ );
}
-
/* wrapper function */
-int help_func(int xc_fd, int cpuid, uint32_t value)
+void help_func(int argc, char *argv[])
{
show_help();
- return 0;
+}
+
+static void print_cxstat(int cpuid, struct xc_cx_stat *cxstat)
+{
+ int i;
+
+ printf("cpu id : %d\n", cpuid);
+ printf("total C-states : %d\n", cxstat->nr);
+ printf("idle time(ms) : %"PRIu64"\n",
+ cxstat->idle_time/1000000UL);
+ for ( i = 0; i < cxstat->nr; i++ )
+ {
+ printf("C%d : transition [%020"PRIu64"]\n",
+ i, cxstat->triggers[i]);
+ printf(" residency [%020"PRIu64" ms]\n",
+ cxstat->residencies[i]/1000000UL);
+ }
+ printf("\n");
}
/* show cpu idle information on CPU cpuid */
-static int show_cx_cpuid(int xc_fd, int cpuid)
+static int get_cxstat_by_cpuid(int xc_fd, int cpuid, struct xc_cx_stat *cxstat)
{
- int i, ret = 0;
+ int ret = 0;
int max_cx_num = 0;
- struct xc_cx_stat cxstatinfo, *cxstat = &cxstatinfo;
ret = xc_pm_get_max_cx(xc_fd, cpuid, &max_cx_num);
if ( ret )
- {
- if ( errno == ENODEV )
- {
- fprintf(stderr, "Xen cpuidle is not enabled!\n");
- return -ENODEV;
- }
- else
- {
- fprintf(stderr, "[CPU%d] failed to get max C-state\n", cpuid);
- return -EINVAL;
- }
- }
+ return errno;
+
+ if ( !cxstat )
+ return -EINVAL;
cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t));
if ( !cxstat->triggers )
- {
- fprintf(stderr, "[CPU%d] failed to malloc for C-states triggers\n", cpuid);
return -ENOMEM;
- }
cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t));
if ( !cxstat->residencies )
{
- fprintf(stderr, "[CPU%d] failed to malloc for C-states residencies\n", cpuid);
free(cxstat->triggers);
return -ENOMEM;
}
ret = xc_pm_get_cxstat(xc_fd, cpuid, cxstat);
if( ret )
{
- fprintf(stderr, "[CPU%d] failed to get C-states statistics "
- "information\n", cpuid);
+ int temp = errno;
free(cxstat->triggers);
free(cxstat->residencies);
- return -EINVAL;
+ cxstat->triggers = NULL;
+ cxstat->residencies = NULL;
+ return temp;
}
- printf("cpu id : %d\n", cpuid);
- printf("total C-states : %d\n", cxstat->nr);
- printf("idle time(ms) : %"PRIu64"\n",
- cxstat->idle_time/1000000UL);
- for ( i = 0; i < cxstat->nr; i++ )
- {
- printf("C%d : transition [%020"PRIu64"]\n",
- i, cxstat->triggers[i]);
- printf(" residency [%020"PRIu64" ms]\n",
- cxstat->residencies[i]/1000000UL);
- }
+ return 0;
+}
- free(cxstat->triggers);
- free(cxstat->residencies);
+static int show_cxstat_by_cpuid(int xc_fd, int cpuid)
+{
+ int ret = 0;
+ struct xc_cx_stat cxstatinfo;
- printf("\n");
+ ret = get_cxstat_by_cpuid(xc_fd, cpuid, &cxstatinfo);
+ if ( ret )
+ return ret;
+
+ print_cxstat(cpuid, &cxstatinfo);
+
+ free(cxstatinfo.triggers);
+ free(cxstatinfo.residencies);
return 0;
}
-int cxstates_func(int xc_fd, int cpuid, uint32_t value)
+void cxstat_func(int argc, char *argv[])
{
- int ret = 0;
- xc_physinfo_t physinfo = { 0 };
+ int cpuid = -1;
+
+ if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
+ cpuid = -1;
+
+ if ( cpuid >= max_cpu_nr )
+ cpuid = -1;
if ( cpuid < 0 )
{
- /* show cxstates on all cpu */
- ret = xc_physinfo(xc_fd, &physinfo);
- if ( ret )
- {
- fprintf(stderr, "failed to get the processor information\n");
- }
- else
- {
- int i;
- for ( i = 0; i < physinfo.nr_cpus; i++ )
- {
- if ( (ret = show_cx_cpuid(xc_fd, i)) == -ENODEV )
- break;
- }
- }
+ /* show cxstates on all cpus */
+ int i;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( show_cxstat_by_cpuid(xc_fd, i) == -ENODEV )
+ break;
}
else
- ret = show_cx_cpuid(xc_fd, cpuid);
+ show_cxstat_by_cpuid(xc_fd, cpuid);
+}
- return ret;
+static void print_pxstat(int cpuid, struct xc_px_stat *pxstat)
+{
+ int i;
+
+ printf("cpu id : %d\n", cpuid);
+ printf("total P-states : %d\n", pxstat->total);
+ printf("usable P-states : %d\n", pxstat->usable);
+ printf("current frequency : %"PRIu64" MHz\n",
+ pxstat->pt[pxstat->cur].freq);
+ for ( i = 0; i < pxstat->total; i++ )
+ {
+ if ( pxstat->cur == i )
+ printf("*P%d", i);
+ else
+ printf("P%d ", i);
+ printf(" : freq [%04"PRIu64" MHz]\n",
+ pxstat->pt[i].freq);
+ printf(" transition [%020"PRIu64"]\n",
+ pxstat->pt[i].count);
+ printf(" residency [%020"PRIu64" ms]\n",
+ pxstat->pt[i].residency/1000000UL);
+ }
+ printf("\n");
}
/* show cpu frequency information on CPU cpuid */
-static int show_px_cpuid(int xc_fd, int cpuid)
+static int get_pxstat_by_cpuid(int xc_fd, int cpuid, struct xc_px_stat *pxstat)
{
- int i, ret = 0;
+ int ret = 0;
int max_px_num = 0;
- struct xc_px_stat pxstatinfo, *pxstat = &pxstatinfo;
ret = xc_pm_get_max_px(xc_fd, cpuid, &max_px_num);
if ( ret )
- {
- if ( errno == ENODEV )
- {
- printf("Xen cpufreq is not enabled!\n");
- return -ENODEV;
- }
- else
- {
- fprintf(stderr, "[CPU%d] failed to get max P-state\n", cpuid);
- return -EINVAL;
- }
- }
+ return errno;
+
+ if ( !pxstat)
+ return -EINVAL;
pxstat->trans_pt = malloc(max_px_num * max_px_num *
sizeof(uint64_t));
if ( !pxstat->trans_pt )
- {
- fprintf(stderr, "[CPU%d] failed to malloc for P-states transition table\n", cpuid);
return -ENOMEM;
- }
pxstat->pt = malloc(max_px_num * sizeof(struct xc_px_val));
if ( !pxstat->pt )
{
- fprintf(stderr, "[CPU%d] failed to malloc for P-states table\n", cpuid);
free(pxstat->trans_pt);
return -ENOMEM;
}
ret = xc_pm_get_pxstat(xc_fd, cpuid, pxstat);
if( ret )
{
- fprintf(stderr, "[CPU%d] failed to get P-states statistics information\n", cpuid);
+ int temp = errno;
free(pxstat->trans_pt);
free(pxstat->pt);
- return -ENOMEM;
+ pxstat->trans_pt = NULL;
+ pxstat->pt = NULL;
+ return temp;
}
- printf("cpu id : %d\n", cpuid);
- printf("total P-states : %d\n", pxstat->total);
- printf("usable P-states : %d\n", pxstat->usable);
- printf("current frequency : %"PRIu64" MHz\n",
- pxstat->pt[pxstat->cur].freq);
- for ( i = 0; i < pxstat->total; i++ )
- {
- if ( pxstat->cur == i )
- printf("*P%d", i);
- else
- printf("P%d ", i);
- printf(" : freq [%04"PRIu64" MHz]\n",
- pxstat->pt[i].freq);
- printf(" transition [%020"PRIu64"]\n",
- pxstat->pt[i].count);
- printf(" residency [%020"PRIu64" ms]\n",
- pxstat->pt[i].residency/1000000UL);
- }
+ return 0;
+}
- free(pxstat->trans_pt);
- free(pxstat->pt);
+static int show_pxstat_by_cpuid(int xc_fd, int cpuid)
+{
+ int ret = 0;
+ struct xc_px_stat pxstatinfo;
- printf("\n");
+ ret = get_pxstat_by_cpuid(xc_fd, cpuid, &pxstatinfo);
+ if ( ret )
+ return ret;
+
+ print_pxstat(cpuid, &pxstatinfo);
+
+ free(pxstatinfo.trans_pt);
+ free(pxstatinfo.pt);
return 0;
}
-int pxstates_func(int xc_fd, int cpuid, uint32_t value)
+void pxstat_func(int argc, char *argv[])
{
- int ret = 0;
- xc_physinfo_t physinfo = { 0 };
+ int cpuid = -1;
+
+ if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
+ cpuid = -1;
+
+ if ( cpuid >= max_cpu_nr )
+ cpuid = -1;
if ( cpuid < 0 )
{
- ret = xc_physinfo(xc_fd, &physinfo);
- if ( ret )
+ /* show pxstates on all cpus */
+ int i;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( show_pxstat_by_cpuid(xc_fd, i) == -ENODEV )
+ break;
+ }
+ else
+ show_pxstat_by_cpuid(xc_fd, cpuid);
+}
+
+static uint64_t usec_start, usec_end;
+static struct xc_cx_stat *cxstat, *cxstat_start, *cxstat_end;
+static struct xc_px_stat *pxstat, *pxstat_start, *pxstat_end;
+static uint64_t *sum, *sum_cx, *sum_px;
+
+static void signal_int_handler(int signo)
+{
+ int i, j;
+ struct timeval tv;
+ int cx_cap = 0, px_cap = 0;
+
+ if ( gettimeofday(&tv, NULL) == -1 )
+ {
+ fprintf(stderr, "failed to get timeofday\n");
+ return ;
+ }
+ usec_end = tv.tv_sec * 1000000UL + tv.tv_usec;
+
+ if ( get_cxstat_by_cpuid(xc_fd, 0, NULL) != -ENODEV )
+ {
+ cx_cap = 1;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( !get_cxstat_by_cpuid(xc_fd, i, &cxstat_end[i]) )
+ for ( j = 0; j < cxstat_end[i].nr; j++ )
+ sum_cx[i] += cxstat_end[i].residencies[j] -
+ cxstat_start[i].residencies[j];
+ }
+
+ if ( get_pxstat_by_cpuid(xc_fd, 0, NULL) != -ENODEV )
+ {
+ px_cap = 1;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( !get_pxstat_by_cpuid(xc_fd, i , &pxstat_end[i]) )
+ for ( j = 0; j < pxstat_end[i].total; j++ )
+ sum_px[i] += pxstat_end[i].pt[j].residency -
+ pxstat_start[i].pt[j].residency;
+ }
+
+ printf("Elapsed time (ms): %"PRIu64"\n", (usec_end - usec_start) / 1000UL);
+ for ( i = 0; i < max_cpu_nr; i++ )
+ {
+ uint64_t temp;
+ printf("CPU%d:\n\tresidency\tpercentage\n", i);
+ if ( cx_cap )
{
- fprintf(stderr, "failed to get the processor information\n");
+ for ( j = 0; j < cxstat_end[i].nr; j++ )
+ {
+ if ( sum_cx[i] > 0 )
+ {
+ temp = cxstat_end[i].residencies[j] -
+ cxstat_start[i].residencies[j];
+ printf(" C%d\t%"PRIu64" ms\t%.2f%%\n", j,
+ temp / 1000000UL, 100UL * temp / (double)sum_cx[i]);
+ }
+ }
}
- else
+ if ( px_cap )
{
- int i;
- for ( i = 0; i < physinfo.nr_cpus; i++ )
+ for ( j = 0; j < pxstat_end[i].total; j++ )
{
- if ( (ret = show_px_cpuid(xc_fd, i)) == -ENODEV )
- break;
+ if ( sum_px[i] > 0 )
+ {
+ temp = pxstat_end[i].pt[j].residency -
+ pxstat_start[i].pt[j].residency;
+ printf(" P%d\t%"PRIu64" ms\t%.2f%%\n", j,
+ temp / 1000000UL, 100UL * temp / (double)sum_px[i]);
+ }
}
}
+ printf("\n");
}
- else
- ret = show_px_cpuid(xc_fd, cpuid);
- return ret;
+ /* some clean up and then exits */
+ for ( i = 0; i < 2 * max_cpu_nr; i++ )
+ {
+ free(cxstat[i].triggers);
+ free(cxstat[i].residencies);
+ free(pxstat[i].trans_pt);
+ free(pxstat[i].pt);
+ }
+ free(cxstat);
+ free(pxstat);
+ free(sum);
+ xc_interface_close(xc_fd);
+ exit(0);
+}
+
+void start_gather_func(int argc, char *argv[])
+{
+ int i;
+ struct timeval tv;
+
+ if ( gettimeofday(&tv, NULL) == -1 )
+ {
+ fprintf(stderr, "failed to get timeofday\n");
+ return ;
+ }
+ usec_start = tv.tv_sec * 1000000UL + tv.tv_usec;
+
+ sum = malloc(sizeof(uint64_t) * 2 * max_cpu_nr);
+ if ( sum == NULL )
+ return ;
+ cxstat = malloc(sizeof(struct xc_cx_stat) * 2 * max_cpu_nr);
+ if ( cxstat == NULL )
+ {
+ free(sum);
+ return ;
+ }
+ pxstat = malloc(sizeof(struct xc_px_stat) * 2 * max_cpu_nr);
+ if ( pxstat == NULL )
+ {
+ free(sum);
+ free(cxstat);
+ return ;
+ }
+ memset(sum, 0, sizeof(uint64_t) * 2 * max_cpu_nr);
+ memset(cxstat, 0, sizeof(struct xc_cx_stat) * 2 * max_cpu_nr);
+ memset(pxstat, 0, sizeof(struct xc_px_stat) * 2 * max_cpu_nr);
+ sum_cx = sum;
+ sum_px = sum + max_cpu_nr;
+ cxstat_start = cxstat;
+ cxstat_end = cxstat + max_cpu_nr;
+ pxstat_start = pxstat;
+ pxstat_end = pxstat + max_cpu_nr;
+
+ if ( get_cxstat_by_cpuid(xc_fd, 0, NULL) == -ENODEV &&
+ get_pxstat_by_cpuid(xc_fd, 0, NULL) == -ENODEV )
+ {
+ fprintf(stderr, "Xen cpu idle and frequency is disabled!\n");
+ return ;
+ }
+
+ for ( i = 0; i < max_cpu_nr; i++ )
+ {
+ get_cxstat_by_cpuid(xc_fd, i, &cxstat_start[i]);
+ get_pxstat_by_cpuid(xc_fd, i, &pxstat_start[i]);
+ }
+
+ if (signal(SIGINT, signal_int_handler) == SIG_ERR)
+ {
+ fprintf(stderr, "failed to set signal int handler\n");
+ free(sum);
+ free(pxstat);
+ free(cxstat);
+ return ;
+ }
+
+ pause();
}
/* print out parameters about cpu frequency */
printf("scaling_avail_freq :");
for ( i = 0; i < p_cpufreq->freq_num; i++ )
- if ( p_cpufreq->scaling_available_frequencies[i] == p_cpufreq->scaling_cur_freq )
+ if ( p_cpufreq->scaling_available_frequencies[i] ==
+ p_cpufreq->scaling_cur_freq )
printf(" *%d", p_cpufreq->scaling_available_frequencies[i]);
else
printf(" %d", p_cpufreq->scaling_available_frequencies[i]);
}
/* show cpu frequency parameters information on CPU cpuid */
-static int show_cpufreq_para_cpuid(int xc_fd, int cpuid)
+static int show_cpufreq_para_by_cpuid(int xc_fd, int cpuid)
{
int ret = 0;
struct xc_get_cpufreq_para cpufreq_para, *p_cpufreq = &cpufreq_para;
return ret;
}
-int cpufreq_para_func(int xc_fd, int cpuid, uint32_t value)
+void cpufreq_para_func(int argc, char *argv[])
{
- int ret = 0;
- xc_physinfo_t physinfo = { 0 };
+ int cpuid = -1;
+
+ if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
+ cpuid = -1;
+
+ if ( cpuid >= max_cpu_nr )
+ cpuid = -1;
if ( cpuid < 0 )
{
- ret = xc_physinfo(xc_fd, &physinfo);
- if ( ret )
- {
- fprintf(stderr, "failed to get the processor information\n");
- }
- else
- {
- int i;
- for ( i = 0; i < physinfo.nr_cpus; i++ )
- {
- if ( (ret = show_cpufreq_para_cpuid(xc_fd, i)) == -ENODEV )
- break;
- }
- }
+ /* show cpu freqency information on all cpus */
+ int i;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( show_cpufreq_para_by_cpuid(xc_fd, i) == -ENODEV )
+ break;
}
else
- ret = show_cpufreq_para_cpuid(xc_fd, cpuid);
-
- return ret;
+ show_cpufreq_para_by_cpuid(xc_fd, cpuid);
}
-int scaling_max_freq_func(int xc_fd, int cpuid, uint32_t value)
+void scaling_max_freq_func(int argc, char *argv[])
{
- int ret = 0;
+ int cpuid = -1, freq = -1;
- if ( cpuid < 0 )
+ if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
+ sscanf(argv[0], "%d", &cpuid) != 1)) ||
+ (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
+ argc == 0 )
{
- show_help();
- return -EINVAL;
+ fprintf(stderr, "failed to set scaling max freq\n");
+ return ;
}
- ret = xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MAX_FREQ, value);
- if ( ret )
+ if ( cpuid < 0 )
{
- fprintf(stderr, "[CPU%d] failed to set scaling max freq\n", cpuid);
+ int i;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( xc_set_cpufreq_para(xc_fd, i, SCALING_MAX_FREQ, freq) )
+ fprintf(stderr, "[CPU%d] failed to set scaling max freq\n", i);
+ }
+ else
+ {
+ if ( xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MAX_FREQ, freq) )
+ fprintf(stderr, "failed to set scaling max freq\n");
}
-
- return ret;
}
-int scaling_min_freq_func(int xc_fd, int cpuid, uint32_t value)
+void scaling_min_freq_func(int argc, char *argv[])
{
- int ret;
+ int cpuid = -1, freq = -1;
- if ( cpuid < 0 )
+ if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
+ sscanf(argv[0], "%d", &cpuid) != 1) ) ||
+ (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
+ argc == 0 )
{
- show_help();
- return -EINVAL;
+ fprintf(stderr, "failed to set scaling min freq\n");
+ return ;
}
- ret = xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MIN_FREQ, value);
- if ( ret )
+ if ( cpuid < 0 )
{
- fprintf(stderr, "[CPU%d] failed to set scaling min freq\n", cpuid);
+ int i;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( xc_set_cpufreq_para(xc_fd, i, SCALING_MIN_FREQ, freq) )
+ fprintf(stderr, "[CPU%d] failed to set scaling min freq\n", i);
+ }
+ else
+ {
+ if ( xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MIN_FREQ, freq) )
+ fprintf(stderr, "failed to set scaling min freq\n");
}
-
- return ret;
}
-int scaling_speed_func(int xc_fd, int cpuid, uint32_t value)
+void scaling_speed_func(int argc, char *argv[])
{
- int ret;
+ int cpuid = -1, speed = -1;
- if ( cpuid < 0 )
+ if ( (argc >= 2 && (sscanf(argv[1], "%d", &speed) != 1 ||
+ sscanf(argv[0], "%d", &cpuid) != 1) ) ||
+ (argc == 1 && sscanf(argv[0], "%d", &speed) != 1 ) ||
+ argc == 0 )
{
- show_help();
- return -EINVAL;
+ fprintf(stderr, "failed to set scaling speed\n");
+ return ;
}
- ret = xc_set_cpufreq_para(xc_fd, cpuid, SCALING_SETSPEED, value);
- if ( ret )
+ if ( cpuid < 0 )
{
- fprintf(stderr, "[CPU%d] failed to set scaling speed\n", cpuid);
+ int i;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( xc_set_cpufreq_para(xc_fd, i, SCALING_SETSPEED, speed) )
+ fprintf(stderr, "[CPU%d] failed to set scaling speed\n", i);
+ }
+ else
+ {
+ if ( xc_set_cpufreq_para(xc_fd, cpuid, SCALING_SETSPEED, speed) )
+ fprintf(stderr, "failed to set scaling speed\n");
}
-
- return ret;
}
-int scaling_sampling_rate_func(int xc_fd, int cpuid, uint32_t value)
+void scaling_sampling_rate_func(int argc, char *argv[])
{
- int ret;
+ int cpuid = -1, rate = -1;
- if ( cpuid < 0 )
+ if ( (argc >= 2 && (sscanf(argv[1], "%d", &rate) != 1 ||
+ sscanf(argv[0], "%d", &cpuid) != 1) ) ||
+ (argc == 1 && sscanf(argv[0], "%d", &rate) != 1 ) ||
+ argc == 0 )
{
- show_help();
- return -EINVAL;
+ fprintf(stderr, "failed to set scaling sampling rate\n");
+ return ;
}
- ret = xc_set_cpufreq_para(xc_fd, cpuid, SAMPLING_RATE, value);
- if ( ret )
+ if ( cpuid < 0 )
{
- fprintf(stderr, "[CPU%d] failed to set scaling sampling rate\n", cpuid);
+ int i;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( xc_set_cpufreq_para(xc_fd, i, SAMPLING_RATE, rate) )
+ fprintf(stderr,
+ "[CPU%d] failed to set scaling sampling rate\n", i);
+ }
+ else
+ {
+ if ( xc_set_cpufreq_para(xc_fd, cpuid, SAMPLING_RATE, rate) )
+ fprintf(stderr, "failed to set scaling sampling rate\n");
}
-
- return ret;
}
-int scaling_up_threshold_func(int xc_fd, int cpuid, uint32_t value)
+void scaling_up_threshold_func(int argc, char *argv[])
{
- int ret;
+ int cpuid = -1, threshold = -1;
- if ( cpuid < 0 )
+ if ( (argc >= 2 && (sscanf(argv[1], "%d", &threshold) != 1 ||
+ sscanf(argv[0], "%d", &cpuid) != 1) ) ||
+ (argc == 1 && sscanf(argv[0], "%d", &threshold) != 1 ) ||
+ argc == 0 )
{
- show_help();
- return -EINVAL;
+ fprintf(stderr, "failed to set up scaling threshold\n");
+ return ;
}
- ret = xc_set_cpufreq_para(xc_fd, cpuid, UP_THRESHOLD, value);
- if ( ret )
+ if ( cpuid < 0 )
{
- fprintf(stderr, "[CPU%d] failed to set scaling threshold\n", cpuid);
+ int i;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( xc_set_cpufreq_para(xc_fd, i, UP_THRESHOLD, threshold) )
+ fprintf(stderr,
+ "[CPU%d] failed to set up scaling threshold\n", i);
+ }
+ else
+ {
+ if ( xc_set_cpufreq_para(xc_fd, cpuid, UP_THRESHOLD, threshold) )
+ fprintf(stderr, "failed to set up scaling threshold\n");
}
-
- return ret;
}
-int scaling_governor_func(int xc_fd, int cpuid, char *name)
+void scaling_governor_func(int argc, char *argv[])
{
- int ret = 0;
+ int cpuid = -1;
+ char *name = NULL;
- if ( cpuid < 0 )
+ if ( argc >= 2 )
{
- show_help();
- return -EINVAL;
+ name = strdup(argv[1]);
+ if ( name == NULL )
+ goto out;
+ if ( sscanf(argv[0], "%d", &cpuid) != 1 )
+ {
+ free(name);
+ goto out;
+ }
}
+ else if ( argc > 0 )
+ {
+ name = strdup(argv[0]);
+ if ( name == NULL )
+ goto out;
+ }
+ else
+ goto out;
- ret = xc_set_cpufreq_gov(xc_fd, cpuid, name);
- if ( ret )
+ if ( cpuid < 0 )
{
- fprintf(stderr, "failed to set cpufreq governor to %s\n", name);
+ int i;
+ for ( i = 0; i < max_cpu_nr; i++ )
+ if ( xc_set_cpufreq_gov(xc_fd, i, name) )
+ fprintf(stderr, "[CPU%d] failed to set governor name\n", i);
+ }
+ else
+ {
+ if ( xc_set_cpufreq_gov(xc_fd, cpuid, name) )
+ fprintf(stderr, "failed to set governor name\n");
}
- return ret;
+ free(name);
+ return ;
+out:
+ fprintf(stderr, "failed to set governor name\n");
}
struct {
const char *name;
- int (*function)(int xc_fd, int cpuid, uint32_t value);
+ void (*function)(int argc, char *argv[]);
} main_options[] = {
{ "help", help_func },
- { "get-cpuidle-states", cxstates_func },
- { "get-cpufreq-states", pxstates_func },
+ { "get-cpuidle-states", cxstat_func },
+ { "get-cpufreq-states", pxstat_func },
+ { "start", start_gather_func },
{ "get-cpufreq-para", cpufreq_para_func },
{ "set-scaling-maxfreq", scaling_max_freq_func },
{ "set-scaling-minfreq", scaling_min_freq_func },
- { "set-scaling-governor", NULL },
+ { "set-scaling-governor", scaling_governor_func },
{ "set-scaling-speed", scaling_speed_func },
{ "set-sampling-rate", scaling_sampling_rate_func },
{ "set-up-threshold", scaling_up_threshold_func },
int main(int argc, char *argv[])
{
- int i, ret = -EINVAL;
- int xc_fd;
- int cpuid = -1;
- uint32_t value = 0;
+ int i, ret = 0;
+ xc_physinfo_t physinfo = { 0 };
int nr_matches = 0;
int matches_main_options[ARRAY_SIZE(main_options)];
if ( argc < 2 )
{
show_help();
- return ret;
- }
-
- if ( argc > 2 )
- {
- if ( sscanf(argv[2], "%d", &cpuid) != 1 )
- cpuid = -1;
+ return 0;
}
xc_fd = xc_interface_open();
if ( xc_fd < 0 )
{
fprintf(stderr, "failed to get the handler\n");
+ return 0;
}
- for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
+ ret = xc_physinfo(xc_fd, &physinfo);
+ if ( ret )
{
+ fprintf(stderr, "failed to get the processor information\n");
+ xc_interface_close(xc_fd);
+ return 0;
+ }
+ max_cpu_nr = physinfo.nr_cpus;
+
+ /* calculate how many options match with user's input */
+ for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
if ( !strncmp(main_options[i].name, argv[1], strlen(argv[1])) )
- {
matches_main_options[nr_matches++] = i;
- }
- }
if ( nr_matches > 1 )
{
fprintf(stderr, "\n");
}
else if ( nr_matches == 1 )
- {
- if ( !strcmp("set-scaling-governor", main_options[matches_main_options[0]].name) )
- {
- char *name = strdup(argv[3]);
- ret = scaling_governor_func(xc_fd, cpuid, name);
- free(name);
- }
- else
- {
- if ( argc > 3 )
- {
- if ( sscanf(argv[3], "%d", &value) != 1 )
- value = 0;
- }
- ret = main_options[matches_main_options[0]].function(xc_fd, cpuid, value);
- }
- }
+ /* dispatch to the corresponding function handler */
+ main_options[matches_main_options[0]].function(argc - 2, argv + 2);
else
show_help();
xc_interface_close(xc_fd);
- return ret;
+ return 0;
}