ia64/xen-unstable

changeset 19004:e9cd8e7c3b44

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>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 08 11:21:23 2009 +0000 (2009-01-08)
parents 95d77829216f
children 9671a4d66f40
files tools/misc/xenpm.c
line diff
     1.1 --- a/tools/misc/xenpm.c	Thu Jan 08 11:19:38 2009 +0000
     1.2 +++ b/tools/misc/xenpm.c	Thu Jan 08 11:21:23 2009 +0000
     1.3 @@ -21,83 +21,55 @@
     1.4  
     1.5  #include <stdio.h>
     1.6  #include <stdlib.h>
     1.7 +#include <unistd.h>
     1.8  #include <string.h>
     1.9  #include <getopt.h>
    1.10  #include <errno.h>
    1.11 +#include <signal.h>
    1.12  
    1.13  #include <xenctrl.h>
    1.14  #include <inttypes.h>
    1.15  
    1.16  #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
    1.17  
    1.18 +static int xc_fd;
    1.19 +static int max_cpu_nr;
    1.20 +
    1.21  /* help message */
    1.22  void show_help(void)
    1.23  {
    1.24      fprintf(stderr,
    1.25 -            "Usage:\n"
    1.26 -            "       xenpm get-cpuidle-states [cpuid]: list cpu idle information on CPU cpuid or all CPUs.\n"
    1.27 -            "       xenpm get-cpufreq-states [cpuid]: list cpu frequency information on CPU cpuid or all CPUs.\n"
    1.28 -            "       xenpm get-cpufreq-para [cpuid]: list cpu frequency information on CPU cpuid or all CPUs.\n"
    1.29 -            "       xenpm set-scaling-maxfreq <cpuid> <HZ>: set max cpu frequency <HZ> on CPU <cpuid>.\n"
    1.30 -            "       xenpm set-scaling-minfreq <cpuid> <HZ>: set min cpu frequency <HZ> on CPU <cpuid>.\n"
    1.31 -            "       xenpm set-scaling-governor <cpuid> <name>: set scaling governor on CPU <cpuid>.\n"
    1.32 -            "       xenpm set-scaling-speed <cpuid> <num>: set scaling speed on CPU <cpuid>.\n"
    1.33 -            "       xenpm set-sampling-rate <cpuid> <num>: set sampling rate on CPU <cpuid>.\n"
    1.34 -            "       xenpm set-up-threshold <cpuid> <num>: set up threshold on CPU <cpuid>.\n");
    1.35 +            "xen power management control tool\n\n"
    1.36 +            "usage: xenpm <command> [args]\n\n"
    1.37 +            "xenpm command list:\n\n"
    1.38 +            " get-cpuidle-states    [cpuid]       list cpu idle info of CPU <cpuid> or all\n"
    1.39 +            " get-cpufreq-states    [cpuid]       list cpu freq info of CPU <cpuid> or all\n"
    1.40 +            " get-cpufreq-para      [cpuid]       list cpu freq parameter of CPU <cpuid> or all\n"
    1.41 +            " set-scaling-maxfreq   [cpuid] <HZ>  set max cpu frequency <HZ> on CPU <cpuid>\n"
    1.42 +            "                                     or all CPUs\n"
    1.43 +            " set-scaling-minfreq   [cpuid] <HZ>  set min cpu frequency <HZ> on CPU <cpuid>\n"
    1.44 +            "                                     or all CPUs\n"
    1.45 +            " set-scaling-speed     [cpuid] <num> set scaling speed on CPU <cpuid> or all\n"
    1.46 +            "                                     it is used in userspace governor.\n"
    1.47 +            " set-scaling-governor  [cpuid] <gov> set scaling governor on CPU <cpuid> or all\n"
    1.48 +            "                                     as userspace/performance/powersave/ondemand\n"
    1.49 +            " set-sampling-rate     [cpuid] <num> set sampling rate on CPU <cpuid> or all\n"
    1.50 +            "                                     it is used in ondemand governor.\n"
    1.51 +            " set-up-threshold      [cpuid] <num> set up threshold on CPU <cpuid> or all\n"
    1.52 +            "                                     it is used in ondemand governor.\n"
    1.53 +            " start                               start collect Cx/Px statistics,\n"
    1.54 +            "                                     output after CTRL-C or SIGINT.\n"
    1.55 +            );
    1.56  }
    1.57 -
    1.58  /* wrapper function */
    1.59 -int help_func(int xc_fd, int cpuid, uint32_t value)
    1.60 +void help_func(int argc, char *argv[])
    1.61  {
    1.62      show_help();
    1.63 -    return 0;
    1.64  }
    1.65  
    1.66 -/* show cpu idle information on CPU cpuid */
    1.67 -static int show_cx_cpuid(int xc_fd, int cpuid)
    1.68 +static void print_cxstat(int cpuid, struct xc_cx_stat *cxstat)
    1.69  {
    1.70 -    int i, ret = 0;
    1.71 -    int max_cx_num = 0;
    1.72 -    struct xc_cx_stat cxstatinfo, *cxstat = &cxstatinfo;
    1.73 -
    1.74 -    ret = xc_pm_get_max_cx(xc_fd, cpuid, &max_cx_num);
    1.75 -    if ( ret )
    1.76 -    {
    1.77 -        if ( errno == ENODEV )
    1.78 -        {
    1.79 -            fprintf(stderr, "Xen cpuidle is not enabled!\n");
    1.80 -            return -ENODEV;
    1.81 -        }
    1.82 -        else
    1.83 -        {
    1.84 -            fprintf(stderr, "[CPU%d] failed to get max C-state\n", cpuid);
    1.85 -            return -EINVAL;
    1.86 -        }
    1.87 -    }
    1.88 -
    1.89 -    cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t));
    1.90 -    if ( !cxstat->triggers )
    1.91 -    {
    1.92 -        fprintf(stderr, "[CPU%d] failed to malloc for C-states triggers\n", cpuid);
    1.93 -        return -ENOMEM;
    1.94 -    }
    1.95 -    cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t));
    1.96 -    if ( !cxstat->residencies )
    1.97 -    {
    1.98 -        fprintf(stderr, "[CPU%d] failed to malloc for C-states residencies\n", cpuid);
    1.99 -        free(cxstat->triggers);
   1.100 -        return -ENOMEM;
   1.101 -    }
   1.102 -
   1.103 -    ret = xc_pm_get_cxstat(xc_fd, cpuid, cxstat);
   1.104 -    if( ret )
   1.105 -    {
   1.106 -        fprintf(stderr, "[CPU%d] failed to get C-states statistics "
   1.107 -                "information\n", cpuid);
   1.108 -        free(cxstat->triggers);
   1.109 -        free(cxstat->residencies);
   1.110 -        return -EINVAL;
   1.111 -    }
   1.112 +    int i;
   1.113  
   1.114      printf("cpu id               : %d\n", cpuid);
   1.115      printf("total C-states       : %d\n", cxstat->nr);
   1.116 @@ -110,88 +82,87 @@ static int show_cx_cpuid(int xc_fd, int 
   1.117          printf("                       residency  [%020"PRIu64" ms]\n",
   1.118                 cxstat->residencies[i]/1000000UL);
   1.119      }
   1.120 +    printf("\n");
   1.121 +}
   1.122  
   1.123 -    free(cxstat->triggers);
   1.124 -    free(cxstat->residencies);
   1.125 +/* show cpu idle information on CPU cpuid */
   1.126 +static int get_cxstat_by_cpuid(int xc_fd, int cpuid, struct xc_cx_stat *cxstat)
   1.127 +{
   1.128 +    int ret = 0;
   1.129 +    int max_cx_num = 0;
   1.130 +
   1.131 +    ret = xc_pm_get_max_cx(xc_fd, cpuid, &max_cx_num);
   1.132 +    if ( ret )
   1.133 +        return errno;
   1.134 +
   1.135 +    if ( !cxstat )
   1.136 +        return -EINVAL;
   1.137  
   1.138 -    printf("\n");
   1.139 +    cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t));
   1.140 +    if ( !cxstat->triggers )
   1.141 +        return -ENOMEM;
   1.142 +    cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t));
   1.143 +    if ( !cxstat->residencies )
   1.144 +    {
   1.145 +        free(cxstat->triggers);
   1.146 +        return -ENOMEM;
   1.147 +    }
   1.148 +
   1.149 +    ret = xc_pm_get_cxstat(xc_fd, cpuid, cxstat);
   1.150 +    if( ret )
   1.151 +    {
   1.152 +        int temp = errno;
   1.153 +        free(cxstat->triggers);
   1.154 +        free(cxstat->residencies);
   1.155 +        cxstat->triggers = NULL;
   1.156 +        cxstat->residencies = NULL;
   1.157 +        return temp;
   1.158 +    }
   1.159 +
   1.160      return 0;
   1.161  }
   1.162  
   1.163 -int cxstates_func(int xc_fd, int cpuid, uint32_t value)
   1.164 +static int show_cxstat_by_cpuid(int xc_fd, int cpuid)
   1.165  {
   1.166      int ret = 0;
   1.167 -    xc_physinfo_t physinfo = { 0 };
   1.168 +    struct xc_cx_stat cxstatinfo;
   1.169 +
   1.170 +    ret = get_cxstat_by_cpuid(xc_fd, cpuid, &cxstatinfo);
   1.171 +    if ( ret )
   1.172 +        return ret;
   1.173 +
   1.174 +    print_cxstat(cpuid, &cxstatinfo);
   1.175 +
   1.176 +    free(cxstatinfo.triggers);
   1.177 +    free(cxstatinfo.residencies);
   1.178 +    return 0;
   1.179 +}
   1.180 +
   1.181 +void cxstat_func(int argc, char *argv[])
   1.182 +{
   1.183 +    int cpuid = -1;
   1.184 +
   1.185 +    if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
   1.186 +        cpuid = -1;
   1.187 +
   1.188 +    if ( cpuid >= max_cpu_nr )
   1.189 +        cpuid = -1;
   1.190  
   1.191      if ( cpuid < 0 )
   1.192      {
   1.193 -        /* show cxstates on all cpu */
   1.194 -        ret = xc_physinfo(xc_fd, &physinfo);
   1.195 -        if ( ret )
   1.196 -        {
   1.197 -            fprintf(stderr, "failed to get the processor information\n");
   1.198 -        }
   1.199 -        else
   1.200 -        {
   1.201 -            int i;
   1.202 -            for ( i = 0; i < physinfo.nr_cpus; i++ )
   1.203 -            {
   1.204 -                if ( (ret = show_cx_cpuid(xc_fd, i)) == -ENODEV )
   1.205 -                    break;
   1.206 -            }
   1.207 -        }
   1.208 +        /* show cxstates on all cpus */
   1.209 +        int i;
   1.210 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.211 +            if ( show_cxstat_by_cpuid(xc_fd, i) == -ENODEV )
   1.212 +                break;
   1.213      }
   1.214      else
   1.215 -        ret = show_cx_cpuid(xc_fd, cpuid);
   1.216 -
   1.217 -    return ret;
   1.218 +        show_cxstat_by_cpuid(xc_fd, cpuid);
   1.219  }
   1.220  
   1.221 -/* show cpu frequency information on CPU cpuid */
   1.222 -static int show_px_cpuid(int xc_fd, int cpuid)
   1.223 +static void print_pxstat(int cpuid, struct xc_px_stat *pxstat)
   1.224  {
   1.225 -    int i, ret = 0;
   1.226 -    int max_px_num = 0;
   1.227 -    struct xc_px_stat pxstatinfo, *pxstat = &pxstatinfo;
   1.228 -
   1.229 -    ret = xc_pm_get_max_px(xc_fd, cpuid, &max_px_num);
   1.230 -    if ( ret )
   1.231 -    {
   1.232 -        if ( errno == ENODEV )
   1.233 -        {
   1.234 -            printf("Xen cpufreq is not enabled!\n");
   1.235 -            return -ENODEV;
   1.236 -        }
   1.237 -        else
   1.238 -        {
   1.239 -            fprintf(stderr, "[CPU%d] failed to get max P-state\n", cpuid);
   1.240 -            return -EINVAL;
   1.241 -        }
   1.242 -    }
   1.243 -
   1.244 -    pxstat->trans_pt = malloc(max_px_num * max_px_num *
   1.245 -                              sizeof(uint64_t));
   1.246 -    if ( !pxstat->trans_pt )
   1.247 -    {
   1.248 -        fprintf(stderr, "[CPU%d] failed to malloc for P-states transition table\n", cpuid);
   1.249 -        return -ENOMEM;
   1.250 -    }
   1.251 -    pxstat->pt = malloc(max_px_num * sizeof(struct xc_px_val));
   1.252 -    if ( !pxstat->pt )
   1.253 -    {
   1.254 -        fprintf(stderr, "[CPU%d] failed to malloc for P-states table\n", cpuid);
   1.255 -        free(pxstat->trans_pt);
   1.256 -        return -ENOMEM;
   1.257 -    }
   1.258 -
   1.259 -    ret = xc_pm_get_pxstat(xc_fd, cpuid, pxstat);
   1.260 -    if( ret )
   1.261 -    {
   1.262 -        fprintf(stderr, "[CPU%d] failed to get P-states statistics information\n", cpuid);
   1.263 -        free(pxstat->trans_pt);
   1.264 -        free(pxstat->pt);
   1.265 -        return -ENOMEM;
   1.266 -    }
   1.267 +    int i;
   1.268  
   1.269      printf("cpu id               : %d\n", cpuid);
   1.270      printf("total P-states       : %d\n", pxstat->total);
   1.271 @@ -211,40 +182,233 @@ static int show_px_cpuid(int xc_fd, int 
   1.272          printf("                       residency  [%020"PRIu64" ms]\n",
   1.273                 pxstat->pt[i].residency/1000000UL);
   1.274      }
   1.275 +    printf("\n");
   1.276 +}
   1.277  
   1.278 -    free(pxstat->trans_pt);
   1.279 -    free(pxstat->pt);
   1.280 +/* show cpu frequency information on CPU cpuid */
   1.281 +static int get_pxstat_by_cpuid(int xc_fd, int cpuid, struct xc_px_stat *pxstat)
   1.282 +{
   1.283 +    int ret = 0;
   1.284 +    int max_px_num = 0;
   1.285 +
   1.286 +    ret = xc_pm_get_max_px(xc_fd, cpuid, &max_px_num);
   1.287 +    if ( ret )
   1.288 +        return errno;
   1.289 +
   1.290 +    if ( !pxstat)
   1.291 +        return -EINVAL;
   1.292  
   1.293 -    printf("\n");
   1.294 +    pxstat->trans_pt = malloc(max_px_num * max_px_num *
   1.295 +                              sizeof(uint64_t));
   1.296 +    if ( !pxstat->trans_pt )
   1.297 +        return -ENOMEM;
   1.298 +    pxstat->pt = malloc(max_px_num * sizeof(struct xc_px_val));
   1.299 +    if ( !pxstat->pt )
   1.300 +    {
   1.301 +        free(pxstat->trans_pt);
   1.302 +        return -ENOMEM;
   1.303 +    }
   1.304 +
   1.305 +    ret = xc_pm_get_pxstat(xc_fd, cpuid, pxstat);
   1.306 +    if( ret )
   1.307 +    {
   1.308 +        int temp = errno;
   1.309 +        free(pxstat->trans_pt);
   1.310 +        free(pxstat->pt);
   1.311 +        pxstat->trans_pt = NULL;
   1.312 +        pxstat->pt = NULL;
   1.313 +        return temp;
   1.314 +    }
   1.315 +
   1.316      return 0;
   1.317  }
   1.318  
   1.319 -int pxstates_func(int xc_fd, int cpuid, uint32_t value)
   1.320 +static int show_pxstat_by_cpuid(int xc_fd, int cpuid)
   1.321  {
   1.322      int ret = 0;
   1.323 -    xc_physinfo_t physinfo = { 0 };
   1.324 +    struct xc_px_stat pxstatinfo;
   1.325 +
   1.326 +    ret = get_pxstat_by_cpuid(xc_fd, cpuid, &pxstatinfo);
   1.327 +    if ( ret )
   1.328 +        return ret;
   1.329 +
   1.330 +    print_pxstat(cpuid, &pxstatinfo);
   1.331 +
   1.332 +    free(pxstatinfo.trans_pt);
   1.333 +    free(pxstatinfo.pt);
   1.334 +    return 0;
   1.335 +}
   1.336 +
   1.337 +void pxstat_func(int argc, char *argv[])
   1.338 +{
   1.339 +    int cpuid = -1;
   1.340 +
   1.341 +    if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
   1.342 +        cpuid = -1;
   1.343 +
   1.344 +    if ( cpuid >= max_cpu_nr )
   1.345 +        cpuid = -1;
   1.346  
   1.347      if ( cpuid < 0 )
   1.348      {
   1.349 -        ret = xc_physinfo(xc_fd, &physinfo);
   1.350 -        if ( ret )
   1.351 +        /* show pxstates on all cpus */
   1.352 +        int i;
   1.353 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.354 +            if ( show_pxstat_by_cpuid(xc_fd, i) == -ENODEV )
   1.355 +                break;
   1.356 +    }
   1.357 +    else
   1.358 +        show_pxstat_by_cpuid(xc_fd, cpuid);
   1.359 +}
   1.360 +
   1.361 +static uint64_t usec_start, usec_end;
   1.362 +static struct xc_cx_stat *cxstat, *cxstat_start, *cxstat_end;
   1.363 +static struct xc_px_stat *pxstat, *pxstat_start, *pxstat_end;
   1.364 +static uint64_t *sum, *sum_cx, *sum_px;
   1.365 +
   1.366 +static void signal_int_handler(int signo)
   1.367 +{
   1.368 +    int i, j;
   1.369 +    struct timeval tv;
   1.370 +    int cx_cap = 0, px_cap = 0;
   1.371 +
   1.372 +    if ( gettimeofday(&tv, NULL) == -1 )
   1.373 +    {
   1.374 +        fprintf(stderr, "failed to get timeofday\n");
   1.375 +        return ;
   1.376 +    }
   1.377 +    usec_end = tv.tv_sec * 1000000UL + tv.tv_usec;
   1.378 +
   1.379 +    if ( get_cxstat_by_cpuid(xc_fd, 0, NULL) != -ENODEV )
   1.380 +    {
   1.381 +        cx_cap = 1;
   1.382 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.383 +            if ( !get_cxstat_by_cpuid(xc_fd, i, &cxstat_end[i]) )
   1.384 +                for ( j = 0; j < cxstat_end[i].nr; j++ )
   1.385 +                    sum_cx[i] += cxstat_end[i].residencies[j] -
   1.386 +                                 cxstat_start[i].residencies[j];
   1.387 +    }
   1.388 +
   1.389 +    if ( get_pxstat_by_cpuid(xc_fd, 0, NULL) != -ENODEV )
   1.390 +    {
   1.391 +        px_cap = 1;
   1.392 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.393 +            if ( !get_pxstat_by_cpuid(xc_fd, i , &pxstat_end[i]) )
   1.394 +                for ( j = 0; j < pxstat_end[i].total; j++ )
   1.395 +                    sum_px[i] += pxstat_end[i].pt[j].residency -
   1.396 +                                 pxstat_start[i].pt[j].residency;
   1.397 +    }
   1.398 +
   1.399 +    printf("Elapsed time (ms): %"PRIu64"\n", (usec_end - usec_start) / 1000UL);
   1.400 +    for ( i = 0; i < max_cpu_nr; i++ )
   1.401 +    {
   1.402 +        uint64_t temp;
   1.403 +        printf("CPU%d:\n\tresidency\tpercentage\n", i);
   1.404 +        if ( cx_cap )
   1.405          {
   1.406 -            fprintf(stderr, "failed to get the processor information\n");
   1.407 +            for ( j = 0; j < cxstat_end[i].nr; j++ )
   1.408 +            {
   1.409 +                if ( sum_cx[i] > 0 )
   1.410 +                {
   1.411 +                    temp = cxstat_end[i].residencies[j] -
   1.412 +                           cxstat_start[i].residencies[j];
   1.413 +                    printf("  C%d\t%"PRIu64" ms\t%.2f%%\n", j,
   1.414 +                           temp / 1000000UL, 100UL * temp / (double)sum_cx[i]);
   1.415 +                }
   1.416 +            }
   1.417          }
   1.418 -        else
   1.419 +        if ( px_cap )
   1.420          {
   1.421 -            int i;
   1.422 -            for ( i = 0; i < physinfo.nr_cpus; i++ )
   1.423 +            for ( j = 0; j < pxstat_end[i].total; j++ )
   1.424              {
   1.425 -                if ( (ret = show_px_cpuid(xc_fd, i)) == -ENODEV )
   1.426 -                    break;
   1.427 +                if ( sum_px[i] > 0 )
   1.428 +                {
   1.429 +                    temp = pxstat_end[i].pt[j].residency -
   1.430 +                           pxstat_start[i].pt[j].residency;
   1.431 +                    printf("  P%d\t%"PRIu64" ms\t%.2f%%\n", j,
   1.432 +                           temp / 1000000UL, 100UL * temp / (double)sum_px[i]);
   1.433 +                }
   1.434              }
   1.435          }
   1.436 +        printf("\n");
   1.437      }
   1.438 -    else
   1.439 -        ret = show_px_cpuid(xc_fd, cpuid);
   1.440 +
   1.441 +    /* some clean up and then exits */
   1.442 +    for ( i = 0; i < 2 * max_cpu_nr; i++ )
   1.443 +    {
   1.444 +        free(cxstat[i].triggers);
   1.445 +        free(cxstat[i].residencies);
   1.446 +        free(pxstat[i].trans_pt);
   1.447 +        free(pxstat[i].pt);
   1.448 +    }
   1.449 +    free(cxstat);
   1.450 +    free(pxstat);
   1.451 +    free(sum);
   1.452 +    xc_interface_close(xc_fd);
   1.453 +    exit(0);
   1.454 +}
   1.455 +
   1.456 +void start_gather_func(int argc, char *argv[])
   1.457 +{
   1.458 +    int i;
   1.459 +    struct timeval tv;
   1.460 +
   1.461 +    if ( gettimeofday(&tv, NULL) == -1 )
   1.462 +    {
   1.463 +        fprintf(stderr, "failed to get timeofday\n");
   1.464 +        return ;
   1.465 +    }
   1.466 +    usec_start = tv.tv_sec * 1000000UL + tv.tv_usec;
   1.467  
   1.468 -    return ret;
   1.469 +    sum = malloc(sizeof(uint64_t) * 2 * max_cpu_nr);
   1.470 +    if ( sum == NULL )
   1.471 +        return ;
   1.472 +    cxstat = malloc(sizeof(struct xc_cx_stat) * 2 * max_cpu_nr);
   1.473 +    if ( cxstat == NULL )
   1.474 +    {
   1.475 +        free(sum);
   1.476 +        return ;
   1.477 +    }
   1.478 +    pxstat = malloc(sizeof(struct xc_px_stat) * 2 * max_cpu_nr);
   1.479 +    if ( pxstat == NULL )
   1.480 +    {
   1.481 +        free(sum);
   1.482 +        free(cxstat);
   1.483 +        return ;
   1.484 +    }
   1.485 +    memset(sum, 0, sizeof(uint64_t) * 2 * max_cpu_nr);
   1.486 +    memset(cxstat, 0, sizeof(struct xc_cx_stat) * 2 * max_cpu_nr);
   1.487 +    memset(pxstat, 0, sizeof(struct xc_px_stat) * 2 * max_cpu_nr);
   1.488 +    sum_cx = sum;
   1.489 +    sum_px = sum + max_cpu_nr;
   1.490 +    cxstat_start = cxstat;
   1.491 +    cxstat_end = cxstat + max_cpu_nr;
   1.492 +    pxstat_start = pxstat;
   1.493 +    pxstat_end = pxstat + max_cpu_nr;
   1.494 +
   1.495 +    if ( get_cxstat_by_cpuid(xc_fd, 0, NULL) == -ENODEV &&
   1.496 +         get_pxstat_by_cpuid(xc_fd, 0, NULL) == -ENODEV )
   1.497 +    {
   1.498 +        fprintf(stderr, "Xen cpu idle and frequency is disabled!\n");
   1.499 +        return ;
   1.500 +    }
   1.501 +
   1.502 +    for ( i = 0; i < max_cpu_nr; i++ )
   1.503 +    {
   1.504 +        get_cxstat_by_cpuid(xc_fd, i, &cxstat_start[i]);
   1.505 +        get_pxstat_by_cpuid(xc_fd, i, &pxstat_start[i]);
   1.506 +    }
   1.507 +
   1.508 +    if (signal(SIGINT, signal_int_handler) == SIG_ERR)
   1.509 +    {
   1.510 +        fprintf(stderr, "failed to set signal int handler\n");
   1.511 +        free(sum);
   1.512 +        free(pxstat);
   1.513 +        free(cxstat);
   1.514 +        return ;
   1.515 +    }
   1.516 +
   1.517 +    pause();
   1.518  }
   1.519  
   1.520  /* print out parameters about cpu frequency */
   1.521 @@ -294,7 +458,8 @@ static void print_cpufreq_para(int cpuid
   1.522  
   1.523      printf("scaling_avail_freq   :");
   1.524      for ( i = 0; i < p_cpufreq->freq_num; i++ )
   1.525 -        if ( p_cpufreq->scaling_available_frequencies[i] == p_cpufreq->scaling_cur_freq )
   1.526 +        if ( p_cpufreq->scaling_available_frequencies[i] ==
   1.527 +             p_cpufreq->scaling_cur_freq )
   1.528              printf(" *%d", p_cpufreq->scaling_available_frequencies[i]);
   1.529          else
   1.530              printf(" %d", p_cpufreq->scaling_available_frequencies[i]);
   1.531 @@ -308,7 +473,7 @@ static void print_cpufreq_para(int cpuid
   1.532  }
   1.533  
   1.534  /* show cpu frequency parameters information on CPU cpuid */
   1.535 -static int show_cpufreq_para_cpuid(int xc_fd, int cpuid)
   1.536 +static int show_cpufreq_para_by_cpuid(int xc_fd, int cpuid)
   1.537  {
   1.538      int ret = 0;
   1.539      struct xc_get_cpufreq_para cpufreq_para, *p_cpufreq = &cpufreq_para;
   1.540 @@ -381,159 +546,221 @@ out:
   1.541      return ret;
   1.542  }
   1.543  
   1.544 -int cpufreq_para_func(int xc_fd, int cpuid, uint32_t value)
   1.545 +void cpufreq_para_func(int argc, char *argv[])
   1.546  {
   1.547 -    int ret = 0;
   1.548 -    xc_physinfo_t physinfo = { 0 };
   1.549 +    int cpuid = -1;
   1.550 +
   1.551 +    if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
   1.552 +        cpuid = -1;
   1.553 +
   1.554 +    if ( cpuid >= max_cpu_nr )
   1.555 +        cpuid = -1;
   1.556 +
   1.557 +    if ( cpuid < 0 )
   1.558 +    {
   1.559 +        /* show cpu freqency information on all cpus */
   1.560 +        int i;
   1.561 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.562 +            if ( show_cpufreq_para_by_cpuid(xc_fd, i) == -ENODEV )
   1.563 +                break;
   1.564 +    }
   1.565 +    else
   1.566 +        show_cpufreq_para_by_cpuid(xc_fd, cpuid);
   1.567 +}
   1.568 +
   1.569 +void scaling_max_freq_func(int argc, char *argv[])
   1.570 +{
   1.571 +    int cpuid = -1, freq = -1;
   1.572 +
   1.573 +    if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
   1.574 +                        sscanf(argv[0], "%d", &cpuid) != 1)) ||
   1.575 +         (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
   1.576 +         argc == 0 )
   1.577 +    {
   1.578 +        fprintf(stderr, "failed to set scaling max freq\n");
   1.579 +        return ;
   1.580 +    }
   1.581  
   1.582      if ( cpuid < 0 )
   1.583      {
   1.584 -        ret = xc_physinfo(xc_fd, &physinfo);
   1.585 -        if ( ret )
   1.586 -        {
   1.587 -            fprintf(stderr, "failed to get the processor information\n");
   1.588 -        }
   1.589 -        else
   1.590 -        {
   1.591 -            int i;
   1.592 -            for ( i = 0; i < physinfo.nr_cpus; i++ )
   1.593 -            {
   1.594 -                if ( (ret = show_cpufreq_para_cpuid(xc_fd, i)) == -ENODEV )
   1.595 -                    break;
   1.596 -            }
   1.597 -        }
   1.598 +        int i;
   1.599 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.600 +            if ( xc_set_cpufreq_para(xc_fd, i, SCALING_MAX_FREQ, freq) )
   1.601 +                fprintf(stderr, "[CPU%d] failed to set scaling max freq\n", i);
   1.602      }
   1.603      else
   1.604 -        ret = show_cpufreq_para_cpuid(xc_fd, cpuid);
   1.605 -
   1.606 -    return ret;
   1.607 +    {
   1.608 +        if ( xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MAX_FREQ, freq) )
   1.609 +            fprintf(stderr, "failed to set scaling max freq\n");
   1.610 +    }
   1.611  }
   1.612  
   1.613 -int scaling_max_freq_func(int xc_fd, int cpuid, uint32_t value)
   1.614 +void scaling_min_freq_func(int argc, char *argv[])
   1.615  {
   1.616 -    int ret = 0;
   1.617 +    int cpuid = -1, freq = -1;
   1.618 +
   1.619 +    if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
   1.620 +                        sscanf(argv[0], "%d", &cpuid) != 1) ) ||
   1.621 +         (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
   1.622 +         argc == 0 )
   1.623 +    {
   1.624 +        fprintf(stderr, "failed to set scaling min freq\n");
   1.625 +        return ;
   1.626 +    }
   1.627  
   1.628      if ( cpuid < 0 )
   1.629      {
   1.630 -        show_help();
   1.631 -        return -EINVAL;
   1.632 +        int i;
   1.633 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.634 +            if ( xc_set_cpufreq_para(xc_fd, i, SCALING_MIN_FREQ, freq) )
   1.635 +                fprintf(stderr, "[CPU%d] failed to set scaling min freq\n", i);
   1.636      }
   1.637 -
   1.638 -    ret = xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MAX_FREQ, value);
   1.639 -    if ( ret )
   1.640 +    else
   1.641      {
   1.642 -        fprintf(stderr, "[CPU%d] failed to set scaling max freq\n", cpuid);
   1.643 +        if ( xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MIN_FREQ, freq) )
   1.644 +            fprintf(stderr, "failed to set scaling min freq\n");
   1.645      }
   1.646 -
   1.647 -    return ret;
   1.648  }
   1.649  
   1.650 -int scaling_min_freq_func(int xc_fd, int cpuid, uint32_t value)
   1.651 +void scaling_speed_func(int argc, char *argv[])
   1.652  {
   1.653 -    int ret;
   1.654 +    int cpuid = -1, speed = -1;
   1.655 +
   1.656 +    if ( (argc >= 2 && (sscanf(argv[1], "%d", &speed) != 1 ||
   1.657 +                        sscanf(argv[0], "%d", &cpuid) != 1) ) ||
   1.658 +         (argc == 1 && sscanf(argv[0], "%d", &speed) != 1 ) ||
   1.659 +         argc == 0 )
   1.660 +    {
   1.661 +        fprintf(stderr, "failed to set scaling speed\n");
   1.662 +        return ;
   1.663 +    }
   1.664  
   1.665      if ( cpuid < 0 )
   1.666      {
   1.667 -        show_help();
   1.668 -        return -EINVAL;
   1.669 +        int i;
   1.670 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.671 +            if ( xc_set_cpufreq_para(xc_fd, i, SCALING_SETSPEED, speed) )
   1.672 +                fprintf(stderr, "[CPU%d] failed to set scaling speed\n", i);
   1.673      }
   1.674 -
   1.675 -    ret = xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MIN_FREQ, value);
   1.676 -    if ( ret )
   1.677 +    else
   1.678      {
   1.679 -        fprintf(stderr, "[CPU%d] failed to set scaling min freq\n", cpuid);
   1.680 +        if ( xc_set_cpufreq_para(xc_fd, cpuid, SCALING_SETSPEED, speed) )
   1.681 +            fprintf(stderr, "failed to set scaling speed\n");
   1.682      }
   1.683 -
   1.684 -    return ret;
   1.685  }
   1.686  
   1.687 -int scaling_speed_func(int xc_fd, int cpuid, uint32_t value)
   1.688 +void scaling_sampling_rate_func(int argc, char *argv[])
   1.689  {
   1.690 -    int ret;
   1.691 +    int cpuid = -1, rate = -1;
   1.692 +
   1.693 +    if ( (argc >= 2 && (sscanf(argv[1], "%d", &rate) != 1 ||
   1.694 +                        sscanf(argv[0], "%d", &cpuid) != 1) ) ||
   1.695 +         (argc == 1 && sscanf(argv[0], "%d", &rate) != 1 ) ||
   1.696 +         argc == 0 )
   1.697 +    {
   1.698 +        fprintf(stderr, "failed to set scaling sampling rate\n");
   1.699 +        return ;
   1.700 +    }
   1.701  
   1.702      if ( cpuid < 0 )
   1.703      {
   1.704 -        show_help();
   1.705 -        return -EINVAL;
   1.706 +        int i;
   1.707 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.708 +            if ( xc_set_cpufreq_para(xc_fd, i, SAMPLING_RATE, rate) )
   1.709 +                fprintf(stderr,
   1.710 +                        "[CPU%d] failed to set scaling sampling rate\n", i);
   1.711      }
   1.712 -
   1.713 -    ret = xc_set_cpufreq_para(xc_fd, cpuid, SCALING_SETSPEED, value);
   1.714 -    if ( ret )
   1.715 +    else
   1.716      {
   1.717 -        fprintf(stderr, "[CPU%d] failed to set scaling speed\n", cpuid);
   1.718 +        if ( xc_set_cpufreq_para(xc_fd, cpuid, SAMPLING_RATE, rate) )
   1.719 +            fprintf(stderr, "failed to set scaling sampling rate\n");
   1.720      }
   1.721 -
   1.722 -    return ret;
   1.723  }
   1.724  
   1.725 -int scaling_sampling_rate_func(int xc_fd, int cpuid, uint32_t value)
   1.726 +void scaling_up_threshold_func(int argc, char *argv[])
   1.727  {
   1.728 -    int ret;
   1.729 +    int cpuid = -1, threshold = -1;
   1.730 +
   1.731 +    if ( (argc >= 2 && (sscanf(argv[1], "%d", &threshold) != 1 ||
   1.732 +                        sscanf(argv[0], "%d", &cpuid) != 1) ) ||
   1.733 +         (argc == 1 && sscanf(argv[0], "%d", &threshold) != 1 ) ||
   1.734 +         argc == 0 )
   1.735 +    {
   1.736 +        fprintf(stderr, "failed to set up scaling threshold\n");
   1.737 +        return ;
   1.738 +    }
   1.739  
   1.740      if ( cpuid < 0 )
   1.741      {
   1.742 -        show_help();
   1.743 -        return -EINVAL;
   1.744 +        int i;
   1.745 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.746 +            if ( xc_set_cpufreq_para(xc_fd, i, UP_THRESHOLD, threshold) )
   1.747 +                fprintf(stderr,
   1.748 +                        "[CPU%d] failed to set up scaling threshold\n", i);
   1.749      }
   1.750 -
   1.751 -    ret = xc_set_cpufreq_para(xc_fd, cpuid, SAMPLING_RATE, value);
   1.752 -    if ( ret ) 
   1.753 +    else
   1.754      {
   1.755 -        fprintf(stderr, "[CPU%d] failed to set scaling sampling rate\n", cpuid);
   1.756 +        if ( xc_set_cpufreq_para(xc_fd, cpuid, UP_THRESHOLD, threshold) )
   1.757 +            fprintf(stderr, "failed to set up scaling threshold\n");
   1.758      }
   1.759 -
   1.760 -    return ret;
   1.761  }
   1.762  
   1.763 -int scaling_up_threshold_func(int xc_fd, int cpuid, uint32_t value)
   1.764 +void scaling_governor_func(int argc, char *argv[])
   1.765  {
   1.766 -    int ret;
   1.767 +    int cpuid = -1;
   1.768 +    char *name = NULL;
   1.769 +
   1.770 +    if ( argc >= 2 )
   1.771 +    {
   1.772 +        name = strdup(argv[1]);
   1.773 +        if ( name == NULL )
   1.774 +            goto out;
   1.775 +        if ( sscanf(argv[0], "%d", &cpuid) != 1 )
   1.776 +        {
   1.777 +            free(name);
   1.778 +            goto out;
   1.779 +        }
   1.780 +    }
   1.781 +    else if ( argc > 0 )
   1.782 +    {
   1.783 +        name = strdup(argv[0]);
   1.784 +        if ( name == NULL )
   1.785 +            goto out;
   1.786 +    }
   1.787 +    else
   1.788 +        goto out;
   1.789  
   1.790      if ( cpuid < 0 )
   1.791      {
   1.792 -        show_help();
   1.793 -        return -EINVAL;
   1.794 +        int i;
   1.795 +        for ( i = 0; i < max_cpu_nr; i++ )
   1.796 +            if ( xc_set_cpufreq_gov(xc_fd, i, name) )
   1.797 +                fprintf(stderr, "[CPU%d] failed to set governor name\n", i);
   1.798      }
   1.799 -
   1.800 -    ret = xc_set_cpufreq_para(xc_fd, cpuid, UP_THRESHOLD, value);
   1.801 -    if ( ret )
   1.802 +    else
   1.803      {
   1.804 -        fprintf(stderr, "[CPU%d] failed to set scaling threshold\n", cpuid);
   1.805 +        if ( xc_set_cpufreq_gov(xc_fd, cpuid, name) )
   1.806 +            fprintf(stderr, "failed to set governor name\n");
   1.807      }
   1.808  
   1.809 -    return ret;
   1.810 -}
   1.811 -
   1.812 -int scaling_governor_func(int xc_fd, int cpuid, char *name)
   1.813 -{
   1.814 -    int ret = 0;
   1.815 -
   1.816 -    if ( cpuid < 0 )
   1.817 -    {
   1.818 -        show_help();
   1.819 -        return -EINVAL;
   1.820 -    }
   1.821 -
   1.822 -    ret = xc_set_cpufreq_gov(xc_fd, cpuid, name);
   1.823 -    if ( ret )
   1.824 -    {
   1.825 -        fprintf(stderr, "failed to set cpufreq governor to %s\n", name);
   1.826 -    }
   1.827 -
   1.828 -    return ret;
   1.829 +    free(name);
   1.830 +    return ;
   1.831 +out:
   1.832 +    fprintf(stderr, "failed to set governor name\n");
   1.833  }
   1.834  
   1.835  struct {
   1.836      const char *name;
   1.837 -    int (*function)(int xc_fd, int cpuid, uint32_t value);
   1.838 +    void (*function)(int argc, char *argv[]);
   1.839  } main_options[] = {
   1.840      { "help", help_func },
   1.841 -    { "get-cpuidle-states", cxstates_func },
   1.842 -    { "get-cpufreq-states", pxstates_func },
   1.843 +    { "get-cpuidle-states", cxstat_func },
   1.844 +    { "get-cpufreq-states", pxstat_func },
   1.845 +    { "start", start_gather_func },
   1.846      { "get-cpufreq-para", cpufreq_para_func },
   1.847      { "set-scaling-maxfreq", scaling_max_freq_func },
   1.848      { "set-scaling-minfreq", scaling_min_freq_func },
   1.849 -    { "set-scaling-governor", NULL },
   1.850 +    { "set-scaling-governor", scaling_governor_func },
   1.851      { "set-scaling-speed", scaling_speed_func },
   1.852      { "set-sampling-rate", scaling_sampling_rate_func },
   1.853      { "set-up-threshold", scaling_up_threshold_func },
   1.854 @@ -541,38 +768,37 @@ struct {
   1.855  
   1.856  int main(int argc, char *argv[])
   1.857  {
   1.858 -    int i, ret = -EINVAL;
   1.859 -    int xc_fd;
   1.860 -    int cpuid = -1;
   1.861 -    uint32_t value = 0;
   1.862 +    int i, ret = 0;
   1.863 +    xc_physinfo_t physinfo = { 0 };
   1.864      int nr_matches = 0;
   1.865      int matches_main_options[ARRAY_SIZE(main_options)];
   1.866  
   1.867      if ( argc < 2 )
   1.868      {
   1.869          show_help();
   1.870 -        return ret;
   1.871 -    }
   1.872 -
   1.873 -    if ( argc > 2 )
   1.874 -    {
   1.875 -        if ( sscanf(argv[2], "%d", &cpuid) != 1 )
   1.876 -            cpuid = -1;
   1.877 +        return 0;
   1.878      }
   1.879  
   1.880      xc_fd = xc_interface_open();
   1.881      if ( xc_fd < 0 )
   1.882      {
   1.883          fprintf(stderr, "failed to get the handler\n");
   1.884 +        return 0;
   1.885      }
   1.886  
   1.887 +    ret = xc_physinfo(xc_fd, &physinfo);
   1.888 +    if ( ret )
   1.889 +    {
   1.890 +        fprintf(stderr, "failed to get the processor information\n");
   1.891 +        xc_interface_close(xc_fd);
   1.892 +        return 0;
   1.893 +    }
   1.894 +    max_cpu_nr = physinfo.nr_cpus;
   1.895 +
   1.896 +    /* calculate how many options match with user's input */
   1.897      for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
   1.898 -    {
   1.899          if ( !strncmp(main_options[i].name, argv[1], strlen(argv[1])) )
   1.900 -        {
   1.901              matches_main_options[nr_matches++] = i;
   1.902 -        }
   1.903 -    }
   1.904  
   1.905      if ( nr_matches > 1 )
   1.906      {
   1.907 @@ -582,27 +808,12 @@ int main(int argc, char *argv[])
   1.908          fprintf(stderr, "\n");
   1.909      }
   1.910      else if ( nr_matches == 1 )
   1.911 -    {
   1.912 -        if ( !strcmp("set-scaling-governor", main_options[matches_main_options[0]].name) )
   1.913 -        {
   1.914 -            char *name = strdup(argv[3]);
   1.915 -            ret = scaling_governor_func(xc_fd, cpuid, name);
   1.916 -            free(name);
   1.917 -        }
   1.918 -        else
   1.919 -        {
   1.920 -            if ( argc > 3 )
   1.921 -            {
   1.922 -                if ( sscanf(argv[3], "%d", &value) != 1 )
   1.923 -                    value = 0;
   1.924 -            }
   1.925 -            ret = main_options[matches_main_options[0]].function(xc_fd, cpuid, value);
   1.926 -        }
   1.927 -    }
   1.928 +        /* dispatch to the corresponding function handler */
   1.929 +        main_options[matches_main_options[0]].function(argc - 2, argv + 2);
   1.930      else
   1.931          show_help();
   1.932  
   1.933      xc_interface_close(xc_fd);
   1.934 -    return ret;
   1.935 +    return 0;
   1.936  }
   1.937