ia64/xen-unstable

changeset 17669:d0817f08599a

Provide Px statistic data to user through libxc

Sampling and collecting dynamic Px statistic data, including
Px state value, Px count, Px residency time, Px transition
matrix, etc. Provide Px statistic data to user through libxc.

Signed-off-by: Liu Jinsong <jinsong.liu@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri May 16 09:37:19 2008 +0100 (2008-05-16)
parents f65906f262f9
children 6d0cc186bf41 3a5750f4a738
files tools/libxc/Makefile tools/libxc/xc_pm.c tools/libxc/xenctrl.h xen/arch/x86/acpi/Makefile xen/arch/x86/acpi/cpufreq/cpufreq.c xen/arch/x86/acpi/cpufreq/utility.c xen/arch/x86/acpi/pmstat.c xen/arch/x86/platform_hypercall.c xen/common/sysctl.c xen/include/acpi/cpufreq/processor_perf.h xen/include/public/sysctl.h
line diff
     1.1 --- a/tools/libxc/Makefile	Fri May 16 09:31:03 2008 +0100
     1.2 +++ b/tools/libxc/Makefile	Fri May 16 09:37:19 2008 +0100
     1.3 @@ -20,6 +20,7 @@ CTRL_SRCS-y       += xc_private.c
     1.4  CTRL_SRCS-y       += xc_sedf.c
     1.5  CTRL_SRCS-y       += xc_csched.c
     1.6  CTRL_SRCS-y       += xc_tbuf.c
     1.7 +CTRL_SRCS-y       += xc_pm.c
     1.8  ifneq ($(stubdom),y)
     1.9  CTRL_SRCS-y       += xc_resume.c
    1.10  endif
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/libxc/xc_pm.c	Fri May 16 09:37:19 2008 +0100
     2.3 @@ -0,0 +1,101 @@
     2.4 +/******************************************************************************
     2.5 + * xc_pm.c - Libxc API for Xen Power Management (Px/Cx/Tx, etc.) statistic
     2.6 + *
     2.7 + * Copyright (c) 2008, Liu Jinsong <jinsong.liu@intel.com>
     2.8 + *
     2.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    2.10 + * of this software and associated documentation files (the "Software"), to
    2.11 + * deal in the Software without restriction, including without limitation the
    2.12 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    2.13 + * sell copies of the Software, and to permit persons to whom the Software is
    2.14 + * furnished to do so, subject to the following conditions:
    2.15 + *
    2.16 + * The above copyright notice and this permission notice shall be included in
    2.17 + * all copies or substantial portions of the Software.
    2.18 + *
    2.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    2.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    2.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    2.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    2.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    2.24 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    2.25 + * DEALINGS IN THE SOFTWARE.
    2.26 + *
    2.27 + */
    2.28 +
    2.29 +#include "xc_private.h"
    2.30 +
    2.31 +int xc_pm_get_max_px(int xc_handle, int cpuid, int *max_px)
    2.32 +{
    2.33 +    DECLARE_SYSCTL;
    2.34 +    int ret;
    2.35 +
    2.36 +    sysctl.cmd = XEN_SYSCTL_get_pmstat;
    2.37 +    sysctl.u.get_pmstat.type = PMSTAT_get_max_px;
    2.38 +    sysctl.u.get_pmstat.cpuid = cpuid;
    2.39 +    ret = xc_sysctl(xc_handle, &sysctl);
    2.40 +    if ( ret )
    2.41 +        return ret;
    2.42 +
    2.43 +    *max_px = sysctl.u.get_pmstat.u.getpx.total;
    2.44 +    return ret;
    2.45 +}
    2.46 +
    2.47 +int xc_pm_get_pxstat(int xc_handle, int cpuid, struct xc_px_stat *pxpt)
    2.48 +{
    2.49 +    DECLARE_SYSCTL;
    2.50 +    int max_px, ret;
    2.51 +
    2.52 +    if ( !pxpt || !(pxpt->trans_pt) || !(pxpt->pt) )
    2.53 +        return -EINVAL;
    2.54 +
    2.55 +    if ( (ret = xc_pm_get_max_px(xc_handle, cpuid, &max_px)) != 0)
    2.56 +        return ret;
    2.57 +
    2.58 +    if ( (ret = lock_pages(pxpt->trans_pt, 
    2.59 +        max_px * max_px * sizeof(uint64_t))) != 0 )
    2.60 +        return ret;
    2.61 +
    2.62 +    if ( (ret = lock_pages(pxpt->pt, 
    2.63 +        max_px * sizeof(struct xc_px_val))) != 0 )
    2.64 +    {
    2.65 +        unlock_pages(pxpt->trans_pt, max_px * max_px * sizeof(uint64_t));
    2.66 +        return ret;
    2.67 +    }
    2.68 +
    2.69 +    sysctl.cmd = XEN_SYSCTL_get_pmstat;
    2.70 +    sysctl.u.get_pmstat.type = PMSTAT_get_pxstat;
    2.71 +    sysctl.u.get_pmstat.cpuid = cpuid;
    2.72 +    set_xen_guest_handle(sysctl.u.get_pmstat.u.getpx.trans_pt, pxpt->trans_pt);
    2.73 +    set_xen_guest_handle(sysctl.u.get_pmstat.u.getpx.pt, 
    2.74 +                        (pm_px_val_t *)pxpt->pt);
    2.75 +
    2.76 +    ret = xc_sysctl(xc_handle, &sysctl);
    2.77 +    if ( ret )
    2.78 +    {
    2.79 +        unlock_pages(pxpt->trans_pt, max_px * max_px * sizeof(uint64_t));
    2.80 +        unlock_pages(pxpt->pt, max_px * sizeof(struct xc_px_val));
    2.81 +        return ret;
    2.82 +    }
    2.83 +
    2.84 +    pxpt->total = sysctl.u.get_pmstat.u.getpx.total;
    2.85 +    pxpt->usable = sysctl.u.get_pmstat.u.getpx.usable;
    2.86 +    pxpt->last = sysctl.u.get_pmstat.u.getpx.last;
    2.87 +    pxpt->cur = sysctl.u.get_pmstat.u.getpx.cur;
    2.88 +
    2.89 +    unlock_pages(pxpt->trans_pt, max_px * max_px * sizeof(uint64_t));
    2.90 +    unlock_pages(pxpt->pt, max_px * sizeof(struct xc_px_val));
    2.91 +
    2.92 +    return ret;
    2.93 +}
    2.94 +
    2.95 +int xc_pm_reset_pxstat(int xc_handle, int cpuid)
    2.96 +{
    2.97 +    DECLARE_SYSCTL;
    2.98 +
    2.99 +    sysctl.cmd = XEN_SYSCTL_get_pmstat;
   2.100 +    sysctl.u.get_pmstat.type = PMSTAT_reset_pxstat;
   2.101 +    sysctl.u.get_pmstat.cpuid = cpuid;
   2.102 +
   2.103 +    return xc_sysctl(xc_handle, &sysctl);
   2.104 +}
     3.1 --- a/tools/libxc/xenctrl.h	Fri May 16 09:31:03 2008 +0100
     3.2 +++ b/tools/libxc/xenctrl.h	Fri May 16 09:37:19 2008 +0100
     3.3 @@ -1034,4 +1034,23 @@ void xc_cpuid_to_str(const unsigned int 
     3.4                       char **strs);
     3.5  #endif
     3.6  
     3.7 +struct xc_px_val {
     3.8 +    uint64_t freq;        /* Px core frequency */
     3.9 +    uint64_t residency;   /* Px residency time */
    3.10 +    uint64_t count;       /* Px transition count */
    3.11 +};
    3.12 +
    3.13 +struct xc_px_stat {
    3.14 +    uint8_t total;        /* total Px states */
    3.15 +    uint8_t usable;       /* usable Px states */
    3.16 +    uint8_t last;         /* last Px state */
    3.17 +    uint8_t cur;          /* current Px state */
    3.18 +    uint64_t *trans_pt;   /* Px transition table */
    3.19 +    struct xc_px_val *pt;
    3.20 +};
    3.21 +
    3.22 +int xc_pm_get_max_px(int xc_handle, int cpuid, int *max_px);
    3.23 +int xc_pm_get_pxstat(int xc_handle, int cpuid, struct xc_px_stat *pxpt);
    3.24 +int xc_pm_reset_pxstat(int xc_handle, int cpuid);
    3.25 +
    3.26  #endif /* XENCTRL_H */
     4.1 --- a/xen/arch/x86/acpi/Makefile	Fri May 16 09:31:03 2008 +0100
     4.2 +++ b/xen/arch/x86/acpi/Makefile	Fri May 16 09:37:19 2008 +0100
     4.3 @@ -2,3 +2,4 @@ subdir-y += cpufreq
     4.4  
     4.5  obj-y += boot.o
     4.6  obj-y += power.o suspend.o wakeup_prot.o cpu_idle.o
     4.7 +obj-y += pmstat.o
     5.1 --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c	Fri May 16 09:31:03 2008 +0100
     5.2 +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c	Fri May 16 09:37:19 2008 +0100
     5.3 @@ -369,6 +369,8 @@ static int acpi_cpufreq_target(struct cp
     5.4      if (!check_freqs(cmd.mask, freqs.new, data))
     5.5          return -EAGAIN;
     5.6  
     5.7 +    px_statistic_update(cmd.mask, perf->state, next_perf_state);
     5.8 +
     5.9      perf->state = next_perf_state;
    5.10      policy->cur = freqs.new;
    5.11  
    5.12 @@ -581,9 +583,13 @@ int acpi_cpufreq_init(void)
    5.13      for_each_online_cpu(i) {
    5.14          xen_px_policy[i].cpu = i;
    5.15  
    5.16 +        ret = px_statistic_init(i);
    5.17 +        if (ret)
    5.18 +            goto out;
    5.19 +
    5.20          ret = acpi_cpufreq_cpu_init(&xen_px_policy[i]);
    5.21          if (ret)
    5.22 -            goto cpufreq_init_out;
    5.23 +            goto out;
    5.24      }
    5.25  
    5.26      /* setup ondemand cpufreq */
    5.27 @@ -593,10 +599,10 @@ int acpi_cpufreq_init(void)
    5.28          i = first_cpu(pt[dom]);
    5.29          ret = cpufreq_governor_dbs(&xen_px_policy[i], CPUFREQ_GOV_START);
    5.30          if (ret)
    5.31 -            goto cpufreq_init_out;
    5.32 +            goto out;
    5.33      }
    5.34  
    5.35 -cpufreq_init_out:
    5.36 +out:
    5.37      xfree(pt);
    5.38     
    5.39      return ret;
     6.1 --- a/xen/arch/x86/acpi/cpufreq/utility.c	Fri May 16 09:31:03 2008 +0100
     6.2 +++ b/xen/arch/x86/acpi/cpufreq/utility.c	Fri May 16 09:37:19 2008 +0100
     6.3 @@ -34,6 +34,83 @@
     6.4  struct cpufreq_driver *cpufreq_driver;
     6.5  
     6.6  /*********************************************************************
     6.7 + *                    Px STATISTIC INFO                              *
     6.8 + *********************************************************************/
     6.9 +
    6.10 +void px_statistic_update(cpumask_t cpumask, uint8_t from, uint8_t to)
    6.11 +{
    6.12 +    uint32_t i;
    6.13 +    uint64_t now;
    6.14 +
    6.15 +    now = NOW();
    6.16 +
    6.17 +    for_each_cpu_mask(i, cpumask) {
    6.18 +        struct pm_px *pxpt = &px_statistic_data[i];
    6.19 +        uint32_t statnum = processor_pminfo[i].perf.state_count;
    6.20 +
    6.21 +        pxpt->u.last = from;
    6.22 +        pxpt->u.cur = to;
    6.23 +        pxpt->u.pt[to].count++;
    6.24 +        pxpt->u.pt[from].residency += now - pxpt->prev_state_wall;
    6.25 +
    6.26 +        (*(pxpt->u.trans_pt + from*statnum + to))++;
    6.27 +
    6.28 +        pxpt->prev_state_wall = now;
    6.29 +    }
    6.30 +}
    6.31 +
    6.32 +int px_statistic_init(int cpuid)
    6.33 +{
    6.34 +    uint32_t i, count;
    6.35 +    struct pm_px *pxpt = &px_statistic_data[cpuid];
    6.36 +    struct processor_pminfo *pmpt = &processor_pminfo[cpuid];
    6.37 +
    6.38 +    count = pmpt->perf.state_count;
    6.39 +
    6.40 +    pxpt->u.trans_pt = xmalloc_array(uint64_t, count * count);
    6.41 +    if (!pxpt->u.trans_pt)
    6.42 +        return -ENOMEM;
    6.43 +
    6.44 +    pxpt->u.pt = xmalloc_array(struct pm_px_val, count);
    6.45 +    if (!pxpt->u.pt) {
    6.46 +        xfree(pxpt->u.trans_pt);
    6.47 +        return -ENOMEM;
    6.48 +    }
    6.49 +
    6.50 +    memset(pxpt->u.trans_pt, 0, count * count * (sizeof(uint64_t)));
    6.51 +    memset(pxpt->u.pt, 0, count * (sizeof(struct pm_px_val)));
    6.52 +
    6.53 +    pxpt->u.total = pmpt->perf.state_count;
    6.54 +    pxpt->u.usable = pmpt->perf.state_count - pmpt->perf.ppc;
    6.55 +
    6.56 +    for (i=0; i < pmpt->perf.state_count; i++)
    6.57 +        pxpt->u.pt[i].freq = pmpt->perf.states[i].core_frequency;
    6.58 +
    6.59 +    pxpt->prev_state_wall = NOW();
    6.60 +
    6.61 +    return 0;
    6.62 +}
    6.63 +
    6.64 +void px_statistic_reset(int cpuid)
    6.65 +{
    6.66 +    uint32_t i, j, count;
    6.67 +    struct pm_px *pxpt = &px_statistic_data[cpuid];
    6.68 +
    6.69 +    count = processor_pminfo[cpuid].perf.state_count;
    6.70 +
    6.71 +    for (i=0; i < count; i++) {
    6.72 +        pxpt->u.pt[i].residency = 0;
    6.73 +        pxpt->u.pt[i].count = 0;
    6.74 +
    6.75 +        for (j=0; j < count; j++)
    6.76 +            *(pxpt->u.trans_pt + i*count + j) = 0;
    6.77 +    }
    6.78 +
    6.79 +    pxpt->prev_state_wall = NOW();
    6.80 +}
    6.81 +
    6.82 +
    6.83 +/*********************************************************************
    6.84   *                   FREQUENCY TABLE HELPERS                         *
    6.85   *********************************************************************/
    6.86  
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/xen/arch/x86/acpi/pmstat.c	Fri May 16 09:37:19 2008 +0100
     7.3 @@ -0,0 +1,110 @@
     7.4 +/*****************************************************************************
     7.5 +#  pmstat.c - Power Management statistic information (Px/Cx/Tx, etc.)
     7.6 +#
     7.7 +#  Copyright (c) 2008, Liu Jinsong <jinsong.liu@intel.com>
     7.8 +#
     7.9 +# This program is free software; you can redistribute it and/or modify it 
    7.10 +# under the terms of the GNU General Public License as published by the Free 
    7.11 +# Software Foundation; either version 2 of the License, or (at your option) 
    7.12 +# any later version.
    7.13 +#
    7.14 +# This program is distributed in the hope that it will be useful, but WITHOUT 
    7.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
    7.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
    7.17 +# more details.
    7.18 +#
    7.19 +# You should have received a copy of the GNU General Public License along with
    7.20 +# this program; if not, write to the Free Software Foundation, Inc., 59 
    7.21 +# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    7.22 +#
    7.23 +# The full GNU General Public License is included in this distribution in the
    7.24 +# file called LICENSE.
    7.25 +#
    7.26 +*****************************************************************************/
    7.27 +
    7.28 +#include <xen/config.h>
    7.29 +#include <xen/lib.h>
    7.30 +#include <xen/errno.h>
    7.31 +#include <xen/sched.h>
    7.32 +#include <xen/event.h>
    7.33 +#include <xen/irq.h>
    7.34 +#include <xen/iocap.h>
    7.35 +#include <xen/compat.h>
    7.36 +#include <xen/guest_access.h>
    7.37 +#include <asm/current.h>
    7.38 +#include <public/xen.h>
    7.39 +#include <xen/cpumask.h>
    7.40 +#include <asm/processor.h>
    7.41 +#include <xen/percpu.h>
    7.42 +
    7.43 +#include <public/sysctl.h>
    7.44 +#include <acpi/cpufreq/cpufreq.h>
    7.45 +
    7.46 +struct pm_px px_statistic_data[NR_CPUS];
    7.47 +
    7.48 +int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
    7.49 +{
    7.50 +    int ret = 0;
    7.51 +    struct pm_px *pxpt = &px_statistic_data[op->cpuid];
    7.52 +    struct processor_pminfo *pmpt = &processor_pminfo[op->cpuid];
    7.53 +
    7.54 +    /* to protect the case when Px was controlled by dom0-kernel */
    7.55 +    /* or when CPU_FREQ not set in which case ACPI Px objects not parsed */
    7.56 +    if ( !pmpt->perf.init )
    7.57 +        return -EINVAL;
    7.58 +
    7.59 +    if ( !cpu_online(op->cpuid) )
    7.60 +        return -EINVAL;
    7.61 +
    7.62 +    switch( op->type )
    7.63 +    {
    7.64 +    case PMSTAT_get_max_px:
    7.65 +    {
    7.66 +        op->u.getpx.total = pmpt->perf.state_count;
    7.67 +        break;
    7.68 +    }
    7.69 +
    7.70 +    case PMSTAT_get_pxstat:
    7.71 +    {
    7.72 +        uint64_t now, ct;
    7.73 +
    7.74 +        now = NOW();
    7.75 +        pxpt->u.usable = pmpt->perf.state_count - pmpt->perf.ppc;
    7.76 +        pxpt->u.pt[pxpt->u.cur].residency += now - pxpt->prev_state_wall;
    7.77 +        pxpt->prev_state_wall = now;
    7.78 +
    7.79 +        ct = pmpt->perf.state_count;
    7.80 +        if ( copy_to_guest(op->u.getpx.trans_pt, pxpt->u.trans_pt, ct*ct) )
    7.81 +        {
    7.82 +            ret = -EFAULT;
    7.83 +            break;
    7.84 +        }
    7.85 +
    7.86 +        if ( copy_to_guest(op->u.getpx.pt, pxpt->u.pt, ct) )
    7.87 +        {
    7.88 +            ret = -EFAULT;
    7.89 +            break;
    7.90 +        }
    7.91 +
    7.92 +        op->u.getpx.total = pxpt->u.total;
    7.93 +        op->u.getpx.usable = pxpt->u.usable;
    7.94 +        op->u.getpx.last = pxpt->u.last;
    7.95 +        op->u.getpx.cur = pxpt->u.cur;
    7.96 +
    7.97 +        break;
    7.98 +    }
    7.99 +
   7.100 +    case PMSTAT_reset_pxstat:
   7.101 +    {
   7.102 +        px_statistic_reset(op->cpuid);
   7.103 +        break;
   7.104 +    }
   7.105 +
   7.106 +    default:
   7.107 +        printk("not defined sub-hypercall @ do_get_pm_info\n");
   7.108 +        ret = -ENOSYS;
   7.109 +        break;
   7.110 +    }
   7.111 +
   7.112 +    return ret;
   7.113 +}
     8.1 --- a/xen/arch/x86/platform_hypercall.c	Fri May 16 09:31:03 2008 +0100
     8.2 +++ b/xen/arch/x86/platform_hypercall.c	Fri May 16 09:37:19 2008 +0100
     8.3 @@ -403,7 +403,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
     8.4  
     8.5              if ( xenpxpt->flags == ( XEN_PX_PCT | XEN_PX_PSS | 
     8.6                  XEN_PX_PSD | XEN_PX_PPC ) )
     8.7 +            {
     8.8 +                pxpt->init =1;
     8.9                  cpu_count++;
    8.10 +            }
    8.11              if ( cpu_count == num_online_cpus() )
    8.12                  ret = acpi_cpufreq_init();
    8.13              break;
     9.1 --- a/xen/common/sysctl.c	Fri May 16 09:31:03 2008 +0100
     9.2 +++ b/xen/common/sysctl.c	Fri May 16 09:37:19 2008 +0100
     9.3 @@ -25,6 +25,8 @@
     9.4  #include <xen/nodemask.h>
     9.5  #include <xsm/xsm.h>
     9.6  
     9.7 +extern int do_get_pm_info(struct xen_sysctl_get_pmstat *op);
     9.8 +
     9.9  extern long arch_do_sysctl(
    9.10      struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
    9.11  
    9.12 @@ -196,6 +198,20 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
    9.13      }
    9.14      break;
    9.15  
    9.16 +    case XEN_SYSCTL_get_pmstat:
    9.17 +    {
    9.18 +        ret = do_get_pm_info(&op->u.get_pmstat);
    9.19 +        if ( ret )
    9.20 +            break;
    9.21 +
    9.22 +        if ( copy_to_guest(u_sysctl, op, 1) )
    9.23 +        {
    9.24 +            ret = -EFAULT;
    9.25 +            break;
    9.26 +        }
    9.27 +    }
    9.28 +    break;
    9.29 +
    9.30      default:
    9.31          ret = arch_do_sysctl(op, u_sysctl);
    9.32          break;
    10.1 --- a/xen/include/acpi/cpufreq/processor_perf.h	Fri May 16 09:31:03 2008 +0100
    10.2 +++ b/xen/include/acpi/cpufreq/processor_perf.h	Fri May 16 09:37:19 2008 +0100
    10.3 @@ -2,9 +2,13 @@
    10.4  #define __XEN_PROCESSOR_PM_H__
    10.5  
    10.6  #include <public/platform.h>
    10.7 +#include <public/sysctl.h>
    10.8  
    10.9  int get_cpu_id(u8);
   10.10  int acpi_cpufreq_init(void);
   10.11 +void px_statistic_update(cpumask_t, uint8_t, uint8_t);
   10.12 +int  px_statistic_init(int);
   10.13 +void px_statistic_reset(int);
   10.14  
   10.15  struct processor_performance {
   10.16      uint32_t state;
   10.17 @@ -16,15 +20,32 @@ struct processor_performance {
   10.18      struct xen_psd_package domain_info;
   10.19      cpumask_t shared_cpu_map;
   10.20      uint32_t shared_type;
   10.21 +
   10.22 +    uint32_t init;
   10.23  };
   10.24  
   10.25  struct processor_pminfo {
   10.26      uint32_t acpi_id;
   10.27      uint32_t id;
   10.28 -    uint32_t flag;
   10.29      struct processor_performance    perf;
   10.30  };
   10.31  
   10.32  extern struct processor_pminfo processor_pminfo[NR_CPUS];
   10.33  
   10.34 +struct px_stat {
   10.35 +    uint8_t total;        /* total Px states */
   10.36 +    uint8_t usable;       /* usable Px states */
   10.37 +    uint8_t last;         /* last Px state */
   10.38 +    uint8_t cur;          /* current Px state */
   10.39 +    uint64_t *trans_pt;   /* Px transition table */
   10.40 +    pm_px_val_t *pt;
   10.41 +};
   10.42 +
   10.43 +struct pm_px {
   10.44 +    struct px_stat u;
   10.45 +    uint64_t prev_state_wall;
   10.46 +};
   10.47 +
   10.48 +extern struct pm_px px_statistic_data[NR_CPUS];
   10.49 +
   10.50  #endif /* __XEN_PROCESSOR_PM_H__ */
    11.1 --- a/xen/include/public/sysctl.h	Fri May 16 09:31:03 2008 +0100
    11.2 +++ b/xen/include/public/sysctl.h	Fri May 16 09:37:19 2008 +0100
    11.3 @@ -212,7 +212,41 @@ struct xen_sysctl_availheap {
    11.4  };
    11.5  typedef struct xen_sysctl_availheap xen_sysctl_availheap_t;
    11.6  DEFINE_XEN_GUEST_HANDLE(xen_sysctl_availheap_t);
    11.7 - 
    11.8 +
    11.9 +#define XEN_SYSCTL_get_pmstat        10
   11.10 +struct pm_px_val {
   11.11 +    uint64_aligned_t freq;        /* Px core frequency */
   11.12 +    uint64_aligned_t residency;   /* Px residency time */
   11.13 +    uint64_aligned_t count;       /* Px transition count */
   11.14 +};
   11.15 +typedef struct pm_px_val pm_px_val_t;
   11.16 +DEFINE_XEN_GUEST_HANDLE(pm_px_val_t);
   11.17 +
   11.18 +struct pm_px_stat {
   11.19 +    uint8_t total;        /* total Px states */
   11.20 +    uint8_t usable;       /* usable Px states */
   11.21 +    uint8_t last;         /* last Px state */
   11.22 +    uint8_t cur;          /* current Px state */
   11.23 +    XEN_GUEST_HANDLE_64(uint64) trans_pt;   /* Px transition table */
   11.24 +    XEN_GUEST_HANDLE_64(pm_px_val_t) pt;
   11.25 +};
   11.26 +typedef struct pm_px_stat pm_px_stat_t;
   11.27 +DEFINE_XEN_GUEST_HANDLE(pm_px_stat_t);
   11.28 +
   11.29 +struct xen_sysctl_get_pmstat {
   11.30 +#define PMSTAT_get_max_px   0x11
   11.31 +#define PMSTAT_get_pxstat   0x12
   11.32 +#define PMSTAT_reset_pxstat 0x13
   11.33 +    uint32_t type;
   11.34 +    uint32_t cpuid;
   11.35 +    union {
   11.36 +        struct pm_px_stat getpx;
   11.37 +        /* other struct for cx, tx, etc */
   11.38 +    } u;
   11.39 +};
   11.40 +typedef struct xen_sysctl_get_pmstat xen_sysctl_get_pmstat_t;
   11.41 +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_get_pmstat_t);
   11.42 +
   11.43  struct xen_sysctl {
   11.44      uint32_t cmd;
   11.45      uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
   11.46 @@ -226,6 +260,7 @@ struct xen_sysctl {
   11.47          struct xen_sysctl_debug_keys        debug_keys;
   11.48          struct xen_sysctl_getcpuinfo        getcpuinfo;
   11.49          struct xen_sysctl_availheap         availheap;
   11.50 +        struct xen_sysctl_get_pmstat        get_pmstat;
   11.51          uint8_t                             pad[128];
   11.52      } u;
   11.53  };