[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 2/5] xen: introduces XEN_PM_PSD sub-hypercall for solely delivery of _PSD info
_PSD(P-State Dependency) provides performance control, no matter legacy P-state or CPPC, logical processor dependency information. In order to re-use it for CPPC, this commit extracts the delivery of _PSD info from push_pxx_to_hypervisor() and wrap it with a new sub-hypercall XEN_PM_PSD. Signed-off-by: Penny Zheng <Penny.Zheng@xxxxxxx> --- v2 -> v3: - new commit --- drivers/xen/xen-acpi-processor.c | 82 ++++++++++++++++++++------------ include/xen/interface/platform.h | 8 ++-- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index e9f38f171240..8db8631a4b9d 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -157,18 +157,40 @@ xen_copy_pss_data(struct acpi_processor *_pr, } return dst_states; } -static int xen_copy_psd_data(struct acpi_processor *_pr, - struct xen_processor_performance *dst) +static int xen_copy_pct_data(struct acpi_pct_register *pct, + struct xen_pct_register *dst_pct) +{ + /* It would be nice if you could just do 'memcpy(pct, dst_pct') but + * sadly the Xen structure did not have the proper padding so the + * descriptor field takes two (dst_pct) bytes instead of one (pct). + */ + dst_pct->descriptor = pct->descriptor; + dst_pct->length = pct->length; + dst_pct->space_id = pct->space_id; + dst_pct->bit_width = pct->bit_width; + dst_pct->bit_offset = pct->bit_offset; + dst_pct->reserved = pct->reserved; + dst_pct->address = pct->address; + return 0; +} +static int push_psd_to_hypervisor(struct acpi_processor *_pr) { + struct xen_platform_op op = { + .cmd = XENPF_set_processor_pminfo, + .interface_version = XENPF_INTERFACE_VERSION, + .u.set_pminfo.id = _pr->acpi_id, + .u.set_pminfo.type = XEN_PM_PSD, + }; struct acpi_psd_package *pdomain; + int ret = 0; BUILD_BUG_ON(sizeof(struct xen_psd_package) != sizeof(struct acpi_psd_package)); - /* This information is enumerated only if acpi_processor_preregister_performance - * has been called. + /* This information is enumerated only if + * acpi_processor_preregister_performance has been called. */ - dst->shared_type = _pr->performance->shared_type; + op.u.set_pminfo.shared_type = _pr->performance->shared_type; pdomain = &(_pr->performance->domain_info); @@ -180,32 +202,30 @@ static int xen_copy_psd_data(struct acpi_processor *_pr, * running as a PVH dom0. */ if (pdomain->num_processors <= 1 || - dst->shared_type == CPUFREQ_SHARED_TYPE_NONE) { + op.u.set_pminfo.shared_type == CPUFREQ_SHARED_TYPE_NONE) { if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL) - dst->shared_type = CPUFREQ_SHARED_TYPE_ALL; + op.u.set_pminfo.shared_type = CPUFREQ_SHARED_TYPE_ALL; else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL) - dst->shared_type = CPUFREQ_SHARED_TYPE_HW; + op.u.set_pminfo.shared_type = CPUFREQ_SHARED_TYPE_HW; else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) - dst->shared_type = CPUFREQ_SHARED_TYPE_ANY; - + op.u.set_pminfo.shared_type = CPUFREQ_SHARED_TYPE_ANY; } - memcpy(&(dst->domain_info), pdomain, sizeof(struct acpi_psd_package)); - return 0; -} -static int xen_copy_pct_data(struct acpi_pct_register *pct, - struct xen_pct_register *dst_pct) -{ - /* It would be nice if you could just do 'memcpy(pct, dst_pct') but - * sadly the Xen structure did not have the proper padding so the - * descriptor field takes two (dst_pct) bytes instead of one (pct). - */ - dst_pct->descriptor = pct->descriptor; - dst_pct->length = pct->length; - dst_pct->space_id = pct->space_id; - dst_pct->bit_width = pct->bit_width; - dst_pct->bit_offset = pct->bit_offset; - dst_pct->reserved = pct->reserved; - dst_pct->address = pct->address; + + memcpy(&(op.u.set_pminfo.domain_info), pdomain, + sizeof(struct acpi_psd_package)); + + if (!no_hypercall) + ret = HYPERVISOR_platform_op(&op); + + if (!ret) { + pr_debug("ACPI CPU%u - _PSD uploaded.\n", _pr->acpi_id); + } else if ((ret != -EINVAL) && (ret != -ENOSYS)) + /* EINVAL means the ACPI ID is incorrect - meaning the ACPI + * table is referencing a non-existing CPU - which can happen + * with broken ACPI tables. */ + pr_warn("(_PSD): Hypervisor error (%d) for ACPI CPU%u\n", + ret, _pr->acpi_id); + return 0; } static int push_pxx_to_hypervisor(struct acpi_processor *_pr) @@ -234,10 +254,8 @@ static int push_pxx_to_hypervisor(struct acpi_processor *_pr) set_xen_guest_handle(dst_perf->states, dst_states); dst_perf->flags |= XEN_PX_PSS; } - if (!xen_copy_psd_data(_pr, dst_perf)) - dst_perf->flags |= XEN_PX_PSD; - if (dst_perf->flags != (XEN_PX_PSD | XEN_PX_PSS | XEN_PX_PCT | XEN_PX_PPC)) { + if (dst_perf->flags != (XEN_PX_PSS | XEN_PX_PCT | XEN_PX_PPC)) { pr_warn("ACPI CPU%u missing some P-state data (%x), skipping\n", _pr->acpi_id, dst_perf->flags); ret = -ENODEV; @@ -281,6 +299,10 @@ static int upload_pm_data(struct acpi_processor *_pr) mutex_unlock(&acpi_ids_mutex); return -EBUSY; } + + if (_pr->performance && _pr->performance->states) + err |= push_psd_to_hypervisor(_pr); + if (_pr->flags.power) err = push_cxx_to_hypervisor(_pr); diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h index 79a443c65ea9..a35e1eb958f3 100644 --- a/include/xen/interface/platform.h +++ b/include/xen/interface/platform.h @@ -319,11 +319,11 @@ DEFINE_GUEST_HANDLE_STRUCT(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; @@ -399,8 +399,6 @@ struct xen_processor_performance { struct xen_pct_register status_register; uint32_t state_count; /* total available performance states */ GUEST_HANDLE(xen_processor_px) states; - struct xen_psd_package domain_info; - uint32_t shared_type; /* coordination type of this processor */ }; DEFINE_GUEST_HANDLE_STRUCT(xen_processor_performance); @@ -410,9 +408,11 @@ 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 */ + struct xen_psd_package domain_info; /* _PSD */ + struct xen_processor_performance perf; /* Px: _PPC/_PCT/_PSS */ GUEST_HANDLE(uint32_t) pdc; }; + uint32_t shared_type; /* coordination type of this processor */ }; DEFINE_GUEST_HANDLE_STRUCT(xenpf_set_processor_pminfo); -- 2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |