Skip to content

Commit ed7bde7

Browse files
spandruvadarafaeljw
authored andcommitted
cpufreq: intel_pstate: Allow enable/disable energy efficiency
By default intel_pstate the driver disables energy efficiency by setting MSR_IA32_POWER_CTL bit 19 for Kaby Lake desktop CPU model in HWP mode. This CPU model is also shared by Coffee Lake desktop CPUs. This allows these systems to reach maximum possible frequency. But this adds power penalty, which some customers don't want. They want some way to enable/ disable dynamically. So, add an additional attribute "energy_efficiency" under /sys/devices/system/cpu/intel_pstate/ for these CPU models. This allows to read and write bit 19 ("Disable Energy Efficiency Optimization") in the MSR IA32_POWER_CTL. This attribute is present in both HWP and non-HWP mode as this has an effect in both modes. Refer to Intel Software Developer's manual for details. The scope of this bit is package wide. Also these systems are single package systems. So read/write MSR on the current CPU is enough. The energy efficiency (EE) bit setting needs to be preserved during suspend/resume and CPU offline/online operation. To do this: - Restoring the EE setting from the cpufreq resume() callback, if there is change from the system default. - By default, don't disable EE from cpufreq init() callback for matching CPU models. Since the scope is package wide and is a single package system, move the disable EE calls from init() callback to intel_pstate_init() function, which is called only once. Suggested-by: Len Brown <[email protected]> Signed-off-by: Srinivas Pandruvada <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 9ebcfad commit ed7bde7

File tree

3 files changed

+88
-26
lines changed

3 files changed

+88
-26
lines changed

Documentation/admin-guide/pm/intel_pstate.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,17 @@ argument is passed to the kernel in the command line.
431431
supported in the current configuration, writes to this attribute will
432432
fail with an appropriate error.
433433

434+
``energy_efficiency``
435+
This attribute is only present on platforms, which have CPUs matching
436+
Kaby Lake or Coffee Lake desktop CPU model. By default
437+
energy efficiency optimizations are disabled on these CPU models in HWP
438+
mode by this driver. Enabling energy efficiency may limit maximum
439+
operating frequency in both HWP and non HWP mode. In non HWP mode,
440+
optimizations are done only in the turbo frequency range. In HWP mode,
441+
optimizations are done in the entire frequency range. Setting this
442+
attribute to "1" enables energy efficiency optimizations and setting
443+
to "0" disables energy efficiency optimizations.
444+
434445
Interpretation of Policy Attributes
435446
-----------------------------------
436447

arch/x86/include/asm/msr-index.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@
149149

150150
#define MSR_LBR_SELECT 0x000001c8
151151
#define MSR_LBR_TOS 0x000001c9
152+
153+
#define MSR_IA32_POWER_CTL 0x000001fc
154+
#define MSR_IA32_POWER_CTL_BIT_EE 19
155+
152156
#define MSR_LBR_NHM_FROM 0x00000680
153157
#define MSR_LBR_NHM_TO 0x000006c0
154158
#define MSR_LBR_CORE_FROM 0x00000040
@@ -253,8 +257,6 @@
253257

254258
#define MSR_PEBS_FRONTEND 0x000003f7
255259

256-
#define MSR_IA32_POWER_CTL 0x000001fc
257-
258260
#define MSR_IA32_MC0_CTL 0x00000400
259261
#define MSR_IA32_MC0_STATUS 0x00000401
260262
#define MSR_IA32_MC0_ADDR 0x00000402

drivers/cpufreq/intel_pstate.c

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -866,10 +866,39 @@ static int intel_pstate_hwp_save_state(struct cpufreq_policy *policy)
866866
return 0;
867867
}
868868

869+
#define POWER_CTL_EE_ENABLE 1
870+
#define POWER_CTL_EE_DISABLE 2
871+
872+
static int power_ctl_ee_state;
873+
874+
static void set_power_ctl_ee_state(bool input)
875+
{
876+
u64 power_ctl;
877+
878+
mutex_lock(&intel_pstate_driver_lock);
879+
rdmsrl(MSR_IA32_POWER_CTL, power_ctl);
880+
if (input) {
881+
power_ctl &= ~BIT(MSR_IA32_POWER_CTL_BIT_EE);
882+
power_ctl_ee_state = POWER_CTL_EE_ENABLE;
883+
} else {
884+
power_ctl |= BIT(MSR_IA32_POWER_CTL_BIT_EE);
885+
power_ctl_ee_state = POWER_CTL_EE_DISABLE;
886+
}
887+
wrmsrl(MSR_IA32_POWER_CTL, power_ctl);
888+
mutex_unlock(&intel_pstate_driver_lock);
889+
}
890+
869891
static void intel_pstate_hwp_enable(struct cpudata *cpudata);
870892

