Bay Trail (BYT) and Cherry Trail (CHT) platforms have a very specific way
of disabling auto-demotion via specific MSR bits. Clean up the code so that
BYT/CHT-specifics do not show up in the common 'struct idle_cpu' data
structure.

Remove the 'byt_auto_demotion_disable_flag' flag from 'struct idle_cpu',
because a better coding pattern is to avoid very case-specific fields like
'bool byt_auto_demotion_disable_flag' in a common data structure, which is
used for all platforms, not only BYT/CHT. The code is just more readable
when common data structures contain only commonly used fields.

Instead, match BYT/CHT in the 'intel_idle_init_cstates_icpu()' function,
and introduce a small helper to take care of BYT/CHT auto-demotion. This
is consistent with how platform-specific things are done for other
platforms.

No intended functional changes.

Inspired by (and description largely taken from) Linux'es c93d13b661a6
("intel_idle: clean up BYT/CHT auto demotion disable").

Signed-off-by: Jan Beulich <[email protected]>

--- a/xen/arch/x86/cpu/mwait-idle.c
+++ b/xen/arch/x86/cpu/mwait-idle.c
@@ -104,7 +104,6 @@ struct idle_cpu {
         * Indicate which enable bits to clear here.
         */
        unsigned long auto_demotion_disable_flags;
-       bool byt_auto_demotion_disable_flag;
        enum c1e_promotion c1e_promotion;
 };
 
@@ -1144,7 +1143,7 @@ static void cf_check auto_demotion_disab
        wrmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits);
 }
 
-static void cf_check byt_auto_demotion_disable(void *dummy)
+static void byt_cht_auto_demotion_disable(void)
 {
        wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0);
        wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0);
@@ -1195,13 +1194,11 @@ static const struct idle_cpu idle_cpu_sn
 static const struct idle_cpu idle_cpu_byt = {
        .state_table = byt_cstates,
        .c1e_promotion = C1E_PROMOTION_DISABLE,
-       .byt_auto_demotion_disable_flag = true,
 };
 
 static const struct idle_cpu idle_cpu_cht = {
        .state_table = cht_cstates,
        .c1e_promotion = C1E_PROMOTION_DISABLE,
-       .byt_auto_demotion_disable_flag = true,
 };
 
 static const struct idle_cpu idle_cpu_ivb = {
@@ -1680,14 +1677,11 @@ static int __init mwait_idle_probe(void)
        return 0;
 }
 
-static void mwait_idle_cpu_tweak(unsigned int cpu)
+static void mwait_idle_cpu_tweak(unsigned int cpu, bool bsp)
 {
        if (icpu->auto_demotion_disable_flags)
                on_selected_cpus(cpumask_of(cpu), auto_demotion_disable, NULL, 
1);
 
-       if (icpu->byt_auto_demotion_disable_flag)
-               on_selected_cpus(cpumask_of(cpu), byt_auto_demotion_disable, 
NULL, 1);
-
        switch (icpu->c1e_promotion) {
        case C1E_PROMOTION_DISABLE:
                on_selected_cpus(cpumask_of(cpu), c1e_promotion_disable, NULL, 
1);
@@ -1700,12 +1694,24 @@ static void mwait_idle_cpu_tweak(unsigne
        case C1E_PROMOTION_PRESERVE:
                break;
        }
+
+       /* Pkg-scope MSRs on 1-socket-only systems need writing only once. */
+       if (!bsp)
+               return;
+
+       switch (boot_cpu_data.vfm) {
+       case INTEL_ATOM_SILVERMONT:
+       case INTEL_ATOM_AIRMONT:
+               byt_cht_auto_demotion_disable();
+               break;
+       }
 }
 
 static int cf_check mwait_idle_cpu_init(
     struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
        unsigned int cpu = (unsigned long)hcpu, cstate;
+       static bool first;
        struct acpi_processor_power *dev = processor_powers[cpu];
 
        switch (action) {
@@ -1784,7 +1790,8 @@ static int cf_check mwait_idle_cpu_init(
                dev->count++;
        }
 
-       mwait_idle_cpu_tweak(cpu);
+       mwait_idle_cpu_tweak(cpu, first);
+       first = false;
 
        return NOTIFY_DONE;
 }
@@ -1821,7 +1828,7 @@ void mwait_idle_resume(void)
        if (!icpu)
                return;
 
-       mwait_idle_cpu_tweak(smp_processor_id());
+       mwait_idle_cpu_tweak(smp_processor_id(), true);
 }
 
 /* Helper function for HPET. */


Reply via email to