[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Add statistic interface for cx.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1211363989 -3600 # Node ID ef019d230080cc1c85a3a9a79c170f898db6be53 # Parent b9735935a69e49e4caaed8844a50a227bd0725c7 Add statistic interface for cx. Implement statistic interface for cx via sysctl & libxc. Provide a easy way to collect processor cx info within dom0. Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx> --- tools/libxc/xc_pm.c | 68 +++++++++++++++++++++++++++++++++++++++++++ tools/libxc/xenctrl.h | 13 ++++++++ xen/arch/x86/acpi/cpu_idle.c | 39 ++++++++++++++++++++++++ xen/arch/x86/acpi/pmstat.c | 25 +++++++++++++++ xen/include/public/sysctl.h | 23 ++++++++++++-- 5 files changed, 163 insertions(+), 5 deletions(-) diff -r b9735935a69e -r ef019d230080 tools/libxc/xc_pm.c --- a/tools/libxc/xc_pm.c Wed May 21 10:59:00 2008 +0100 +++ b/tools/libxc/xc_pm.c Wed May 21 10:59:49 2008 +0100 @@ -99,3 +99,71 @@ int xc_pm_reset_pxstat(int xc_handle, in return xc_sysctl(xc_handle, &sysctl); } + +int xc_pm_get_max_cx(int xc_handle, int cpuid, int *max_cx) +{ + DECLARE_SYSCTL; + int ret = 0; + + sysctl.cmd = XEN_SYSCTL_get_pmstat; + sysctl.u.get_pmstat.type = PMSTAT_get_max_cx; + sysctl.u.get_pmstat.cpuid = cpuid; + if ( (ret = xc_sysctl(xc_handle, &sysctl)) != 0 ) + return ret; + + *max_cx = sysctl.u.get_pmstat.u.getcx.nr; + return ret; +} + +int xc_pm_get_cxstat(int xc_handle, int cpuid, struct xc_cx_stat *cxpt) +{ + DECLARE_SYSCTL; + int max_cx, ret; + + if( !cxpt || !(cxpt->triggers) || !(cxpt->residencies) ) + return -EINVAL; + + if ( (ret = xc_pm_get_max_cx(xc_handle, cpuid, &max_cx)) ) + goto unlock_0; + + if ( (ret = lock_pages(cxpt, sizeof(struct xc_cx_stat))) ) + goto unlock_0; + if ( (ret = lock_pages(cxpt->triggers, max_cx * sizeof(uint64_t))) ) + goto unlock_1; + if ( (ret = lock_pages(cxpt->residencies, max_cx * sizeof(uint64_t))) ) + goto unlock_2; + + sysctl.cmd = XEN_SYSCTL_get_pmstat; + sysctl.u.get_pmstat.type = PMSTAT_get_cxstat; + sysctl.u.get_pmstat.cpuid = cpuid; + set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.triggers, cxpt->triggers); + set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.residencies, + cxpt->residencies); + + if ( (ret = xc_sysctl(xc_handle, &sysctl)) ) + goto unlock_3; + + cxpt->nr = sysctl.u.get_pmstat.u.getcx.nr; + cxpt->last = sysctl.u.get_pmstat.u.getcx.last; + cxpt->idle_time = sysctl.u.get_pmstat.u.getcx.idle_time; + +unlock_3: + unlock_pages(cxpt->residencies, max_cx * sizeof(uint64_t)); +unlock_2: + unlock_pages(cxpt->triggers, max_cx * sizeof(uint64_t)); +unlock_1: + unlock_pages(cxpt, sizeof(struct xc_cx_stat)); +unlock_0: + return ret; +} + +int xc_pm_reset_cxstat(int xc_handle, int cpuid) +{ + DECLARE_SYSCTL; + + sysctl.cmd = XEN_SYSCTL_get_pmstat; + sysctl.u.get_pmstat.type = PMSTAT_reset_cxstat; + sysctl.u.get_pmstat.cpuid = cpuid; + + return xc_sysctl(xc_handle, &sysctl); +} diff -r b9735935a69e -r ef019d230080 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Wed May 21 10:59:00 2008 +0100 +++ b/tools/libxc/xenctrl.h Wed May 21 10:59:49 2008 +0100 @@ -1053,4 +1053,17 @@ int xc_pm_get_pxstat(int xc_handle, int int xc_pm_get_pxstat(int xc_handle, int cpuid, struct xc_px_stat *pxpt); int xc_pm_reset_pxstat(int xc_handle, int cpuid); +struct xc_cx_stat { + uint32_t nr; /* entry nr in triggers & residencies, including C0 */ + uint32_t last; /* last Cx state */ + uint64_t idle_time; /* idle time from boot */ + uint64_t *triggers; /* Cx trigger counts */ + uint64_t *residencies; /* Cx residencies */ +}; +typedef struct xc_cx_stat xc_cx_stat_t; + +int xc_pm_get_max_cx(int xc_handle, int cpuid, int *max_cx); +int xc_pm_get_cxstat(int xc_handle, int cpuid, struct xc_cx_stat *cxpt); +int xc_pm_reset_cxstat(int xc_handle, int cpuid); + #endif /* XENCTRL_H */ diff -r b9735935a69e -r ef019d230080 xen/arch/x86/acpi/cpu_idle.c --- a/xen/arch/x86/acpi/cpu_idle.c Wed May 21 10:59:00 2008 +0100 +++ b/xen/arch/x86/acpi/cpu_idle.c Wed May 21 10:59:49 2008 +0100 @@ -44,6 +44,7 @@ #include <asm/hpet.h> #include <asm/processor.h> #include <public/platform.h> +#include <public/sysctl.h> #define DEBUG_PM_CX @@ -940,3 +941,41 @@ long set_cx_pminfo(uint32_t cpu, struct return 0; } + +uint32_t pmstat_get_cx_nr(uint32_t cpuid) +{ + return processor_powers[cpuid].count; +} + +int pmstat_get_cx_stat(uint32_t cpuid, struct pm_cx_stat *stat) +{ + struct acpi_processor_power *power = &processor_powers[cpuid]; + struct vcpu *v = idle_vcpu[cpuid]; + uint64_t usage; + int i; + + stat->last = (power->state) ? power->state->type : 0; + stat->nr = processor_powers[cpuid].count; + stat->idle_time = v->runstate.time[RUNSTATE_running]; + if ( v->is_running ) + stat->idle_time += NOW() - v->runstate.state_entry_time; + + for ( i = 0; i < power->count; i++ ) + { + usage = power->states[i].usage; + if ( copy_to_guest_offset(stat->triggers, i, &usage, 1) ) + return -EFAULT; + } + for ( i = 0; i < power->count; i++ ) + if ( copy_to_guest_offset(stat->residencies, i, + &power->states[i].time, 1) ) + return -EFAULT; + + return 0; +} + +int pmstat_reset_cx_stat(uint32_t cpuid) +{ + return 0; +} + diff -r b9735935a69e -r ef019d230080 xen/arch/x86/acpi/pmstat.c --- a/xen/arch/x86/acpi/pmstat.c Wed May 21 10:59:00 2008 +0100 +++ b/xen/arch/x86/acpi/pmstat.c Wed May 21 10:59:49 2008 +0100 @@ -42,6 +42,10 @@ struct pm_px px_statistic_data[NR_CPUS]; +extern uint32_t pmstat_get_cx_nr(uint32_t cpuid); +extern int pmstat_get_cx_stat(uint32_t cpuid, struct pm_cx_stat *stat); +extern int pmstat_reset_cx_stat(uint32_t cpuid); + int do_get_pm_info(struct xen_sysctl_get_pmstat *op) { int ret = 0; @@ -50,7 +54,7 @@ int do_get_pm_info(struct xen_sysctl_get /* to protect the case when Px was controlled by dom0-kernel */ /* or when CPU_FREQ not set in which case ACPI Px objects not parsed */ - if ( !pmpt->perf.init ) + if ( !pmpt->perf.init && (op->type & PMSTAT_CATEGORY_MASK) == PMSTAT_PX ) return -EINVAL; if ( !cpu_online(op->cpuid) ) @@ -100,6 +104,25 @@ int do_get_pm_info(struct xen_sysctl_get break; } + case PMSTAT_get_max_cx: + { + op->u.getcx.nr = pmstat_get_cx_nr(op->cpuid); + ret = 0; + break; + } + + case PMSTAT_get_cxstat: + { + ret = pmstat_get_cx_stat(op->cpuid, &op->u.getcx); + break; + } + + case PMSTAT_reset_cxstat: + { + ret = pmstat_reset_cx_stat(op->cpuid); + break; + } + default: printk("not defined sub-hypercall @ do_get_pm_info\n"); ret = -ENOSYS; diff -r b9735935a69e -r ef019d230080 xen/include/public/sysctl.h --- a/xen/include/public/sysctl.h Wed May 21 10:59:00 2008 +0100 +++ b/xen/include/public/sysctl.h Wed May 21 10:59:49 2008 +0100 @@ -233,15 +233,30 @@ typedef struct pm_px_stat pm_px_stat_t; typedef struct pm_px_stat pm_px_stat_t; DEFINE_XEN_GUEST_HANDLE(pm_px_stat_t); +struct pm_cx_stat { + uint32_t nr; /* entry nr in triggers & residencies, including C0 */ + uint32_t last; /* last Cx state */ + uint64_aligned_t idle_time; /* idle time from boot */ + XEN_GUEST_HANDLE_64(uint64) triggers; /* Cx trigger counts */ + XEN_GUEST_HANDLE_64(uint64) residencies; /* Cx residencies */ +}; + struct xen_sysctl_get_pmstat { -#define PMSTAT_get_max_px 0x11 -#define PMSTAT_get_pxstat 0x12 -#define PMSTAT_reset_pxstat 0x13 +#define PMSTAT_CATEGORY_MASK 0xf0 +#define PMSTAT_PX 0x10 +#define PMSTAT_CX 0x20 +#define PMSTAT_get_max_px (PMSTAT_PX | 0x1) +#define PMSTAT_get_pxstat (PMSTAT_PX | 0x2) +#define PMSTAT_reset_pxstat (PMSTAT_PX | 0x3) +#define PMSTAT_get_max_cx (PMSTAT_CX | 0x1) +#define PMSTAT_get_cxstat (PMSTAT_CX | 0x2) +#define PMSTAT_reset_cxstat (PMSTAT_CX | 0x3) uint32_t type; uint32_t cpuid; union { struct pm_px_stat getpx; - /* other struct for cx, tx, etc */ + struct pm_cx_stat getcx; + /* other struct for tx, etc */ } u; }; typedef struct xen_sysctl_get_pmstat xen_sysctl_get_pmstat_t; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |