404 lines
14 KiB
Diff
404 lines
14 KiB
Diff
Index: xen-3.3.1-testing/xen/arch/x86/acpi/cpufreq/cpufreq.c
|
|
===================================================================
|
|
--- xen-3.3.1-testing.orig/xen/arch/x86/acpi/cpufreq/cpufreq.c
|
|
+++ xen-3.3.1-testing/xen/arch/x86/acpi/cpufreq/cpufreq.c
|
|
@@ -44,7 +44,7 @@
|
|
#include <acpi/acpi.h>
|
|
#include <acpi/cpufreq/cpufreq.h>
|
|
|
|
-struct processor_pminfo processor_pminfo[NR_CPUS];
|
|
+struct processor_pminfo *__read_mostly processor_pminfo[NR_CPUS];
|
|
struct cpufreq_policy xen_px_policy[NR_CPUS];
|
|
|
|
static cpumask_t *cpufreq_dom_pt;
|
|
@@ -436,7 +436,7 @@ acpi_cpufreq_cpu_init(struct cpufreq_pol
|
|
|
|
drv_data[cpu] = data;
|
|
|
|
- data->acpi_data = &processor_pminfo[cpu].perf;
|
|
+ data->acpi_data = &processor_pminfo[cpu]->perf;
|
|
|
|
perf = data->acpi_data;
|
|
policy->shared_type = perf->shared_type;
|
|
@@ -575,8 +575,8 @@ int cpufreq_dom_init(void)
|
|
cpufreq_dom_max = 0;
|
|
|
|
for_each_online_cpu(i) {
|
|
- if (cpufreq_dom_max < processor_pminfo[i].perf.domain_info.domain)
|
|
- cpufreq_dom_max = processor_pminfo[i].perf.domain_info.domain;
|
|
+ if (cpufreq_dom_max < processor_pminfo[i]->perf.domain_info.domain)
|
|
+ cpufreq_dom_max = processor_pminfo[i]->perf.domain_info.domain;
|
|
}
|
|
cpufreq_dom_max++;
|
|
|
|
@@ -592,13 +592,13 @@ int cpufreq_dom_init(void)
|
|
memset(cpufreq_dom_pt, 0, cpufreq_dom_max * sizeof(cpumask_t));
|
|
|
|
for_each_online_cpu(i) {
|
|
- __set_bit(processor_pminfo[i].perf.domain_info.domain, cpufreq_dom_mask);
|
|
- cpu_set(i, cpufreq_dom_pt[processor_pminfo[i].perf.domain_info.domain]);
|
|
+ __set_bit(processor_pminfo[i]->perf.domain_info.domain, cpufreq_dom_mask);
|
|
+ cpu_set(i, cpufreq_dom_pt[processor_pminfo[i]->perf.domain_info.domain]);
|
|
}
|
|
|
|
for_each_online_cpu(i)
|
|
- processor_pminfo[i].perf.shared_cpu_map =
|
|
- cpufreq_dom_pt[processor_pminfo[i].perf.domain_info.domain];
|
|
+ processor_pminfo[i]->perf.shared_cpu_map =
|
|
+ cpufreq_dom_pt[processor_pminfo[i]->perf.domain_info.domain];
|
|
|
|
return 0;
|
|
}
|
|
Index: xen-3.3.1-testing/xen/arch/x86/acpi/cpufreq/powernow.c
|
|
===================================================================
|
|
--- xen-3.3.1-testing.orig/xen/arch/x86/acpi/cpufreq/powernow.c
|
|
+++ xen-3.3.1-testing/xen/arch/x86/acpi/cpufreq/powernow.c
|
|
@@ -49,9 +49,6 @@
|
|
#define MSR_PSTATE_CTRL 0xc0010062 /* Pstate control MSR */
|
|
#define MSR_PSTATE_CUR_LIMIT 0xc0010061 /* pstate current limit MSR */
|
|
|
|
-extern struct processor_pminfo processor_pminfo[NR_CPUS];
|
|
-extern struct cpufreq_policy xen_px_policy[NR_CPUS];
|
|
-
|
|
struct powernow_cpufreq_data {
|
|
struct processor_performance *acpi_data;
|
|
struct cpufreq_frequency_table *freq_table;
|
|
@@ -149,7 +146,7 @@ static int powernow_cpufreq_cpu_init(str
|
|
|
|
drv_data[cpu] = data;
|
|
|
|
- data->acpi_data = &processor_pminfo[cpu].perf;
|
|
+ data->acpi_data = &processor_pminfo[cpu]->perf;
|
|
|
|
perf = data->acpi_data;
|
|
policy->shared_type = perf->shared_type;
|
|
@@ -271,8 +268,8 @@ int powernow_cpufreq_init(void)
|
|
}
|
|
if (ret)
|
|
return ret;
|
|
- if (max_dom < processor_pminfo[i].perf.domain_info.domain)
|
|
- max_dom = processor_pminfo[i].perf.domain_info.domain;
|
|
+ if (max_dom < processor_pminfo[i]->perf.domain_info.domain)
|
|
+ max_dom = processor_pminfo[i]->perf.domain_info.domain;
|
|
}
|
|
max_dom++;
|
|
|
|
@@ -288,13 +285,13 @@ int powernow_cpufreq_init(void)
|
|
|
|
/* get cpumask of each psd domain */
|
|
for_each_online_cpu(i) {
|
|
- __set_bit(processor_pminfo[i].perf.domain_info.domain, dom_mask);
|
|
- cpu_set(i, pt[processor_pminfo[i].perf.domain_info.domain]);
|
|
+ __set_bit(processor_pminfo[i]->perf.domain_info.domain, dom_mask);
|
|
+ cpu_set(i, pt[processor_pminfo[i]->perf.domain_info.domain]);
|
|
}
|
|
|
|
for_each_online_cpu(i)
|
|
- processor_pminfo[i].perf.shared_cpu_map =
|
|
- pt[processor_pminfo[i].perf.domain_info.domain];
|
|
+ processor_pminfo[i]->perf.shared_cpu_map =
|
|
+ pt[processor_pminfo[i]->perf.domain_info.domain];
|
|
|
|
cpufreq_driver = &powernow_cpufreq_driver;
|
|
|
|
Index: xen-3.3.1-testing/xen/arch/x86/acpi/cpufreq/utility.c
|
|
===================================================================
|
|
--- xen-3.3.1-testing.orig/xen/arch/x86/acpi/cpufreq/utility.c
|
|
+++ xen-3.3.1-testing/xen/arch/x86/acpi/cpufreq/utility.c
|
|
@@ -45,10 +45,12 @@ void px_statistic_suspend(void)
|
|
now = NOW();
|
|
|
|
for_each_online_cpu(cpu) {
|
|
- struct pm_px *pxpt = &px_statistic_data[cpu];
|
|
+ struct pm_px *pxpt = px_statistic_data[cpu];
|
|
uint64_t total_idle_ns;
|
|
uint64_t tmp_idle_ns;
|
|
|
|
+ if ( !pxpt || !pxpt->u.pt )
|
|
+ continue;
|
|
total_idle_ns = get_cpu_idle_time(cpu);
|
|
tmp_idle_ns = total_idle_ns - pxpt->prev_idle_wall;
|
|
|
|
@@ -66,7 +68,10 @@ void px_statistic_resume(void)
|
|
now = NOW();
|
|
|
|
for_each_online_cpu(cpu) {
|
|
- struct pm_px *pxpt = &px_statistic_data[cpu];
|
|
+ struct pm_px *pxpt = px_statistic_data[cpu];
|
|
+
|
|
+ if ( !pxpt )
|
|
+ continue;
|
|
pxpt->prev_state_wall = now;
|
|
pxpt->prev_idle_wall = get_cpu_idle_time(cpu);
|
|
}
|
|
@@ -80,11 +85,14 @@ void px_statistic_update(cpumask_t cpuma
|
|
now = NOW();
|
|
|
|
for_each_cpu_mask(i, cpumask) {
|
|
- struct pm_px *pxpt = &px_statistic_data[i];
|
|
- uint32_t statnum = processor_pminfo[i].perf.state_count;
|
|
+ struct pm_px *pxpt = px_statistic_data[i];
|
|
+ struct processor_pminfo *pmpt = processor_pminfo[i];
|
|
uint64_t total_idle_ns;
|
|
uint64_t tmp_idle_ns;
|
|
|
|
+ if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt || !pmpt )
|
|
+ continue;
|
|
+
|
|
total_idle_ns = get_cpu_idle_time(i);
|
|
tmp_idle_ns = total_idle_ns - pxpt->prev_idle_wall;
|
|
|
|
@@ -94,7 +102,7 @@ void px_statistic_update(cpumask_t cpuma
|
|
pxpt->u.pt[from].residency += now - pxpt->prev_state_wall;
|
|
pxpt->u.pt[from].residency -= tmp_idle_ns;
|
|
|
|
- (*(pxpt->u.trans_pt + from*statnum + to))++;
|
|
+ (*(pxpt->u.trans_pt + from * pmpt->perf.state_count + to))++;
|
|
|
|
pxpt->prev_state_wall = now;
|
|
pxpt->prev_idle_wall = total_idle_ns;
|
|
@@ -104,11 +112,23 @@ void px_statistic_update(cpumask_t cpuma
|
|
int px_statistic_init(int cpuid)
|
|
{
|
|
uint32_t i, count;
|
|
- struct pm_px *pxpt = &px_statistic_data[cpuid];
|
|
- struct processor_pminfo *pmpt = &processor_pminfo[cpuid];
|
|
+ struct pm_px *pxpt = px_statistic_data[cpuid];
|
|
+ const struct processor_pminfo *pmpt = processor_pminfo[cpuid];
|
|
+
|
|
+ if ( !pmpt )
|
|
+ return -EINVAL;
|
|
|
|
count = pmpt->perf.state_count;
|
|
|
|
+ if ( !pxpt )
|
|
+ {
|
|
+ pxpt = xmalloc(struct pm_px);
|
|
+ if ( !pxpt )
|
|
+ return -ENOMEM;
|
|
+ memset(pxpt, 0, sizeof(*pxpt));
|
|
+ px_statistic_data[cpuid] = pxpt;
|
|
+ }
|
|
+
|
|
pxpt->u.trans_pt = xmalloc_array(uint64_t, count * count);
|
|
if (!pxpt->u.trans_pt)
|
|
return -ENOMEM;
|
|
@@ -137,9 +157,13 @@ int px_statistic_init(int cpuid)
|
|
void px_statistic_reset(int cpuid)
|
|
{
|
|
uint32_t i, j, count;
|
|
- struct pm_px *pxpt = &px_statistic_data[cpuid];
|
|
+ struct pm_px *pxpt = px_statistic_data[cpuid];
|
|
+ const struct processor_pminfo *pmpt = processor_pminfo[cpuid];
|
|
|
|
- count = processor_pminfo[cpuid].perf.state_count;
|
|
+ if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt || !pmpt )
|
|
+ return;
|
|
+
|
|
+ count = pmpt->perf.state_count;
|
|
|
|
for (i=0; i < count; i++) {
|
|
pxpt->u.pt[i].residency = 0;
|
|
@@ -298,9 +322,9 @@ void cpufreq_suspend(void)
|
|
|
|
/* to protect the case when Px was not controlled by xen */
|
|
for_each_online_cpu(cpu) {
|
|
- struct processor_performance *perf = &processor_pminfo[cpu].perf;
|
|
+ const struct processor_pminfo *pmpt = processor_pminfo[cpu];
|
|
|
|
- if (!(perf->init & XEN_PX_INIT))
|
|
+ if (!pmpt || !(pmpt->perf.init & XEN_PX_INIT))
|
|
return;
|
|
}
|
|
|
|
@@ -318,10 +342,11 @@ int cpufreq_resume(void)
|
|
/* 1. to protect the case when Px was not controlled by xen */
|
|
/* 2. set state and resume flag to sync cpu to right state and freq */
|
|
for_each_online_cpu(cpu) {
|
|
- struct processor_performance *perf = &processor_pminfo[cpu].perf;
|
|
+ struct processor_pminfo *pmpt = processor_pminfo[cpu];
|
|
+ struct processor_performance *perf = &pmpt->perf;
|
|
struct cpufreq_policy *policy = &xen_px_policy[cpu];
|
|
|
|
- if (!(perf->init & XEN_PX_INIT))
|
|
+ if (!pmpt || !(perf->init & XEN_PX_INIT))
|
|
goto err;
|
|
perf->state = 0;
|
|
policy->resume = 1;
|
|
Index: xen-3.3.1-testing/xen/arch/x86/acpi/cpu_idle.c
|
|
===================================================================
|
|
--- xen-3.3.1-testing.orig/xen/arch/x86/acpi/cpu_idle.c
|
|
+++ xen-3.3.1-testing/xen/arch/x86/acpi/cpu_idle.c
|
|
@@ -128,7 +128,7 @@ struct acpi_processor_power
|
|
struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
|
|
};
|
|
|
|
-static struct acpi_processor_power processor_powers[NR_CPUS];
|
|
+static struct acpi_processor_power *__read_mostly processor_powers[NR_CPUS];
|
|
|
|
static void print_acpi_power(uint32_t cpu, struct acpi_processor_power *power)
|
|
{
|
|
@@ -162,8 +162,11 @@ static void print_acpi_power(uint32_t cp
|
|
|
|
static void dump_cx(unsigned char key)
|
|
{
|
|
- for( int i = 0; i < num_online_cpus(); i++ )
|
|
- print_acpi_power(i, &processor_powers[i]);
|
|
+ unsigned int cpu;
|
|
+
|
|
+ for_each_online_cpu ( cpu )
|
|
+ if (processor_powers[cpu])
|
|
+ print_acpi_power(cpu, processor_powers[cpu]);
|
|
}
|
|
|
|
static int __init cpu_idle_key_init(void)
|
|
@@ -272,14 +275,12 @@ static struct {
|
|
|
|
static void acpi_processor_idle(void)
|
|
{
|
|
- struct acpi_processor_power *power = NULL;
|
|
+ struct acpi_processor_power *power = processor_powers[smp_processor_id()];
|
|
struct acpi_processor_cx *cx = NULL;
|
|
struct acpi_processor_cx *next_state = NULL;
|
|
int sleep_ticks = 0;
|
|
u32 t1, t2 = 0;
|
|
|
|
- power = &processor_powers[smp_processor_id()];
|
|
-
|
|
/*
|
|
* Interrupts must be disabled during bus mastering calculations and
|
|
* for C2/C3 transitions.
|
|
@@ -292,7 +293,7 @@ static void acpi_processor_idle(void)
|
|
return;
|
|
}
|
|
|
|
- cx = power->state;
|
|
+ cx = power ? power->state : NULL;
|
|
if ( !cx )
|
|
{
|
|
if ( pm_idle_save )
|
|
@@ -949,7 +950,15 @@ long set_cx_pminfo(uint32_t cpu, struct
|
|
return -EFAULT;
|
|
}
|
|
|
|
- acpi_power = &processor_powers[cpu_id];
|
|
+ acpi_power = processor_powers[cpu_id];
|
|
+ if ( !acpi_power )
|
|
+ {
|
|
+ acpi_power = xmalloc(struct acpi_processor_power);
|
|
+ if ( !acpi_power )
|
|
+ return -ENOMEM;
|
|
+ memset(acpi_power, 0, sizeof(*acpi_power));
|
|
+ processor_powers[cpu_id] = acpi_power;
|
|
+ }
|
|
|
|
init_cx_pminfo(acpi_power);
|
|
|
|
@@ -985,18 +994,25 @@ long set_cx_pminfo(uint32_t cpu, struct
|
|
|
|
uint32_t pmstat_get_cx_nr(uint32_t cpuid)
|
|
{
|
|
- return processor_powers[cpuid].count;
|
|
+ return processor_powers[cpuid] ? processor_powers[cpuid]->count : 0;
|
|
}
|
|
|
|
int pmstat_get_cx_stat(uint32_t cpuid, struct pm_cx_stat *stat)
|
|
{
|
|
- struct acpi_processor_power *power = &processor_powers[cpuid];
|
|
+ const struct acpi_processor_power *power = processor_powers[cpuid];
|
|
struct vcpu *v = idle_vcpu[cpuid];
|
|
uint64_t usage;
|
|
int i;
|
|
|
|
+ if ( unlikely(!power) )
|
|
+ {
|
|
+ stat->last = 0;
|
|
+ stat->nr = 0;
|
|
+ stat->idle_time = 0;
|
|
+ return 0;
|
|
+ }
|
|
stat->last = (power->state) ? power->state->type : 0;
|
|
- stat->nr = processor_powers[cpuid].count;
|
|
+ stat->nr = power->count;
|
|
stat->idle_time = v->runstate.time[RUNSTATE_running];
|
|
if ( v->is_running )
|
|
stat->idle_time += NOW() - v->runstate.state_entry_time;
|
|
Index: xen-3.3.1-testing/xen/arch/x86/acpi/pmstat.c
|
|
===================================================================
|
|
--- xen-3.3.1-testing.orig/xen/arch/x86/acpi/pmstat.c
|
|
+++ xen-3.3.1-testing/xen/arch/x86/acpi/pmstat.c
|
|
@@ -41,7 +41,7 @@
|
|
#include <public/sysctl.h>
|
|
#include <acpi/cpufreq/cpufreq.h>
|
|
|
|
-struct pm_px px_statistic_data[NR_CPUS];
|
|
+struct pm_px *__read_mostly 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);
|
|
@@ -55,7 +55,7 @@ int do_get_pm_info(struct xen_sysctl_get
|
|
if ( !op || (op->cpuid >= NR_CPUS) || !cpu_online(op->cpuid) )
|
|
return -EINVAL;
|
|
|
|
- pmpt = &processor_pminfo[op->cpuid];
|
|
+ pmpt = processor_pminfo[op->cpuid];
|
|
|
|
switch ( op->type & PMSTAT_CATEGORY_MASK )
|
|
{
|
|
@@ -86,7 +86,7 @@ int do_get_pm_info(struct xen_sysctl_get
|
|
uint64_t now, ct;
|
|
uint64_t total_idle_ns;
|
|
uint64_t tmp_idle_ns;
|
|
- struct pm_px *pxpt = &px_statistic_data[op->cpuid];
|
|
+ struct pm_px *pxpt = px_statistic_data[op->cpuid];
|
|
|
|
if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt )
|
|
return -ENODATA;
|
|
Index: xen-3.3.1-testing/xen/arch/x86/platform_hypercall.c
|
|
===================================================================
|
|
--- xen-3.3.1-testing.orig/xen/arch/x86/platform_hypercall.c
|
|
+++ xen-3.3.1-testing/xen/arch/x86/platform_hypercall.c
|
|
@@ -364,8 +364,19 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
|
|
ret = -EINVAL;
|
|
break;
|
|
}
|
|
- pmpt = &processor_pminfo[cpuid];
|
|
- pxpt = &processor_pminfo[cpuid].perf;
|
|
+ pmpt = processor_pminfo[cpuid];
|
|
+ if ( !pmpt )
|
|
+ {
|
|
+ pmpt = xmalloc(struct processor_pminfo);
|
|
+ if ( !pmpt )
|
|
+ {
|
|
+ ret = -ENOMEM;
|
|
+ break;
|
|
+ }
|
|
+ memset(pmpt, 0, sizeof(*pmpt));
|
|
+ processor_pminfo[cpuid] = pmpt;
|
|
+ }
|
|
+ pxpt = &pmpt->perf;
|
|
pmpt->acpi_id = xenpmpt->id;
|
|
pmpt->id = cpuid;
|
|
|
|
Index: xen-3.3.1-testing/xen/include/acpi/cpufreq/processor_perf.h
|
|
===================================================================
|
|
--- xen-3.3.1-testing.orig/xen/include/acpi/cpufreq/processor_perf.h
|
|
+++ xen-3.3.1-testing/xen/include/acpi/cpufreq/processor_perf.h
|
|
@@ -44,7 +44,7 @@ struct processor_pminfo {
|
|
struct processor_performance perf;
|
|
};
|
|
|
|
-extern struct processor_pminfo processor_pminfo[NR_CPUS];
|
|
+extern struct processor_pminfo *processor_pminfo[NR_CPUS];
|
|
|
|
struct px_stat {
|
|
uint8_t total; /* total Px states */
|
|
@@ -61,6 +61,6 @@ struct pm_px {
|
|
uint64_t prev_idle_wall;
|
|
};
|
|
|
|
-extern struct pm_px px_statistic_data[NR_CPUS];
|
|
+extern struct pm_px *px_statistic_data[NR_CPUS];
|
|
|
|
#endif /* __XEN_PROCESSOR_PM_H__ */
|