Even functions used on infrequently executed paths want converting: This
way all pre-filled struct cpufreq_driver instances can become
__initconst_cf_clobber, thus allowing to eliminate another 15 ENDBR
during the 2nd phase of alternatives patching.
For acpi-cpufreq's optionally populated .get hook make sure alternatives
patching can actually see the pointer. See also the code comment.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
Instead of adjusting the call site, we could also purge the .setpolicy
hook: None of the three drivers actually implements it.
--- a/xen/arch/x86/acpi/cpufreq/cpufreq.c
+++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c
@@ -625,12 +625,14 @@ static int cf_check acpi_cpufreq_cpu_exi
return 0;
}
-static const struct cpufreq_driver __initconstrel acpi_cpufreq_driver = {
+static const struct cpufreq_driver __initconst_cf_clobber
+acpi_cpufreq_driver = {
.name = "acpi-cpufreq",
.verify = acpi_cpufreq_verify,
.target = acpi_cpufreq_target,
.init = acpi_cpufreq_cpu_init,
.exit = acpi_cpufreq_cpu_exit,
+ .get = get_cur_freq_on_cpu,
};
static int __init cf_check cpufreq_driver_init(void)
@@ -675,6 +677,19 @@ static int __init cf_check cpufreq_drive
}
presmp_initcall(cpufreq_driver_init);
+static int __init cf_check cpufreq_driver_late_init(void)
+{
+ /*
+ * While acpi_cpufreq_driver wants to unconditionally have all hooks
+ * populated for __initconst_cf_clobber to have as much of an effect as
+ * possible, zap the .get hook here (but not in cpufreq_driver_init()),
+ * until acpi_cpufreq_cpu_init() knows whether it's wanted / needed.
+ */
+ cpufreq_driver.get = NULL;
+ return 0;
+}
+__initcall(cpufreq_driver_late_init);
+
int cpufreq_cpu_init(unsigned int cpuid)
{
int ret;
--- a/xen/arch/x86/acpi/cpufreq/hwp.c
+++ b/xen/arch/x86/acpi/cpufreq/hwp.c
@@ -513,8 +513,8 @@ static int cf_check hwp_cpufreq_update(i
return per_cpu(hwp_drv_data, cpuid)->ret;
}
-static const struct cpufreq_driver __initconstrel hwp_cpufreq_driver =
-{
+static const struct cpufreq_driver __initconst_cf_clobber
+hwp_cpufreq_driver = {
.name = XEN_HWP_DRIVER_NAME,
.verify = hwp_cpufreq_verify,
.target = hwp_cpufreq_target,
--- a/xen/arch/x86/acpi/cpufreq/powernow.c
+++ b/xen/arch/x86/acpi/cpufreq/powernow.c
@@ -317,7 +317,8 @@ static int cf_check powernow_cpufreq_cpu
return 0;
}
-static const struct cpufreq_driver __initconstrel powernow_cpufreq_driver = {
+static const struct cpufreq_driver __initconst_cf_clobber
+powernow_cpufreq_driver = {
.name = "powernow",
.verify = powernow_cpufreq_verify,
.target = powernow_cpufreq_target,
--- a/xen/drivers/acpi/pmstat.c
+++ b/xen/drivers/acpi/pmstat.c
@@ -240,7 +240,8 @@ static int get_cpufreq_para(struct xen_s
return ret;
op->u.get_para.cpuinfo_cur_freq =
- cpufreq_driver.get ? cpufreq_driver.get(op->cpuid) : policy->cur;
+ cpufreq_driver.get ? alternative_call(cpufreq_driver.get, op->cpuid)
+ : policy->cur;
op->u.get_para.cpuinfo_max_freq = policy->cpuinfo.max_freq;
op->u.get_para.cpuinfo_min_freq = policy->cpuinfo.min_freq;
op->u.get_para.turbo_enabled = cpufreq_get_turbo_status(op->cpuid);
--- a/xen/drivers/cpufreq/cpufreq.c
+++ b/xen/drivers/cpufreq/cpufreq.c
@@ -278,7 +278,7 @@ int cpufreq_add_cpu(unsigned int cpu)
policy->cpu = cpu;
per_cpu(cpufreq_cpu_policy, cpu) = policy;
- ret = cpufreq_driver.init(policy);
+ ret = alternative_call(cpufreq_driver.init, policy);
if (ret) {
free_cpumask_var(policy->cpus);
xfree(policy);
@@ -337,7 +337,7 @@ err1:
cpumask_clear_cpu(cpu, cpufreq_dom->map);
if (cpumask_empty(policy->cpus)) {
- cpufreq_driver.exit(policy);
+ alternative_call(cpufreq_driver.exit, policy);
free_cpumask_var(policy->cpus);
xfree(policy);
}
@@ -401,7 +401,7 @@ int cpufreq_del_cpu(unsigned int cpu)
cpumask_clear_cpu(cpu, cpufreq_dom->map);
if (cpumask_empty(policy->cpus)) {
- cpufreq_driver.exit(policy);
+ alternative_call(cpufreq_driver.exit, policy);
free_cpumask_var(policy->cpus);
xfree(policy);
}
--- a/xen/drivers/cpufreq/utility.c
+++ b/xen/drivers/cpufreq/utility.c
@@ -413,7 +413,7 @@ int cpufreq_update_turbo(int cpuid, int
policy->turbo = new_state;
if (cpufreq_driver.update)
{
- ret = cpufreq_driver.update(cpuid, policy);
+ ret = alternative_call(cpufreq_driver.update, cpuid, policy);
if (ret)
policy->turbo = curr_state;
}
@@ -449,7 +449,7 @@ int __cpufreq_set_policy(struct cpufreq_
return -EINVAL;
/* verify the cpu speed can be set within this limit */
- ret = cpufreq_driver.verify(policy);
+ ret = alternative_call(cpufreq_driver.verify, policy);
if (ret)
return ret;
@@ -457,7 +457,7 @@ int __cpufreq_set_policy(struct cpufreq_
data->max = policy->max;
data->limits = policy->limits;
if (cpufreq_driver.setpolicy)
- return cpufreq_driver.setpolicy(data);
+ return alternative_call(cpufreq_driver.setpolicy, data);
if (policy->governor != data->governor) {
/* save old, working values */
On 15.01.2024 17:10, Jan Beulich wrote: > Even functions used on infrequently executed paths want converting: This > way all pre-filled struct cpufreq_driver instances can become > __initconst_cf_clobber, thus allowing to eliminate another 15 ENDBR > during the 2nd phase of alternatives patching. > > For acpi-cpufreq's optionally populated .get hook make sure alternatives > patching can actually see the pointer. See also the code comment. > > Signed-off-by: Jan Beulich <jbeulich@suse.com> Sadly it was only after pushing that I noticed the stray "genapic" in the title here. Jan
On 15/01/2024 4:10 pm, Jan Beulich wrote: > Even functions used on infrequently executed paths want converting: This > way all pre-filled struct cpufreq_driver instances can become > __initconst_cf_clobber, thus allowing to eliminate another 15 ENDBR > during the 2nd phase of alternatives patching. > > For acpi-cpufreq's optionally populated .get hook make sure alternatives > patching can actually see the pointer. See also the code comment. > > Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
© 2016 - 2024 Red Hat, Inc.