aboutsummaryrefslogtreecommitdiffstats
path: root/tools/misc/xenpm.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-01-08 11:21:23 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-01-08 11:21:23 +0000
commit6df92ebc3022fa27c6bcf5bbcda1c2ccd24c1c17 (patch)
treed77e1691efff559f9a6ada50300d93086b31bc64 /tools/misc/xenpm.c
parent51f2134fab26bce424ee30711b194f700234c13d (diff)
downloadxen-6df92ebc3022fa27c6bcf5bbcda1c2ccd24c1c17.tar.gz
xen-6df92ebc3022fa27c6bcf5bbcda1c2ccd24c1c17.tar.bz2
xen-6df92ebc3022fa27c6bcf5bbcda1c2ccd24c1c17.zip
xenpm tool enhancements
Two enhancements are made in this patch: 1. Make cpuid in command line optional: if user does not provide cpuid, xenpm will operate on all the CPUs. this will easy the xenpm usage. e.g. to set the cpufreq governor, user usually want to set the governor on all CPUs. User can accomplish this easily with this enhancement. 2. Add another option "xenpm start" to calculate the Cx/Px state residency percentage during specified period. when user issue "xenpm start", xenpm will start to record the Cx/Px state residency. when user issue CTRL-C, xenpm will stop and show the Cx/Px state residency and percentage of this period. this is helpful to measure the xenpm effect for speficied workload. Signed-off-by: Guanqun Lu <guanqun.lu@intel.com>Signed-off-by: Ke Yu <ke.yu@intel.com>
Diffstat (limited to 'tools/misc/xenpm.c')
-rw-r--r--tools/misc/xenpm.c697
1 files changed, 454 insertions, 243 deletions
diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
index c3b19584bc..55523c6965 100644
--- a/tools/misc/xenpm.c
+++ b/tools/misc/xenpm.c
@@ -21,70 +21,89 @@
#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;
}
@@ -92,94 +111,100 @@ static int show_cx_cpuid(int xc_fd, int cpuid)
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;
}
@@ -187,64 +212,203 @@ static int show_px_cpuid(int xc_fd, int cpuid)
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 */
@@ -294,7 +458,8 @@ static void print_cpufreq_para(int cpuid, struct xc_get_cpufreq_para *p_cpufreq)
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]);
@@ -308,7 +473,7 @@ static void print_cpufreq_para(int cpuid, struct xc_get_cpufreq_para *p_cpufreq)
}
/* 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;
@@ -381,159 +546,221 @@ out:
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 },
@@ -541,38 +768,37 @@ struct {
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 )
{
@@ -582,27 +808,12 @@ int main(int argc, char *argv[])
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;
}