Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm-6.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
"Revert three recent intel_idle commits that introduced a functional
issue, included a coding mistake and have been questioned at the
design level"

* tag 'pm-6.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
Revert "intel_idle: Add support for using intel_idle in a VM guest using just hlt"
Revert "intel_idle: Add a "Long HLT" C1 state for the VM guest mode"
Revert "intel_idle: Add __init annotation to matchup_vm_state_with_baremetal()"

+1 -171
+1 -171
drivers/idle/intel_idle.c
··· 199 199 return __intel_idle(dev, drv, index); 200 200 } 201 201 202 - static __always_inline int __intel_idle_hlt(struct cpuidle_device *dev, 203 - struct cpuidle_driver *drv, int index) 204 - { 205 - raw_safe_halt(); 206 - raw_local_irq_disable(); 207 - return index; 208 - } 209 - 210 - /** 211 - * intel_idle_hlt - Ask the processor to enter the given idle state using hlt. 212 - * @dev: cpuidle device of the target CPU. 213 - * @drv: cpuidle driver (assumed to point to intel_idle_driver). 214 - * @index: Target idle state index. 215 - * 216 - * Use the HLT instruction to notify the processor that the CPU represented by 217 - * @dev is idle and it can try to enter the idle state corresponding to @index. 218 - * 219 - * Must be called under local_irq_disable(). 220 - */ 221 - static __cpuidle int intel_idle_hlt(struct cpuidle_device *dev, 222 - struct cpuidle_driver *drv, int index) 223 - { 224 - return __intel_idle_hlt(dev, drv, index); 225 - } 226 - 227 - static __cpuidle int intel_idle_hlt_irq_on(struct cpuidle_device *dev, 228 - struct cpuidle_driver *drv, int index) 229 - { 230 - int ret; 231 - 232 - raw_local_irq_enable(); 233 - ret = __intel_idle_hlt(dev, drv, index); 234 - raw_local_irq_disable(); 235 - 236 - return ret; 237 - } 238 - 239 202 /** 240 203 * intel_idle_s2idle - Ask the processor to enter the given idle state. 241 204 * @dev: cpuidle device of the target CPU. ··· 1242 1279 .enter = NULL } 1243 1280 }; 1244 1281 1245 - static struct cpuidle_state vmguest_cstates[] __initdata = { 1246 - { 1247 - .name = "C1", 1248 - .desc = "HLT", 1249 - .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_IRQ_ENABLE, 1250 - .exit_latency = 5, 1251 - .target_residency = 10, 1252 - .enter = &intel_idle_hlt, }, 1253 - { 1254 - .name = "C1L", 1255 - .desc = "Long HLT", 1256 - .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TLB_FLUSHED, 1257 - .exit_latency = 5, 1258 - .target_residency = 200, 1259 - .enter = &intel_idle_hlt, }, 1260 - { 1261 - .enter = NULL } 1262 - }; 1263 - 1264 1282 static const struct idle_cpu idle_cpu_nehalem __initconst = { 1265 1283 .state_table = nehalem_cstates, 1266 1284 .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, ··· 1841 1897 1842 1898 static void state_update_enter_method(struct cpuidle_state *state, int cstate) 1843 1899 { 1844 - if (state->enter == intel_idle_hlt) { 1845 - if (force_irq_on) { 1846 - pr_info("forced intel_idle_irq for state %d\n", cstate); 1847 - state->enter = intel_idle_hlt_irq_on; 1848 - } 1849 - return; 1850 - } 1851 - if (state->enter == intel_idle_hlt_irq_on) 1852 - return; /* no update scenarios */ 1853 - 1854 1900 if (state->flags & CPUIDLE_FLAG_INIT_XSTATE) { 1855 1901 /* 1856 1902 * Combining with XSTATE with IBRS or IRQ_ENABLE flags ··· 1872 1938 pr_info("forced intel_idle_irq for state %d\n", cstate); 1873 1939 state->enter = intel_idle_irq; 1874 1940 } 1875 - } 1876 - 1877 - /* 1878 - * For mwait based states, we want to verify the cpuid data to see if the state 1879 - * is actually supported by this specific CPU. 1880 - * For non-mwait based states, this check should be skipped. 1881 - */ 1882 - static bool should_verify_mwait(struct cpuidle_state *state) 1883 - { 1884 - if (state->enter == intel_idle_hlt) 1885 - return false; 1886 - if (state->enter == intel_idle_hlt_irq_on) 1887 - return false; 1888 - 1889 - return true; 1890 1941 } 1891 1942 1892 1943 static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) ··· 1922 2003 } 1923 2004 1924 2005 mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); 1925 - if (should_verify_mwait(&cpuidle_state_table[cstate]) && !intel_idle_verify_cstate(mwait_hint)) 2006 + if (!intel_idle_verify_cstate(mwait_hint)) 1926 2007 continue; 1927 2008 1928 2009 /* Structure copy. */ ··· 2056 2137 cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i)); 2057 2138 } 2058 2139 2059 - /* 2060 - * Match up the latency and break even point of the bare metal (cpu based) 2061 - * states with the deepest VM available state. 2062 - * 2063 - * We only want to do this for the deepest state, the ones that has 2064 - * the TLB_FLUSHED flag set on the . 2065 - * 2066 - * All our short idle states are dominated by vmexit/vmenter latencies, 2067 - * not the underlying hardware latencies so we keep our values for these. 2068 - */ 2069 - static void __init matchup_vm_state_with_baremetal(void) 2070 - { 2071 - int cstate; 2072 - 2073 - for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { 2074 - int matching_cstate; 2075 - 2076 - if (intel_idle_max_cstate_reached(cstate)) 2077 - break; 2078 - 2079 - if (!cpuidle_state_table[cstate].enter) 2080 - break; 2081 - 2082 - if (!(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_TLB_FLUSHED)) 2083 - continue; 2084 - 2085 - for (matching_cstate = 0; matching_cstate < CPUIDLE_STATE_MAX; ++matching_cstate) { 2086 - if (!icpu->state_table[matching_cstate].enter) 2087 - break; 2088 - if (icpu->state_table[matching_cstate].exit_latency > cpuidle_state_table[cstate].exit_latency) { 2089 - cpuidle_state_table[cstate].exit_latency = icpu->state_table[matching_cstate].exit_latency; 2090 - cpuidle_state_table[cstate].target_residency = icpu->state_table[matching_cstate].target_residency; 2091 - } 2092 - } 2093 - 2094 - } 2095 - } 2096 - 2097 - 2098 - static int __init intel_idle_vminit(const struct x86_cpu_id *id) 2099 - { 2100 - int retval; 2101 - 2102 - cpuidle_state_table = vmguest_cstates; 2103 - 2104 - icpu = (const struct idle_cpu *)id->driver_data; 2105 - 2106 - pr_debug("v" INTEL_IDLE_VERSION " model 0x%X\n", 2107 - boot_cpu_data.x86_model); 2108 - 2109 - intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); 2110 - if (!intel_idle_cpuidle_devices) 2111 - return -ENOMEM; 2112 - 2113 - /* 2114 - * We don't know exactly what the host will do when we go idle, but as a worst estimate 2115 - * we can assume that the exit latency of the deepest host state will be hit for our 2116 - * deep (long duration) guest idle state. 2117 - * The same logic applies to the break even point for the long duration guest idle state. 2118 - * So lets copy these two properties from the table we found for the host CPU type. 2119 - */ 2120 - matchup_vm_state_with_baremetal(); 2121 - 2122 - intel_idle_cpuidle_driver_init(&intel_idle_driver); 2123 - 2124 - retval = cpuidle_register_driver(&intel_idle_driver); 2125 - if (retval) { 2126 - struct cpuidle_driver *drv = cpuidle_get_driver(); 2127 - printk(KERN_DEBUG pr_fmt("intel_idle yielding to %s\n"), 2128 - drv ? drv->name : "none"); 2129 - goto init_driver_fail; 2130 - } 2131 - 2132 - retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online", 2133 - intel_idle_cpu_online, NULL); 2134 - if (retval < 0) 2135 - goto hp_setup_fail; 2136 - 2137 - return 0; 2138 - hp_setup_fail: 2139 - intel_idle_cpuidle_devices_uninit(); 2140 - cpuidle_unregister_driver(&intel_idle_driver); 2141 - init_driver_fail: 2142 - free_percpu(intel_idle_cpuidle_devices); 2143 - return retval; 2144 - } 2145 - 2146 2140 static int __init intel_idle_init(void) 2147 2141 { 2148 2142 const struct x86_cpu_id *id; ··· 2074 2242 id = x86_match_cpu(intel_idle_ids); 2075 2243 if (id) { 2076 2244 if (!boot_cpu_has(X86_FEATURE_MWAIT)) { 2077 - if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) 2078 - return intel_idle_vminit(id); 2079 2245 pr_debug("Please enable MWAIT in BIOS SETUP\n"); 2080 2246 return -ENODEV; 2081 2247 }