871893
static int intel_pstate_resume(struct cpufreq_policy *policy)
872894
{
895+
896+
/* Only restore if the system default is changed */
897+
if (power_ctl_ee_state == POWER_CTL_EE_ENABLE)
898+
set_power_ctl_ee_state(true);
899+
else if (power_ctl_ee_state == POWER_CTL_EE_DISABLE)
900+
set_power_ctl_ee_state(false);
901+
873902
if (!hwp_active)
874903
return 0;
875904

@@ -1218,6 +1247,32 @@ static ssize_t store_hwp_dynamic_boost(struct kobject *a,
12181247
return count;
12191248
}
12201249

1250+
static ssize_t show_energy_efficiency(struct kobject *kobj, struct kobj_attribute *attr,
1251+
char *buf)
1252+
{
1253+
u64 power_ctl;
1254+
int enable;
1255+
1256+
rdmsrl(MSR_IA32_POWER_CTL, power_ctl);
1257+
enable = !!(power_ctl & BIT(MSR_IA32_POWER_CTL_BIT_EE));
1258+
return sprintf(buf, "%d\n", !enable);
1259+
}
1260+
1261+
static ssize_t store_energy_efficiency(struct kobject *a, struct kobj_attribute *b,
1262+
const char *buf, size_t count)
1263+
{
1264+
bool input;
1265+
int ret;
1266+
1267+
ret = kstrtobool(buf, &input);
1268+
if (ret)
1269+
return ret;
1270+
1271+
set_power_ctl_ee_state(input);
1272+
1273+
return count;
1274+
}
1275+
12211276
show_one(max_perf_pct, max_perf_pct);
12221277
show_one(min_perf_pct, min_perf_pct);
12231278

@@ -1228,6 +1283,7 @@ define_one_global_rw(min_perf_pct);
12281283
define_one_global_ro(turbo_pct);
12291284
define_one_global_ro(num_pstates);
12301285
define_one_global_rw(hwp_dynamic_boost);
1286+
define_one_global_rw(energy_efficiency);
12311287

12321288
static struct attribute *intel_pstate_attributes[] = {
12331289
&status.attr,
@@ -1241,6 +1297,8 @@ static const struct attribute_group intel_pstate_attr_group = {
12411297
.attrs = intel_pstate_attributes,
12421298
};
12431299

1300+
static const struct x86_cpu_id intel_pstate_cpu_ee_disable_ids[];
1301+
12441302
static void __init intel_pstate_sysfs_expose_params(void)
12451303
{
12461304
struct kobject *intel_pstate_kobject;
@@ -1273,6 +1331,11 @@ static void __init intel_pstate_sysfs_expose_params(void)
12731331
&hwp_dynamic_boost.attr);
12741332
WARN_ON(rc);
12751333
}
1334+
1335+
if (x86_match_cpu(intel_pstate_cpu_ee_disable_ids)) {
1336+
rc = sysfs_create_file(intel_pstate_kobject, &energy_efficiency.attr);
1337+
WARN_ON(rc);
1338+
}
12761339
}
12771340
/************************** sysfs end ************************/
12781341

@@ -1288,25 +1351,6 @@ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
12881351
cpudata->epp_default = intel_pstate_get_epp(cpudata, 0);
12891352
}
12901353

1291-
#define MSR_IA32_POWER_CTL_BIT_EE 19
1292-
1293-
/* Disable energy efficiency optimization */
1294-
static void intel_pstate_disable_ee(int cpu)
1295-
{
1296-
u64 power_ctl;
1297-
int ret;
1298-
1299-
ret = rdmsrl_on_cpu(cpu, MSR_IA32_POWER_CTL, &power_ctl);
1300-
if (ret)
1301-
return;
1302-
1303-
if (!(power_ctl & BIT(MSR_IA32_POWER_CTL_BIT_EE))) {
1304-
pr_info("Disabling energy efficiency optimization\n");
1305-
power_ctl |= BIT(MSR_IA32_POWER_CTL_BIT_EE);
1306-
wrmsrl_on_cpu(cpu, MSR_IA32_POWER_CTL, power_ctl);
1307-
}
1308-
}
1309-
13101354
static int atom_get_min_pstate(void)
13111355
{
13121356
u64 value;
@@ -1982,10 +2026,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
19822026
if (hwp_active) {
19832027
const struct x86_cpu_id *id;
19842028

1985-
id = x86_match_cpu(intel_pstate_cpu_ee_disable_ids);
1986-
if (id)
1987-
intel_pstate_disable_ee(cpunum);
1988-
19892029
intel_pstate_hwp_enable(cpu);
19902030

19912031
id = x86_match_cpu(intel_pstate_hwp_boost_ids);
@@ -2806,8 +2846,17 @@ static int __init intel_pstate_init(void)
28062846
if (rc)
28072847
return rc;
28082848

2809-
if (hwp_active)
2849+
if (hwp_active) {
2850+
const struct x86_cpu_id *id;
2851+
2852+
id = x86_match_cpu(intel_pstate_cpu_ee_disable_ids);
2853+
if (id) {
2854+
set_power_ctl_ee_state(false);
2855+
pr_info("Disabling energy efficiency optimization\n");
2856+
}
2857+
28102858
pr_info("HWP enabled\n");
2859+
}
28112860

28122861
return 0;
28132862
}

0 commit comments

Comments
 (0)