[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 01/15] xen/cpufreq: introduces XEN_PM_PSD for solely delivery of _PSD
_PSD(P-State Dependency) provides performance control, no matter legacy P-state or CPPC, logical processor dependency information to OSPM. In order to re-use it for CPPC, this commit extracts the delivery of _PSD info from set_px_pminfo() and wrap it with a new sub-hypercall XEN_PM_PSD. Signed-off-by: Penny Zheng <Penny.Zheng@xxxxxxx> --- v2 -> v3: - new commit --- xen/arch/x86/acpi/cpufreq/acpi.c | 2 +- xen/arch/x86/acpi/cpufreq/powernow.c | 2 +- xen/arch/x86/platform_hypercall.c | 11 ++ xen/arch/x86/x86_64/cpufreq.c | 2 + xen/drivers/cpufreq/cpufreq.c | 122 +++++++++++++--------- xen/drivers/cpufreq/cpufreq_ondemand.c | 2 +- xen/include/acpi/cpufreq/processor_perf.h | 4 +- xen/include/public/platform.h | 17 +-- xen/include/xen/pmstat.h | 2 + xen/include/xlat.lst | 2 +- 10 files changed, 103 insertions(+), 63 deletions(-) diff --git a/xen/arch/x86/acpi/cpufreq/acpi.c b/xen/arch/x86/acpi/cpufreq/acpi.c index 0c25376406..0cf94ab2d6 100644 --- a/xen/arch/x86/acpi/cpufreq/acpi.c +++ b/xen/arch/x86/acpi/cpufreq/acpi.c @@ -393,7 +393,7 @@ static int cf_check acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) data->acpi_data = &processor_pminfo[cpu]->perf; perf = data->acpi_data; - policy->shared_type = perf->shared_type; + policy->shared_type = processor_pminfo[cpu]->shared_type; switch (perf->control_register.space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: diff --git a/xen/arch/x86/acpi/cpufreq/powernow.c b/xen/arch/x86/acpi/cpufreq/powernow.c index 69364e1855..69ad403fc1 100644 --- a/xen/arch/x86/acpi/cpufreq/powernow.c +++ b/xen/arch/x86/acpi/cpufreq/powernow.c @@ -218,7 +218,7 @@ static int cf_check powernow_cpufreq_cpu_init(struct cpufreq_policy *policy) data->acpi_data = &processor_pminfo[cpu]->perf; info.perf = perf = data->acpi_data; - policy->shared_type = perf->shared_type; + policy->shared_type = processor_pminfo[cpu]->shared_type; if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 90abd3197f..b0d98b5840 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -571,6 +571,17 @@ ret_t do_platform_op( ret = acpi_set_pdc_bits(op->u.set_pminfo.id, pdc); break; } + case XEN_PM_PSD: + if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) ) + { + ret = -EOPNOTSUPP; + break; + } + + ret = set_psd_pminfo(op->u.set_pminfo.id, + op->u.set_pminfo.shared_type, + &op->u.set_pminfo.u.domain_info); + break; default: ret = -EINVAL; diff --git a/xen/arch/x86/x86_64/cpufreq.c b/xen/arch/x86/x86_64/cpufreq.c index e4f3d5b436..d1b93b8eef 100644 --- a/xen/arch/x86/x86_64/cpufreq.c +++ b/xen/arch/x86/x86_64/cpufreq.c @@ -28,6 +28,8 @@ CHECK_processor_px; +CHECK_psd_package; + DEFINE_XEN_GUEST_HANDLE(compat_processor_px_t); int compat_set_px_pminfo(uint32_t acpi_id, diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c index 4a103c6de9..638476ca15 100644 --- a/xen/drivers/cpufreq/cpufreq.c +++ b/xen/drivers/cpufreq/cpufreq.c @@ -36,6 +36,7 @@ #include <xen/string.h> #include <xen/timer.h> #include <xen/xmalloc.h> +#include <xen/xvmalloc.h> #include <xen/guest_access.h> #include <xen/domain.h> #include <xen/cpu.h> @@ -201,15 +202,15 @@ int cpufreq_add_cpu(unsigned int cpu) struct cpufreq_dom *cpufreq_dom = NULL; struct cpufreq_policy new_policy; struct cpufreq_policy *policy; - struct processor_performance *perf; + struct processor_pminfo *pmpt; /* to protect the case when Px was not controlled by xen */ if ( !processor_pminfo[cpu] || !cpu_online(cpu) ) return -EINVAL; - perf = &processor_pminfo[cpu]->perf; + pmpt = processor_pminfo[cpu]; - if ( !(perf->init & XEN_PX_INIT) ) + if ( !(pmpt->perf.init & XEN_PX_INIT) ) return -EINVAL; if (!cpufreq_driver.init) @@ -218,10 +219,10 @@ int cpufreq_add_cpu(unsigned int cpu) if (per_cpu(cpufreq_cpu_policy, cpu)) return 0; - if (perf->shared_type == CPUFREQ_SHARED_TYPE_HW) + if (pmpt->shared_type == CPUFREQ_SHARED_TYPE_HW) hw_all = 1; - dom = perf->domain_info.domain; + dom = pmpt->domain_info.domain; list_for_each(pos, &cpufreq_dom_list_head) { cpufreq_dom = list_entry(pos, struct cpufreq_dom, node); @@ -246,18 +247,18 @@ int cpufreq_add_cpu(unsigned int cpu) } else { /* domain sanity check under whatever coordination type */ firstcpu = cpumask_first(cpufreq_dom->map); - if ((perf->domain_info.coord_type != - processor_pminfo[firstcpu]->perf.domain_info.coord_type) || - (perf->domain_info.num_processors != - processor_pminfo[firstcpu]->perf.domain_info.num_processors)) { + if ((pmpt->domain_info.coord_type != + processor_pminfo[firstcpu]->domain_info.coord_type) || + (pmpt->domain_info.num_processors != + processor_pminfo[firstcpu]->domain_info.num_processors)) { printk(KERN_WARNING "cpufreq fail to add CPU%d:" "incorrect _PSD(%"PRIu64":%"PRIu64"), " "expect(%"PRIu64"/%"PRIu64")\n", - cpu, perf->domain_info.coord_type, - perf->domain_info.num_processors, - processor_pminfo[firstcpu]->perf.domain_info.coord_type, - processor_pminfo[firstcpu]->perf.domain_info.num_processors + cpu, pmpt->domain_info.coord_type, + pmpt->domain_info.num_processors, + processor_pminfo[firstcpu]->domain_info.coord_type, + processor_pminfo[firstcpu]->domain_info.num_processors ); return -EINVAL; } @@ -305,7 +306,7 @@ int cpufreq_add_cpu(unsigned int cpu) goto err1; if (hw_all || (cpumask_weight(cpufreq_dom->map) == - perf->domain_info.num_processors)) { + pmpt->domain_info.num_processors)) { memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); policy->governor = NULL; @@ -359,24 +360,24 @@ int cpufreq_del_cpu(unsigned int cpu) struct list_head *pos; struct cpufreq_dom *cpufreq_dom = NULL; struct cpufreq_policy *policy; - struct processor_performance *perf; + struct processor_pminfo *pmpt; /* to protect the case when Px was not controlled by xen */ if ( !processor_pminfo[cpu] || !cpu_online(cpu) ) return -EINVAL; - perf = &processor_pminfo[cpu]->perf; + pmpt = processor_pminfo[cpu]; - if ( !(perf->init & XEN_PX_INIT) ) + if ( !(pmpt->perf.init & XEN_PX_INIT) ) return -EINVAL; if (!per_cpu(cpufreq_cpu_policy, cpu)) return 0; - if (perf->shared_type == CPUFREQ_SHARED_TYPE_HW) + if (pmpt->shared_type == CPUFREQ_SHARED_TYPE_HW) hw_all = 1; - dom = perf->domain_info.domain; + dom = pmpt->domain_info.domain; policy = per_cpu(cpufreq_cpu_policy, cpu); list_for_each(pos, &cpufreq_dom_list_head) { @@ -393,7 +394,7 @@ int cpufreq_del_cpu(unsigned int cpu) /* for HW_ALL, stop gov for each core of the _PSD domain */ /* for SW_ALL & SW_ANY, stop gov for the 1st core of the _PSD domain */ if (hw_all || (cpumask_weight(cpufreq_dom->map) == - perf->domain_info.num_processors)) + pmpt->domain_info.num_processors)) __cpufreq_governor(policy, CPUFREQ_GOV_STOP); cpufreq_statistic_exit(cpu); @@ -475,19 +476,13 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *perf) acpi_id, cpu); pmpt = processor_pminfo[cpu]; + /* Must already allocated in set_psd_pminfo */ if ( !pmpt ) { - pmpt = xzalloc(struct processor_pminfo); - if ( !pmpt ) - { - ret = -ENOMEM; - goto out; - } - processor_pminfo[cpu] = pmpt; + ret = -EINVAL; + goto out; } pxpt = &pmpt->perf; - pmpt->acpi_id = acpi_id; - pmpt->id = cpu; if ( perf->flags & XEN_PX_PCT ) { @@ -537,25 +532,6 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *perf) print_PSS(pxpt->states,pxpt->state_count); } - if ( perf->flags & XEN_PX_PSD ) - { - /* check domain coordination */ - if ( perf->shared_type != CPUFREQ_SHARED_TYPE_ALL && - perf->shared_type != CPUFREQ_SHARED_TYPE_ANY && - perf->shared_type != CPUFREQ_SHARED_TYPE_HW ) - { - ret = -EINVAL; - goto out; - } - - pxpt->shared_type = perf->shared_type; - memcpy(&pxpt->domain_info, &perf->domain_info, - sizeof(struct xen_psd_package)); - - if ( cpufreq_verbose ) - print_PSD(&pxpt->domain_info); - } - if ( perf->flags & XEN_PX_PPC ) { pxpt->platform_limit = perf->platform_limit; @@ -570,7 +546,7 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *perf) } } - if ( perf->flags == ( XEN_PX_PCT | XEN_PX_PSS | XEN_PX_PSD | XEN_PX_PPC ) ) + if ( perf->flags == ( XEN_PX_PCT | XEN_PX_PSS | XEN_PX_PPC ) ) { pxpt->init = XEN_PX_INIT; @@ -582,6 +558,54 @@ out: return ret; } +int set_psd_pminfo(uint32_t acpi_id, uint32_t shared_type, + const struct xen_psd_package *psd_data) +{ + int ret = 0, cpuid; + struct processor_pminfo *pm_info; + + cpuid = get_cpu_id(acpi_id); + if ( cpuid < 0 || !psd_data ) + { + ret = -EINVAL; + goto out; + } + + /* check domain coordination */ + if ( shared_type != CPUFREQ_SHARED_TYPE_ALL && + shared_type != CPUFREQ_SHARED_TYPE_ANY && + shared_type != CPUFREQ_SHARED_TYPE_HW ) + { + ret = -EINVAL; + goto out; + } + if ( cpufreq_verbose ) + printk("Set CPU acpi_id(%d) cpuid(%d) _PSD State info:\n", + acpi_id, cpuid); + + pm_info = processor_pminfo[cpuid]; + if ( !pm_info ) + { + pm_info = xvzalloc(struct processor_pminfo); + if ( !pm_info ) + { + ret = -ENOMEM; + goto out; + } + processor_pminfo[cpuid] = pm_info; + } + pm_info->acpi_id = acpi_id; + pm_info->id = cpuid; + pm_info->shared_type = shared_type; + pm_info->domain_info = *psd_data; + + if ( cpufreq_verbose ) + print_PSD(&pm_info->domain_info); + + out: + return ret; +} + static void cpufreq_cmdline_common_para(struct cpufreq_policy *new_policy) { if (usr_max_freq) diff --git a/xen/drivers/cpufreq/cpufreq_ondemand.c b/xen/drivers/cpufreq/cpufreq_ondemand.c index 06cfc88d30..5b23daaac1 100644 --- a/xen/drivers/cpufreq/cpufreq_ondemand.c +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c @@ -194,7 +194,7 @@ static void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) set_timer(&per_cpu(dbs_timer, dbs_info->cpu), NOW()+dbs_tuners_ins.sampling_rate); - if ( processor_pminfo[dbs_info->cpu]->perf.shared_type + if ( processor_pminfo[dbs_info->cpu]->shared_type == CPUFREQ_SHARED_TYPE_HW ) { dbs_info->stoppable = 1; diff --git a/xen/include/acpi/cpufreq/processor_perf.h b/xen/include/acpi/cpufreq/processor_perf.h index 301104e16f..19f5de6b08 100644 --- a/xen/include/acpi/cpufreq/processor_perf.h +++ b/xen/include/acpi/cpufreq/processor_perf.h @@ -27,8 +27,6 @@ struct processor_performance { struct xen_pct_register status_register; uint32_t state_count; struct xen_processor_px *states; - struct xen_psd_package domain_info; - uint32_t shared_type; uint32_t init; }; @@ -36,6 +34,8 @@ struct processor_performance { struct processor_pminfo { uint32_t acpi_id; uint32_t id; + struct xen_psd_package domain_info; + uint32_t shared_type; struct processor_performance perf; }; diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h index 2725b8d104..f5c50380cb 100644 --- a/xen/include/public/platform.h +++ b/xen/include/public/platform.h @@ -363,12 +363,12 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t); #define XEN_PM_PX 1 #define XEN_PM_TX 2 #define XEN_PM_PDC 3 +#define XEN_PM_PSD 4 /* Px sub info type */ #define XEN_PX_PCT 1 #define XEN_PX_PSS 2 #define XEN_PX_PPC 4 -#define XEN_PX_PSD 8 struct xen_power_register { uint32_t space_id; @@ -439,6 +439,7 @@ struct xen_psd_package { uint64_t coord_type; uint64_t num_processors; }; +typedef struct xen_psd_package xen_psd_package_t; struct xen_processor_performance { uint32_t flags; /* flag for Px sub info type */ @@ -447,12 +448,6 @@ struct xen_processor_performance { struct xen_pct_register status_register; uint32_t state_count; /* total available performance states */ XEN_GUEST_HANDLE(xen_processor_px_t) states; - struct xen_psd_package domain_info; - /* Coordination type of this processor */ -#define XEN_CPUPERF_SHARED_TYPE_HW 1 /* HW does needed coordination */ -#define XEN_CPUPERF_SHARED_TYPE_ALL 2 /* All dependent CPUs should set freq */ -#define XEN_CPUPERF_SHARED_TYPE_ANY 3 /* Freq can be set from any dependent CPU */ - uint32_t shared_type; }; typedef struct xen_processor_performance xen_processor_performance_t; DEFINE_XEN_GUEST_HANDLE(xen_processor_performance_t); @@ -463,9 +458,15 @@ struct xenpf_set_processor_pminfo { uint32_t type; /* {XEN_PM_CX, XEN_PM_PX} */ union { struct xen_processor_power power;/* Cx: _CST/_CSD */ - struct xen_processor_performance perf; /* Px: _PPC/_PCT/_PSS/_PSD */ + xen_psd_package_t domain_info; /* _PSD */ + struct xen_processor_performance perf; /* Px: _PPC/_PCT/_PSS/ */ XEN_GUEST_HANDLE(uint32) pdc; /* _PDC */ } u; + /* Coordination type of this processor */ +#define XEN_CPUPERF_SHARED_TYPE_HW 1 /* HW does needed coordination */ +#define XEN_CPUPERF_SHARED_TYPE_ALL 2 /* All dependent CPUs should set freq */ +#define XEN_CPUPERF_SHARED_TYPE_ANY 3 /* Freq can be set from any dependent CPU */ + uint32_t shared_type; }; typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t; DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t); diff --git a/xen/include/xen/pmstat.h b/xen/include/xen/pmstat.h index 8350403e95..fd02316ce9 100644 --- a/xen/include/xen/pmstat.h +++ b/xen/include/xen/pmstat.h @@ -5,6 +5,8 @@ #include <public/platform.h> /* for struct xen_processor_power */ #include <public/sysctl.h> /* for struct pm_cx_stat */ +int set_psd_pminfo(uint32_t acpi_id, uint32_t shared_type, + const struct xen_psd_package *psd_data); int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *perf); long set_cx_pminfo(uint32_t acpi_id, struct xen_processor_power *power); diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 3c7b6c6830..0d964fe0ce 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -168,7 +168,7 @@ ! processor_performance platform.h ! processor_power platform.h ? processor_px platform.h -! psd_package platform.h +? psd_package platform.h ? xenpf_enter_acpi_sleep platform.h ? xenpf_pcpu_version platform.h ? xenpf_pcpuinfo platform.h -- 2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |