From: Keir Fraser Date: Fri, 19 Dec 2008 14:44:40 +0000 (+0000) Subject: CPUIDLE: adjust cstate statistic interface X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14026^2~6 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=7784d17ecd62bf31eb46d4b44082e71898fd64c7;p=xen.git CPUIDLE: adjust cstate statistic interface 1. change unit of residency, PM ticks -> ns. 2. output C0 usage & residency. Signed-off-by: Wei Gang Signed-off-by: Keir Fraser --- diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c index 348b21d579..c3b19584bc 100644 --- a/tools/misc/xenpm.c +++ b/tools/misc/xenpm.c @@ -108,7 +108,7 @@ static int show_cx_cpuid(int xc_fd, int cpuid) printf("C%d : transition [%020"PRIu64"]\n", i, cxstat->triggers[i]); printf(" residency [%020"PRIu64" ms]\n", - cxstat->residencies[i]*1000000UL/3579/1000000UL); + cxstat->residencies[i]/1000000UL); } free(cxstat->triggers); diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c index bf88f14a78..9d080f6506 100644 --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -71,7 +71,8 @@ static struct acpi_processor_power *__read_mostly processor_powers[NR_CPUS]; static void print_acpi_power(uint32_t cpu, struct acpi_processor_power *power) { - uint32_t i; + uint32_t i, idle_usage = 0; + uint64_t res, idle_res = 0; printk("==cpu%d==\n", cpu); printk("active state:\t\tC%d\n", @@ -81,14 +82,21 @@ static void print_acpi_power(uint32_t cpu, struct acpi_processor_power *power) for ( i = 1; i < power->count; i++ ) { + res = acpi_pm_tick_to_ns(power->states[i].time); + idle_usage += power->states[i].usage; + idle_res += res; + printk((power->last_state && power->last_state->idx == i) ? " *" : " "); printk("C%d:\t", i); printk("type[C%d] ", power->states[i].type); printk("latency[%03d] ", power->states[i].latency); printk("usage[%08d] ", power->states[i].usage); - printk("duration[%"PRId64"]\n", power->states[i].time); + printk("duration[%"PRId64"]\n", res); } + printk(" C0:\tusage[%08d] duration[%"PRId64"]\n", + idle_usage, NOW() - idle_res); + } static void dump_cx(unsigned char key) @@ -749,7 +757,7 @@ uint32_t pmstat_get_cx_nr(uint32_t cpuid) int pmstat_get_cx_stat(uint32_t cpuid, struct pm_cx_stat *stat) { const struct acpi_processor_power *power = processor_powers[cpuid]; - uint64_t usage; + uint64_t usage, res, idle_usage = 0, idle_res = 0; int i; if ( power == NULL ) @@ -764,16 +772,24 @@ int pmstat_get_cx_stat(uint32_t cpuid, struct pm_cx_stat *stat) stat->nr = power->count; stat->idle_time = get_cpu_idle_time(cpuid); - for ( i = 0; i < power->count; i++ ) + for ( i = power->count - 1; i >= 0; i-- ) { - usage = power->states[i].usage; - if ( copy_to_guest_offset(stat->triggers, i, &usage, 1) ) + if ( i != 0 ) + { + usage = power->states[i].usage; + res = acpi_pm_tick_to_ns(power->states[i].time); + idle_usage += usage; + idle_res += res; + } + else + { + usage = idle_usage; + res = NOW() - idle_res; + } + if ( copy_to_guest_offset(stat->triggers, i, &usage, 1) || + copy_to_guest_offset(stat->residencies, i, &res, 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; } diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 289d678651..a642401546 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -531,6 +531,19 @@ static struct platform_timesource plt_pmtimer = .init = init_pmtimer }; +static struct time_scale pmt_scale; +static __init int init_pmtmr_scale(void) +{ + set_time_scale(&pmt_scale, ACPI_PM_FREQUENCY); + return 0; +} +__initcall(init_pmtmr_scale); + +uint64_t acpi_pm_tick_to_ns(uint64_t ticks) +{ + return scale_delta(ticks, &pmt_scale); +} + /************************************************************ * GENERIC PLATFORM TIMER INFRASTRUCTURE */ diff --git a/xen/include/asm-x86/time.h b/xen/include/asm-x86/time.h index 0477f2b2b7..73b06a7246 100644 --- a/xen/include/asm-x86/time.h +++ b/xen/include/asm-x86/time.h @@ -38,4 +38,6 @@ void pit_broadcast_enter(void); void pit_broadcast_exit(void); int pit_broadcast_is_available(void); +uint64_t acpi_pm_tick_to_ns(uint64_t ticks); + #endif /* __X86_TIME_H__ */