aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-devices-system-cpu18
-rw-r--r--Documentation/admin-guide/pm/intel_epb.rst27
-rw-r--r--arch/x86/kernel/cpu/intel_epb.c93
3 files changed, 134 insertions, 4 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index 9605dbd4b5b5..7f4af7da3fbc 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -518,3 +518,21 @@ Description: Control Symetric Multi Threading (SMT)
518 518
519 If control status is "forceoff" or "notsupported" writes 519 If control status is "forceoff" or "notsupported" writes
520 are rejected. 520 are rejected.
521
522What: /sys/devices/system/cpu/cpu#/power/energy_perf_bias
523Date: March 2019
524Contact: linux-pm@vger.kernel.org
525Description: 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.
diff --git a/Documentation/admin-guide/pm/intel_epb.rst b/Documentation/admin-guide/pm/intel_epb.rst
index e9cfa7ec5420..d100849edfc4 100644
--- a/Documentation/admin-guide/pm/intel_epb.rst
+++ b/Documentation/admin-guide/pm/intel_epb.rst
@@ -4,3 +4,30 @@ Intel Performance and Energy Bias Hint
4 4
5.. kernel-doc:: arch/x86/kernel/cpu/intel_epb.c 5.. kernel-doc:: arch/x86/kernel/cpu/intel_epb.c
6 :doc: overview 6 :doc: overview
7
8Intel Performance and Energy Bias Attribute in ``sysfs``
9========================================================
10
11The Intel Performance and Energy Bias Hint (EPB) value for a given (logical) CPU
12can be checked or updated through a ``sysfs`` attribute (file) under
13:file:`/sys/devices/system/cpu/cpu<N>/power/`, where the CPU number ``<N>``
14is allocated at the system initialization time:
15
16``energy_perf_bias``
17 Shows the current EPB value for the CPU in a sliding scale 0 - 15, where
18 a value of 0 corresponds to a hint preference for highest performance
19 and a value of 15 corresponds to the maximum energy savings.
20
21 In order to update the EPB value for the CPU, this attribute can be
22 written to, either with a number in the 0 - 15 sliding scale above, or
23 with one of the strings: "performance", "balance-performance", "normal",
24 "balance-power", "power" that represent values reflected by their
25 meaning.
26
27 This attribute is present for all online CPUs supporting the EPB
28 feature.
29
30Note that while the EPB interface to the processor is defined at the logical CPU
31level, the physical register backing it may be shared by multiple CPUs (for
32example, SMT siblings or cores in one package). For this reason, updating the
33EPB value for one CPU may cause the EPB values for other CPUs to change.
diff --git a/arch/x86/kernel/cpu/intel_epb.c b/arch/x86/kernel/cpu/intel_epb.c
index 8d53cc88bd22..f4dd73396f28 100644
--- a/arch/x86/kernel/cpu/intel_epb.c
+++ b/arch/x86/kernel/cpu/intel_epb.c
@@ -9,8 +9,12 @@
9 */ 9 */
10 10
11#include <linux/cpuhotplug.h> 11#include <linux/cpuhotplug.h>
12#include <linux/cpu.h>
13#include <linux/device.h>
12#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/string.h>
13#include <linux/syscore_ops.h> 16#include <linux/syscore_ops.h>
17#include <linux/pm.h>
14 18
15#include <asm/cpufeature.h> 19#include <asm/cpufeature.h>
16#include <asm/msr.h> 20#include <asm/msr.h>
@@ -20,9 +24,9 @@
20 * 24 *
21 * The Performance and Energy Bias Hint (EPB) allows software to specify its 25 * The Performance and Energy Bias Hint (EPB) allows software to specify its
22 * preference with respect to the power-performance tradeoffs present in the 26 * preference with respect to the power-performance tradeoffs present in the
23 * processor. Generally, the EPB is expected to be set by user space through 27 * processor. Generally, the EPB is expected to be set by user space (directly
24 * the generic MSR interface (with the help of the x86_energy_perf_policy tool), 28 * via sysfs or with the help of the x86_energy_perf_policy tool), but there are
25 * but there are two reasons for the kernel to touch it. 29 * two reasons for the kernel to update it.
26 * 30 *
27 * First, there are systems where the platform firmware resets the EPB during 31 * First, there are systems where the platform firmware resets the EPB during
28 * system-wide transitions from sleep states back into the working state 32 * system-wide transitions from sleep states back into the working state
@@ -52,6 +56,7 @@ static DEFINE_PER_CPU(u8, saved_epb);
52 56
53#define EPB_MASK 0x0fULL 57#define EPB_MASK 0x0fULL
54#define EPB_SAVED 0x10ULL 58#define EPB_SAVED 0x10ULL
59#define MAX_EPB EPB_MASK
55 60
56static int intel_epb_save(void) 61static int intel_epb_save(void)
57{ 62{
@@ -97,15 +102,95 @@ static struct syscore_ops intel_epb_syscore_ops = {
97 .resume = intel_epb_restore, 102 .resume = intel_epb_restore,
98}; 103};
99 104
105static const char * const energy_perf_strings[] = {
106 "performance",
107 "balance-performance",
108 "normal",
109 "balance-power",
110 "power"
111};
112static 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
120static 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
135static 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
162static DEVICE_ATTR_RW(energy_perf_bias);
163
164static struct attribute *intel_epb_attrs[] = {
165 &dev_attr_energy_perf_bias.attr,
166 NULL
167};
168
169static const struct attribute_group intel_epb_attr_group = {
170 .name = power_group_name,
171 .attrs = intel_epb_attrs
172};
173
100static int intel_epb_online(unsigned int cpu) 174static int intel_epb_online(unsigned int cpu)
101{ 175{
176 struct device *cpu_dev = get_cpu_device(cpu);
177
102 intel_epb_restore(); 178 intel_epb_restore();
179 if (!cpuhp_tasks_frozen)
180 sysfs_merge_group(&cpu_dev->kobj, &intel_epb_attr_group);
181
103 return 0; 182 return 0;
104} 183}
105 184
106static int intel_epb_offline(unsigned int cpu) 185static int intel_epb_offline(unsigned int cpu)
107{ 186{
108 return intel_epb_save(); 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;
109} 194}
110 195
111static __init int intel_epb_init(void) 196static __init int intel_epb_init(void)