Add CONFIG_CPUFREQ to allow CPU frequency scaling support to be disabled at build time. When disabled, this removes cpufreq code from the build.
Introduce IS_ENABLED(CONFIG_CPUFREQ) checks for relevant do_pm_op and do_platform_op subops and other functions that require CONFIG_CPUFREQ to work. Add stubs where necessary. Signed-off-by: Stefano Stabellini <[email protected]> --- Changes in v4: - fix IS_ENABLED(CPUFREQ) - remove #ifdef in platform_hypercall.c and use DCE - move cpufreq_controller enum out of #ifdef --- xen/arch/x86/acpi/Makefile | 2 +- xen/arch/x86/platform_hypercall.c | 6 ++++-- xen/drivers/Makefile | 2 +- xen/drivers/acpi/pm-op.c | 3 ++- xen/drivers/acpi/pmstat.c | 8 ++++++-- xen/drivers/cpufreq/Kconfig | 14 +++++++++++++- xen/include/acpi/cpufreq/cpufreq.h | 13 ++++++++++++- xen/include/acpi/cpufreq/processor_perf.h | 3 --- xen/include/xen/acpi.h | 8 ++++++++ xen/include/xen/pmstat.h | 15 ++++++++++++++- xen/include/xen/sched.h | 7 +++++++ 11 files changed, 68 insertions(+), 13 deletions(-) diff --git a/xen/arch/x86/acpi/Makefile b/xen/arch/x86/acpi/Makefile index 041377e2bb..aa476f65d5 100644 --- a/xen/arch/x86/acpi/Makefile +++ b/xen/arch/x86/acpi/Makefile @@ -1,4 +1,4 @@ -obj-y += cpufreq/ +obj-$(CONFIG_CPUFREQ) += cpufreq/ obj-y += lib.o power.o cpu_idle.o cpuidle_menu.o obj-bin-y += boot.init.o wakeup_prot.o diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index c6c5135806..1dc7dae919 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -487,7 +487,8 @@ ret_t do_platform_op( case XENPF_change_freq: ret = -ENOSYS; - if ( cpufreq_controller != FREQCTL_dom0_kernel ) + if ( !IS_ENABLED(CONFIG_CPUFREQ) || + cpufreq_controller != FREQCTL_dom0_kernel ) break; ret = -EINVAL; if ( op->u.change_freq.flags || !cpu_online(op->u.change_freq.cpu) ) @@ -507,7 +508,8 @@ ret_t do_platform_op( XEN_GUEST_HANDLE(uint64) idletimes; ret = -ENOSYS; - if ( cpufreq_controller != FREQCTL_dom0_kernel ) + if ( !IS_ENABLED(CONFIG_CPUFREQ) || + cpufreq_controller != FREQCTL_dom0_kernel ) break; ctlmap.nr_bits = op->u.getidletime.cpumap_nr_cpus; diff --git a/xen/drivers/Makefile b/xen/drivers/Makefile index 2a1ae8ad13..3d81b8dde4 100644 --- a/xen/drivers/Makefile +++ b/xen/drivers/Makefile @@ -1,5 +1,5 @@ obj-y += char/ -obj-$(CONFIG_HAS_CPUFREQ) += cpufreq/ +obj-$(CONFIG_CPUFREQ) += cpufreq/ obj-$(CONFIG_HAS_PCI) += pci/ obj-$(CONFIG_HAS_VPCI) += vpci/ obj-$(CONFIG_HAS_PASSTHROUGH) += passthrough/ diff --git a/xen/drivers/acpi/pm-op.c b/xen/drivers/acpi/pm-op.c index 07bddc58d9..72f1eea62f 100644 --- a/xen/drivers/acpi/pm-op.c +++ b/xen/drivers/acpi/pm-op.c @@ -367,7 +367,8 @@ int do_pm_op(struct xen_sysctl_pm_op *op) return ret; } - if ( op->cpuid >= nr_cpu_ids || !cpu_online(op->cpuid) ) + if ( op->cpuid >= nr_cpu_ids || !cpu_online(op->cpuid) || + !IS_ENABLED(CONFIG_CPUFREQ) ) return -EINVAL; pmpt = processor_pminfo[op->cpuid]; diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c index 0f31736df2..d640d3a92c 100644 --- a/xen/drivers/acpi/pmstat.c +++ b/xen/drivers/acpi/pmstat.c @@ -76,6 +76,9 @@ void cpufreq_statistic_update(unsigned int cpu, uint8_t from, uint8_t to) spinlock_t *cpufreq_statistic_lock = &per_cpu(cpufreq_statistic_lock, cpu); + if ( !IS_ENABLED(CONFIG_CPUFREQ) ) + return; + spin_lock(cpufreq_statistic_lock); pxpt = per_cpu(cpufreq_statistic_data, cpu); @@ -105,7 +108,7 @@ int cpufreq_statistic_init(unsigned int cpu) spin_lock_init(cpufreq_statistic_lock); - if ( !pmpt ) + if ( !pmpt || !IS_ENABLED(CONFIG_CPUFREQ) ) return -EINVAL; /* Only need to initialize in Px mode */ @@ -225,7 +228,8 @@ int do_get_pm_info(struct xen_sysctl_get_pmstat *op) int ret = 0; const struct processor_pminfo *pmpt; - if ( !op || (op->cpuid >= nr_cpu_ids) || !cpu_online(op->cpuid) ) + if ( !IS_ENABLED(CONFIG_CPUFREQ) || !op || (op->cpuid >= nr_cpu_ids) || + !cpu_online(op->cpuid) ) return -EINVAL; pmpt = processor_pminfo[op->cpuid]; diff --git a/xen/drivers/cpufreq/Kconfig b/xen/drivers/cpufreq/Kconfig index cce80f4aec..b9b93c1a26 100644 --- a/xen/drivers/cpufreq/Kconfig +++ b/xen/drivers/cpufreq/Kconfig @@ -1,3 +1,15 @@ - config HAS_CPUFREQ bool + +config CPUFREQ + bool "CPU Frequency scaling" + default y + depends on HAS_CPUFREQ + help + Enable CPU frequency scaling and power management governors. + This allows Xen to dynamically adjust CPU P-states (performance + states) based on system load. + + Disabling this option removes all cpufreq governors and power + management interfaces. This is useful for real-time systems or + minimal hypervisor builds. diff --git a/xen/include/acpi/cpufreq/cpufreq.h b/xen/include/acpi/cpufreq/cpufreq.h index 0171ccf0ba..828d23961c 100644 --- a/xen/include/acpi/cpufreq/cpufreq.h +++ b/xen/include/acpi/cpufreq/cpufreq.h @@ -381,8 +381,19 @@ int write_ondemand_up_threshold(unsigned int up_threshold); int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq); +#ifdef CONFIG_CPUFREQ +int cpufreq_add_cpu(unsigned int cpu); +int cpufreq_del_cpu(unsigned int cpu); + void cpufreq_dbs_timer_suspend(void); void cpufreq_dbs_timer_resume(void); +#else +static inline int cpufreq_add_cpu(unsigned int cpu) { return -EOPNOTSUPP; } +static inline int cpufreq_del_cpu(unsigned int cpu) { return -EOPNOTSUPP; } + +static inline void cpufreq_dbs_timer_suspend(void) {} +static inline void cpufreq_dbs_timer_resume(void) {} +#endif void intel_feature_detect(struct cpufreq_policy *policy); @@ -398,7 +409,7 @@ void intel_feature_detect(struct cpufreq_policy *policy); int hwp_cmdline_parse(const char *s, const char *e); int hwp_register_driver(void); -#ifdef CONFIG_INTEL +#if defined(CONFIG_INTEL) && defined(CONFIG_CPUFREQ) bool hwp_active(void); #else static inline bool hwp_active(void) { return false; } diff --git a/xen/include/acpi/cpufreq/processor_perf.h b/xen/include/acpi/cpufreq/processor_perf.h index 0a87bc0384..bad9d94865 100644 --- a/xen/include/acpi/cpufreq/processor_perf.h +++ b/xen/include/acpi/cpufreq/processor_perf.h @@ -36,9 +36,6 @@ static inline void cpufreq_statistic_exit(unsigned int cpu) {} int cpufreq_limit_change(unsigned int cpu); -int cpufreq_add_cpu(unsigned int cpu); -int cpufreq_del_cpu(unsigned int cpu); - struct processor_performance { uint32_t state; uint32_t platform_limit; diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h index 90635ba0f3..ae6dba481c 100644 --- a/xen/include/xen/acpi.h +++ b/xen/include/xen/acpi.h @@ -186,7 +186,15 @@ static inline void acpi_set_csubstate_limit(unsigned int new_limit) { return; } #endif #ifdef XEN_GUEST_HANDLE +#ifdef CONFIG_CPUFREQ int acpi_set_pdc_bits(unsigned int acpi_id, XEN_GUEST_HANDLE(uint32)); +#else +static inline int acpi_set_pdc_bits(unsigned int acpi_id, + XEN_GUEST_HANDLE(uint32) pdc) +{ + return -EOPNOTSUPP; +} +#endif #endif int arch_acpi_set_pdc_bits(u32 acpi_id, u32 *, u32 mask); diff --git a/xen/include/xen/pmstat.h b/xen/include/xen/pmstat.h index 6096560d3c..51d3ee404f 100644 --- a/xen/include/xen/pmstat.h +++ b/xen/include/xen/pmstat.h @@ -5,10 +5,23 @@ #include <public/platform.h> /* for struct xen_processor_power */ #include <public/sysctl.h> /* for struct pm_cx_stat */ +#ifdef CONFIG_CPUFREQ 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); int set_cppc_pminfo(unsigned int acpi_id, const struct xen_processor_cppc *cppc_data); +#else +static inline int set_px_pminfo(uint32_t acpi_id, + struct xen_processor_performance *perf) +{ + return -EOPNOTSUPP; +} +static inline int set_cppc_pminfo(unsigned int acpi_id, + const struct xen_processor_cppc *cppc_data) +{ + return -EOPNOTSUPP; +} +#endif +long set_cx_pminfo(uint32_t acpi_id, struct xen_processor_power *power); #ifdef CONFIG_COMPAT struct compat_processor_performance; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 1268632344..084f3835dc 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -1259,6 +1259,7 @@ extern enum cpufreq_controller { FREQCTL_none, FREQCTL_dom0_kernel, FREQCTL_xen } cpufreq_controller; +#ifdef CONFIG_CPUFREQ static always_inline bool is_cpufreq_controller(const struct domain *d) { /* @@ -1274,6 +1275,12 @@ static always_inline bool is_cpufreq_controller(const struct domain *d) return (is_pv_domain(d) && is_hardware_domain(d) && cpufreq_controller == FREQCTL_dom0_kernel); } +#else +static always_inline bool is_cpufreq_controller(const struct domain *d) +{ + return false; +} +#endif int cpupool_move_domain(struct domain *d, struct cpupool *c); int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op); -- 2.25.1
