* pm-x86: x86: tsc: Rework time_cpufreq_notifier() admin-guide: pm: intel_epb: Add SPDX license tag and copyright notice PM / arch: x86: MSR_IA32_ENERGY_PERF_BIAS sysfs interface PM / arch: x86: Rework the MSR_IA32_ENERGY_PERF_BIAS handling
Unified · Split
| @@ -518,3 +518,21 @@ Description: Control Symetric Multi Threading (SMT) · 517 unmodified lines | ||
| 518 | 518 | |
| 519 | 519 | If control status is "forceoff" or "notsupported" writes |
| 520 | 520 | are rejected. |
| 521 | + | |
| 522 | +What: /sys/devices/system/cpu/cpu#/power/energy_perf_bias | |
| 523 | +Date: March 2019 | |
| 524 | +Contact: linux-pm@vger.kernel.org | |
| 525 | +Description: Intel Energy and Performance Bias Hint (EPB) | |
| 526 | + | |
| 527 | + EPB for the given CPU in a sliding scale 0 - 15, where a value | |
| 528 | + of 0 corresponds to a hint preference for highest performance | |
| 529 | + and a value of 15 corresponds to the maximum energy savings. | |
| 530 | + | |
| 531 | + In order to change the EPB value for the CPU, write either | |
| 532 | + a number in the 0 - 15 sliding scale above, or one of the | |
| 533 | + strings: "performance", "balance-performance", "normal", | |
| 534 | + "balance-power", "power" (that represent values reflected by | |
| 535 | + their meaning), to this attribute. | |
| 536 | + | |
| 537 | + This attribute is present for all online CPUs supporting the | |
| 538 | + Intel EPB feature. | |
| @@ -0,0 +1,41 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | +.. include:: <isonum.txt> | |
| 3 | + | |
| 4 | +====================================== | |
| 5 | +Intel Performance and Energy Bias Hint | |
| 6 | +====================================== | |
| 7 | + | |
| 8 | +:Copyright: |copy| 2019 Intel Corporation | |
| 9 | + | |
| 10 | +:Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | |
| 11 | + | |
| 12 | + | |
| 13 | +.. kernel-doc:: arch/x86/kernel/cpu/intel_epb.c | |
| 14 | + :doc: overview | |
| 15 | + | |
| 16 | +Intel Performance and Energy Bias Attribute in ``sysfs`` | |
| 17 | +======================================================== | |
| 18 | + | |
| 19 | +The Intel Performance and Energy Bias Hint (EPB) value for a given (logical) CPU | |
| 20 | +can be checked or updated through a ``sysfs`` attribute (file) under | |
| 21 | +:file:`/sys/devices/system/cpu/cpu<N>/power/`, where the CPU number ``<N>`` | |
| 22 | +is allocated at the system initialization time: | |
| 23 | + | |
| 24 | +``energy_perf_bias`` | |
| 25 | + Shows the current EPB value for the CPU in a sliding scale 0 - 15, where | |
| 26 | + a value of 0 corresponds to a hint preference for highest performance | |
| 27 | + and a value of 15 corresponds to the maximum energy savings. | |
| 28 | + | |
| 29 | + In order to update the EPB value for the CPU, this attribute can be | |
| 30 | + written to, either with a number in the 0 - 15 sliding scale above, or | |
| 31 | + with one of the strings: "performance", "balance-performance", "normal", | |
| 32 | + "balance-power", "power" that represent values reflected by their | |
| 33 | + meaning. | |
| 34 | + | |
| 35 | + This attribute is present for all online CPUs supporting the EPB | |
| 36 | + feature. | |
| 37 | + | |
| 38 | +Note that while the EPB interface to the processor is defined at the logical CPU | |
| 39 | +level, the physical register backing it may be shared by multiple CPUs (for | |
| 40 | +example, SMT siblings or cores in one package). For this reason, updating the | |
| 41 | +EPB value for one CPU may cause the EPB values for other CPUs to change. | |
| @@ -8,3 +8,4 @@ Working-State Power Management · 7 unmodified lines | ||
| 8 | 8 | cpuidle |
| 9 | 9 | cpufreq |
| 10 | 10 | intel_pstate |
| 11 | + intel_epb | |
| @@ -28,7 +28,7 @@ obj-y += cpuid-deps.o · 27 unmodified lines | ||
| 28 | 28 | obj-$(CONFIG_PROC_FS) += proc.o |
| 29 | 29 | obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o |
| 30 | 30 | |
| 31 | −obj-$(CONFIG_CPU_SUP_INTEL) += intel.o intel_pconfig.o | |
| 31 | +obj-$(CONFIG_CPU_SUP_INTEL) += intel.o intel_pconfig.o intel_epb.o | |
| 32 | 32 | obj-$(CONFIG_CPU_SUP_AMD) += amd.o |
| 33 | 33 | obj-$(CONFIG_CPU_SUP_HYGON) += hygon.o |
| 34 | 34 | obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o |
| @@ -1864,23 +1864,6 @@ void cpu_init(void) · 1863 unmodified lines | ||
| 1864 | 1864 | } |
| 1865 | 1865 | #endif |
| 1866 | 1866 | |
| 1867 | −static void bsp_resume(void) | |
| 1868 | −{ | |
| 1869 | − if (this_cpu->c_bsp_resume) | |
| 1870 | − this_cpu->c_bsp_resume(&boot_cpu_data); | |
| 1871 | −} | |
| 1872 | − | |
| 1873 | −static struct syscore_ops cpu_syscore_ops = { | |
| 1874 | − .resume = bsp_resume, | |
| 1875 | −}; | |
| 1876 | − | |
| 1877 | −static int __init init_cpu_syscore(void) | |
| 1878 | −{ | |
| 1879 | − register_syscore_ops(&cpu_syscore_ops); | |
| 1880 | − return 0; | |
| 1881 | −} | |
| 1882 | −core_initcall(init_cpu_syscore); | |
| 1883 | − | |
| 1884 | 1867 | /* |
| 1885 | 1868 | * The microcode loader calls this upon late microcode load to recheck features, |
| 1886 | 1869 | * only when microcode has been updated. Caller holds microcode_mutex and CPU |
| @@ -14,7 +14,6 @@ struct cpu_dev { · 13 unmodified lines | ||
| 14 | 14 | void (*c_init)(struct cpuinfo_x86 *); |
| 15 | 15 | void (*c_identify)(struct cpuinfo_x86 *); |
| 16 | 16 | void (*c_detect_tlb)(struct cpuinfo_x86 *); |
| 17 | − void (*c_bsp_resume)(struct cpuinfo_x86 *); | |
| 18 | 17 | int c_x86_vendor; |
| 19 | 18 | #ifdef CONFIG_X86_32 |
| 20 | 19 | /* Optional vendor specific routine to obtain the cache size. */ |
| @@ -596,36 +596,6 @@ detect_keyid_bits: · 595 unmodified lines | ||
| 596 | 596 | c->x86_phys_bits -= keyid_bits; |
| 597 | 597 | } |
| 598 | 598 | |
| 599 | −static void init_intel_energy_perf(struct cpuinfo_x86 *c) | |
| 600 | −{ | |
| 601 | − u64 epb; | |
| 602 | − | |
| 603 | − /* | |
| 604 | − * Initialize MSR_IA32_ENERGY_PERF_BIAS if not already initialized. | |
| 605 | − * (x86_energy_perf_policy(8) is available to change it at run-time.) | |
| 606 | − */ | |
| 607 | − if (!cpu_has(c, X86_FEATURE_EPB)) | |
| 608 | − return; | |
| 609 | − | |
| 610 | − rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); | |
| 611 | − if ((epb & 0xF) != ENERGY_PERF_BIAS_PERFORMANCE) | |
| 612 | − return; | |
| 613 | − | |
| 614 | − pr_info_once("ENERGY_PERF_BIAS: Set to 'normal', was 'performance'\n"); | |
| 615 | − pr_info_once("ENERGY_PERF_BIAS: View and update with x86_energy_perf_policy(8)\n"); | |
| 616 | − epb = (epb & ~0xF) | ENERGY_PERF_BIAS_NORMAL; | |
| 617 | − wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); | |
| 618 | −} | |
| 619 | − | |
| 620 | −static void intel_bsp_resume(struct cpuinfo_x86 *c) | |
| 621 | −{ | |
| 622 | − /* | |
| 623 | − * MSR_IA32_ENERGY_PERF_BIAS is lost across suspend/resume, | |
| 624 | − * so reinitialize it properly like during bootup: | |
| 625 | − */ | |
| 626 | − init_intel_energy_perf(c); | |
| 627 | −} | |
| 628 | − | |
| 629 | 599 | static void init_cpuid_fault(struct cpuinfo_x86 *c) |
| 630 | 600 | { |
| 631 | 601 | u64 msr; |
| @@ -763,8 +733,6 @@ static void init_intel(struct cpuinfo_x86 *c) · 131 unmodified lines | ||
| 763 | 733 | if (cpu_has(c, X86_FEATURE_TME)) |
| 764 | 734 | detect_tme(c); |
| 765 | 735 | |
| 766 | − init_intel_energy_perf(c); | |
| 767 | − | |
| 768 | 736 | init_intel_misc_features(c); |
| 769 | 737 | } |
| 770 | 738 | |
| @@ -1023,9 +991,7 @@ static const struct cpu_dev intel_cpu_dev = { · 252 unmodified lines | ||
| 1023 | 991 | .c_detect_tlb = intel_detect_tlb, |
| 1024 | 992 | .c_early_init = early_init_intel, |
| 1025 | 993 | .c_init = init_intel, |
| 1026 | − .c_bsp_resume = intel_bsp_resume, | |
| 1027 | 994 | .c_x86_vendor = X86_VENDOR_INTEL, |
| 1028 | 995 | }; |
| 1029 | 996 | |
| 1030 | 997 | cpu_dev_register(intel_cpu_dev); |
| 1031 | − | |
| @@ -0,0 +1,216 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * Intel Performance and Energy Bias Hint support. | |
| 4 | + * | |
| 5 | + * Copyright (C) 2019 Intel Corporation | |
| 6 | + * | |
| 7 | + * Author: | |
| 8 | + * Rafael J. Wysocki <rafael.j.wysocki@intel.com> | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <linux/cpuhotplug.h> | |
| 12 | +#include <linux/cpu.h> | |
| 13 | +#include <linux/device.h> | |
| 14 | +#include <linux/kernel.h> | |
| 15 | +#include <linux/string.h> | |
| 16 | +#include <linux/syscore_ops.h> | |
| 17 | +#include <linux/pm.h> | |
| 18 | + | |
| 19 | +#include <asm/cpufeature.h> | |
| 20 | +#include <asm/msr.h> | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * DOC: overview | |
| 24 | + * | |
| 25 | + * The Performance and Energy Bias Hint (EPB) allows software to specify its | |
| 26 | + * preference with respect to the power-performance tradeoffs present in the | |
| 27 | + * processor. Generally, the EPB is expected to be set by user space (directly | |
| 28 | + * via sysfs or with the help of the x86_energy_perf_policy tool), but there are | |
| 29 | + * two reasons for the kernel to update it. | |
| 30 | + * | |
| 31 | + * First, there are systems where the platform firmware resets the EPB during | |
| 32 | + * system-wide transitions from sleep states back into the working state | |
| 33 | + * effectively causing the previous EPB updates by user space to be lost. | |
| 34 | + * Thus the kernel needs to save the current EPB values for all CPUs during | |
| 35 | + * system-wide transitions to sleep states and restore them on the way back to | |
| 36 | + * the working state. That can be achieved by saving EPB for secondary CPUs | |
| 37 | + * when they are taken offline during transitions into system sleep states and | |
| 38 | + * for the boot CPU in a syscore suspend operation, so that it can be restored | |
| 39 | + * for the boot CPU in a syscore resume operation and for the other CPUs when | |
| 40 | + * they are brought back online. However, CPUs that are already offline when | |
| 41 | + * a system-wide PM transition is started are not taken offline again, but their | |
| 42 | + * EPB values may still be reset by the platform firmware during the transition, | |
| 43 | + * so in fact it is necessary to save the EPB of any CPU taken offline and to | |
| 44 | + * restore it when the given CPU goes back online at all times. | |
| 45 | + * | |
| 46 | + * Second, on many systems the initial EPB value coming from the platform | |
| 47 | + * firmware is 0 ('performance') and at least on some of them that is because | |
| 48 | + * the platform firmware does not initialize EPB at all with the assumption that | |
| 49 | + * the OS will do that anyway. That sometimes is problematic, as it may cause | |
| 50 | + * the system battery to drain too fast, for example, so it is better to adjust | |
| 51 | + * it on CPU bring-up and if the initial EPB value for a given CPU is 0, the | |
| 52 | + * kernel changes it to 6 ('normal'). | |
| 53 | + */ | |
| 54 | + | |
| 55 | +static DEFINE_PER_CPU(u8, saved_epb); | |
| 56 | + | |
| 57 | +#define EPB_MASK 0x0fULL | |
| 58 | +#define EPB_SAVED 0x10ULL | |
| 59 | +#define MAX_EPB EPB_MASK | |
| 60 | + | |
| 61 | +static int intel_epb_save(void) | |
| 62 | +{ | |
| 63 | + u64 epb; | |
| 64 | + | |
| 65 | + rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); | |
| 66 | + /* | |
| 67 | + * Ensure that saved_epb will always be nonzero after this write even if | |
| 68 | + * the EPB value read from the MSR is 0. | |
| 69 | + */ | |
| 70 | + this_cpu_write(saved_epb, (epb & EPB_MASK) | EPB_SAVED); | |
| 71 | + | |
| 72 | + return 0; | |
| 73 | +} | |
| 74 | + | |
| 75 | +static void intel_epb_restore(void) | |
| 76 | +{ | |
| 77 | + u64 val = this_cpu_read(saved_epb); | |
| 78 | + u64 epb; | |
| 79 | + | |
| 80 | + rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); | |
| 81 | + if (val) { | |
| 82 | + val &= EPB_MASK; | |
| 83 | + } else { | |
| 84 | + /* | |
| 85 | + * Because intel_epb_save() has not run for the current CPU yet, | |
| 86 | + * it is going online for the first time, so if its EPB value is | |
| 87 | + * 0 ('performance') at this point, assume that it has not been | |
| 88 | + * initialized by the platform firmware and set it to 6 | |
| 89 | + * ('normal'). | |
| 90 | + */ | |
| 91 | + val = epb & EPB_MASK; | |
| 92 | + if (val == ENERGY_PERF_BIAS_PERFORMANCE) { | |
| 93 | + val = ENERGY_PERF_BIAS_NORMAL; | |
| 94 | + pr_warn_once("ENERGY_PERF_BIAS: Set to 'normal', was 'performance'\n"); | |
| 95 | + } | |
| 96 | + } | |
| 97 | + wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, (epb & ~EPB_MASK) | val); | |
| 98 | +} | |
| 99 | + | |
| 100 | +static struct syscore_ops intel_epb_syscore_ops = { | |
| 101 | + .suspend = intel_epb_save, | |
| 102 | + .resume = intel_epb_restore, | |
| 103 | +}; | |
| 104 | + | |
| 105 | +static const char * const energy_perf_strings[] = { | |
| 106 | + "performance", | |
| 107 | + "balance-performance", | |
| 108 | + "normal", | |
| 109 | + "balance-power", | |
| 110 | + "power" | |
| 111 | +}; | |
| 112 | +static const u8 energ_perf_values[] = { | |
| 113 | + ENERGY_PERF_BIAS_PERFORMANCE, | |
| 114 | + ENERGY_PERF_BIAS_BALANCE_PERFORMANCE, | |
| 115 | + ENERGY_PERF_BIAS_NORMAL, | |
| 116 | + ENERGY_PERF_BIAS_BALANCE_POWERSAVE, | |
| 117 | + ENERGY_PERF_BIAS_POWERSAVE | |
| 118 | +}; | |
| 119 | + | |
| 120 | +static ssize_t energy_perf_bias_show(struct device *dev, | |
| 121 | + struct device_attribute *attr, | |
| 122 | + char *buf) | |
| 123 | +{ | |
| 124 | + unsigned int cpu = dev->id; | |
| 125 | + u64 epb; | |
| 126 | + int ret; | |
| 127 | + | |
| 128 | + ret = rdmsrl_on_cpu(cpu, MSR_IA32_ENERGY_PERF_BIAS, &epb); | |
| 129 | + if (ret < 0) | |
| 130 | + return ret; | |
| 131 | + | |
| 132 | + return sprintf(buf, "%llu\n", epb); | |
| 133 | +} | |
| 134 | + | |
| 135 | +static ssize_t energy_perf_bias_store(struct device *dev, | |
| 136 | + struct device_attribute *attr, | |
| 137 | + const char *buf, size_t count) | |
| 138 | +{ | |
| 139 | + unsigned int cpu = dev->id; | |
| 140 | + u64 epb, val; | |
| 141 | + int ret; | |
| 142 | + | |
| 143 | + ret = __sysfs_match_string(energy_perf_strings, | |
| 144 | + ARRAY_SIZE(energy_perf_strings), buf); | |
| 145 | + if (ret >= 0) | |
| 146 | + val = energ_perf_values[ret]; | |
| 147 | + else if (kstrtou64(buf, 0, &val) || val > MAX_EPB) | |
| 148 | + return -EINVAL; | |
| 149 | + | |
| 150 | + ret = rdmsrl_on_cpu(cpu, MSR_IA32_ENERGY_PERF_BIAS, &epb); | |
| 151 | + if (ret < 0) | |
| 152 | + return ret; | |
| 153 | + | |
| 154 | + ret = wrmsrl_on_cpu(cpu, MSR_IA32_ENERGY_PERF_BIAS, | |
| 155 | + (epb & ~EPB_MASK) | val); | |
| 156 | + if (ret < 0) | |
| 157 | + return ret; | |
| 158 | + | |
| 159 | + return count; | |
| 160 | +} | |
| 161 | + | |
| 162 | +static DEVICE_ATTR_RW(energy_perf_bias); | |
| 163 | + | |
| 164 | +static struct attribute *intel_epb_attrs[] = { | |
| 165 | + &dev_attr_energy_perf_bias.attr, | |
| 166 | + NULL | |
| 167 | +}; | |
| 168 | + | |
| 169 | +static const struct attribute_group intel_epb_attr_group = { | |
| 170 | + .name = power_group_name, | |
| 171 | + .attrs = intel_epb_attrs | |
| 172 | +}; | |
| 173 | + | |
| 174 | +static int intel_epb_online(unsigned int cpu) | |
| 175 | +{ | |
| 176 | + struct device *cpu_dev = get_cpu_device(cpu); | |
| 177 | + | |
| 178 | + intel_epb_restore(); | |
| 179 | + if (!cpuhp_tasks_frozen) | |
| 180 | + sysfs_merge_group(&cpu_dev->kobj, &intel_epb_attr_group); | |
| 181 | + | |
| 182 | + return 0; | |
| 183 | +} | |
| 184 | + | |
| 185 | +static int intel_epb_offline(unsigned int cpu) | |
| 186 | +{ | |
| 187 | + struct device *cpu_dev = get_cpu_device(cpu); | |
| 188 | + | |
| 189 | + if (!cpuhp_tasks_frozen) | |
| 190 | + sysfs_unmerge_group(&cpu_dev->kobj, &intel_epb_attr_group); | |
| 191 | + | |
| 192 | + intel_epb_save(); | |
| 193 | + return 0; | |
| 194 | +} | |
| 195 | + | |
| 196 | +static __init int intel_epb_init(void) | |
| 197 | +{ | |
| 198 | + int ret; | |
| 199 | + | |
| 200 | + if (!boot_cpu_has(X86_FEATURE_EPB)) | |
| 201 | + return -ENODEV; | |
| 202 | + | |
| 203 | + ret = cpuhp_setup_state(CPUHP_AP_X86_INTEL_EPB_ONLINE, | |
| 204 | + "x86/intel/epb:online", intel_epb_online, | |
| 205 | + intel_epb_offline); | |
| 206 | + if (ret < 0) | |
| 207 | + goto err_out_online; | |
| 208 | + | |
| 209 | + register_syscore_ops(&intel_epb_syscore_ops); | |
| 210 | + return 0; | |
| 211 | + | |
| 212 | +err_out_online: | |
| 213 | + cpuhp_remove_state(CPUHP_AP_X86_INTEL_EPB_ONLINE); | |
| 214 | + return ret; | |
| 215 | +} | |
| 216 | +subsys_initcall(intel_epb_init); | |
| @@ -185,8 +185,7 @@ static void __init cyc2ns_init_boot_cpu(void) · 184 unmodified lines | ||
| 185 | 185 | /* |
| 186 | 186 | * Secondary CPUs do not run through tsc_init(), so set up |
| 187 | 187 | * all the scale factors for all CPUs, assuming the same |
| 188 | − * speed as the bootup CPU. (cpufreq notifiers will fix this | |
| 189 | − * up if their speed diverges) | |
| 188 | + * speed as the bootup CPU. | |
| 190 | 189 | */ |
| 191 | 190 | static void __init cyc2ns_init_secondary_cpus(void) |
| 192 | 191 | { |
| @@ -937,12 +936,12 @@ void tsc_restore_sched_clock_state(void) · 744 unmodified lines | ||
| 937 | 936 | } |
| 938 | 937 | |
| 939 | 938 | #ifdef CONFIG_CPU_FREQ |
| 940 | −/* Frequency scaling support. Adjust the TSC based timer when the cpu frequency | |
| 939 | +/* | |
| 940 | + * Frequency scaling support. Adjust the TSC based timer when the CPU frequency | |
| 941 | 941 | * changes. |
| 942 | 942 | * |
| 943 | − * RED-PEN: On SMP we assume all CPUs run with the same frequency. It's | |
| 944 | − * not that important because current Opteron setups do not support | |
| 945 | − * scaling on SMP anyroads. | |
| 943 | + * NOTE: On SMP the situation is not fixable in general, so simply mark the TSC | |
| 944 | + * as unstable and give up in those cases. | |
| 946 | 945 | * |
| 947 | 946 | * Should fix up last_tsc too. Currently gettimeofday in the |
| 948 | 947 | * first tick after the change will be slightly wrong. |
| @@ -956,22 +955,22 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, · 7 unmodified lines | ||
| 956 | 955 | void *data) |
| 957 | 956 | { |
| 958 | 957 | struct cpufreq_freqs *freq = data; |
| 959 | − unsigned long *lpj; | |
| 960 | 958 | |
| 961 | − lpj = &boot_cpu_data.loops_per_jiffy; | |
| 962 | −#ifdef CONFIG_SMP | |
| 963 | − if (!(freq->flags & CPUFREQ_CONST_LOOPS)) | |
| 964 | − lpj = &cpu_data(freq->cpu).loops_per_jiffy; | |
| 965 | −#endif | |
| 959 | + if (num_online_cpus() > 1) { | |
| 960 | + mark_tsc_unstable("cpufreq changes on SMP"); | |
| 961 | + return 0; | |
| 962 | + } | |
| 966 | 963 | |
| 967 | 964 | if (!ref_freq) { |
| 968 | 965 | ref_freq = freq->old; |
| 969 | − loops_per_jiffy_ref = *lpj; | |
| 966 | + loops_per_jiffy_ref = boot_cpu_data.loops_per_jiffy; | |
| 970 | 967 | tsc_khz_ref = tsc_khz; |
| 971 | 968 | } |
| 969 | + | |
| 972 | 970 | if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || |
| 973 | − (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) { | |
| 974 | − *lpj = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); | |
| 971 | + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) { | |
| 972 | + boot_cpu_data.loops_per_jiffy = | |
| 973 | + cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); | |
| 975 | 974 | |
| 976 | 975 | tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); |
| 977 | 976 | if (!(freq->flags & CPUFREQ_CONST_LOOPS)) |
| @@ -147,6 +147,7 @@ enum cpuhp_state { · 146 unmodified lines | ||
| 147 | 147 | CPUHP_AP_X86_VDSO_VMA_ONLINE, |
| 148 | 148 | CPUHP_AP_IRQ_AFFINITY_ONLINE, |
| 149 | 149 | CPUHP_AP_ARM_MVEBU_SYNC_CLOCKS, |
| 150 | + CPUHP_AP_X86_INTEL_EPB_ONLINE, | |
| 150 | 151 | CPUHP_AP_PERF_ONLINE, |
| 151 | 152 | CPUHP_AP_PERF_X86_ONLINE, |
| 152 | 153 | CPUHP_AP_PERF_X86_UNCORE_ONLINE, |