Skip to content

Commit 3521ba1

Browse files
spandruvadaIngo Molnar
authored andcommitted
powercap, perf/x86/intel/rapl: Add PSys support
Skylake processor supports a new set of RAPL registers for controlling entire SoC instead of just CPU package. This is useful for thermal and power control when source of power/thermal is not just CPU/GPU. This change adds a new platform domain (AKA PSys) to the current power capping Intel RAPL driver. PSys also supports PL1 (long term) and PL2 (short term) control like package domain. This also follows same MSRs for energy and time units as package domain. Unlike package domain, PSys support requires more than just processor level implementation. The other parts in the system need additional implementation, which OEMs needs to support. So not all Skylake systems will support PSys. Signed-off-by: Srinivas Pandruvada <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vince Weaver <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: http://lkml.kernel.org/r/1460930581-29748-3-git-send-email-srinivas.pandruvada@linux.intel.com Signed-off-by: Ingo Molnar <[email protected]>
1 parent 0b20e59 commit 3521ba1

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

drivers/powercap/intel_rapl.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
#include <asm/processor.h>
3535
#include <asm/cpu_device_id.h>
3636

37+
/* Local defines */
38+
#define MSR_PLATFORM_POWER_LIMIT 0x0000065C
39+
3740
/* bitmasks for RAPL MSRs, used by primitive access functions */
3841
#define ENERGY_STATUS_MASK 0xffffffff
3942

@@ -86,6 +89,7 @@ enum rapl_domain_type {
8689
RAPL_DOMAIN_PP0, /* core power plane */
8790
RAPL_DOMAIN_PP1, /* graphics uncore */
8891
RAPL_DOMAIN_DRAM,/* DRAM control_type */
92+
RAPL_DOMAIN_PLATFORM, /* PSys control_type */
8993
RAPL_DOMAIN_MAX,
9094
};
9195

@@ -251,9 +255,11 @@ static const char * const rapl_domain_names[] = {
251255
"core",
252256
"uncore",
253257
"dram",
258+
"psys",
254259
};
255260

256261
static struct powercap_control_type *control_type; /* PowerCap Controller */
262+
static struct rapl_domain *platform_rapl_domain; /* Platform (PSys) domain */
257263

258264
/* caller to ensure CPU hotplug lock is held */
259265
static struct rapl_package *find_package_by_id(int id)
@@ -409,6 +415,14 @@ static const struct powercap_zone_ops zone_ops[] = {
409415
.set_enable = set_domain_enable,
410416
.get_enable = get_domain_enable,
411417
},
418+
/* RAPL_DOMAIN_PLATFORM */
419+
{
420+
.get_energy_uj = get_energy_counter,
421+
.get_max_energy_range_uj = get_max_energy_counter,
422+
.release = release_zone,
423+
.set_enable = set_domain_enable,
424+
.get_enable = get_domain_enable,
425+
},
412426
};
413427

414428
static int set_power_limit(struct powercap_zone *power_zone, int id,
@@ -1160,6 +1174,13 @@ static int rapl_unregister_powercap(void)
11601174
powercap_unregister_zone(control_type,
11611175
&rd_package->power_zone);
11621176
}
1177+
1178+
if (platform_rapl_domain) {
1179+
powercap_unregister_zone(control_type,
1180+
&platform_rapl_domain->power_zone);
1181+
kfree(platform_rapl_domain);
1182+
}
1183+
11631184
powercap_unregister_control_type(control_type);
11641185

11651186
return 0;
@@ -1239,6 +1260,47 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
12391260
return ret;
12401261
}
12411262

1263+
static int rapl_register_psys(void)
1264+
{
1265+
struct rapl_domain *rd;
1266+
struct powercap_zone *power_zone;
1267+
u64 val;
1268+
1269+
if (rdmsrl_safe_on_cpu(0, MSR_PLATFORM_ENERGY_STATUS, &val) || !val)
1270+
return -ENODEV;
1271+
1272+
if (rdmsrl_safe_on_cpu(0, MSR_PLATFORM_POWER_LIMIT, &val) || !val)
1273+
return -ENODEV;
1274+
1275+
rd = kzalloc(sizeof(*rd), GFP_KERNEL);
1276+
if (!rd)
1277+
return -ENOMEM;
1278+
1279+
rd->name = rapl_domain_names[RAPL_DOMAIN_PLATFORM];
1280+
rd->id = RAPL_DOMAIN_PLATFORM;
1281+
rd->msrs[0] = MSR_PLATFORM_POWER_LIMIT;
1282+
rd->msrs[1] = MSR_PLATFORM_ENERGY_STATUS;
1283+
rd->rpl[0].prim_id = PL1_ENABLE;
1284+
rd->rpl[0].name = pl1_name;
1285+
rd->rpl[1].prim_id = PL2_ENABLE;
1286+
rd->rpl[1].name = pl2_name;
1287+
rd->rp = find_package_by_id(0);
1288+
1289+
power_zone = powercap_register_zone(&rd->power_zone, control_type,
1290+
"psys", NULL,
1291+
&zone_ops[RAPL_DOMAIN_PLATFORM],
1292+
2, &constraint_ops);
1293+
1294+
if (IS_ERR(power_zone)) {
1295+
kfree(rd);
1296+
return PTR_ERR(power_zone);
1297+
}
1298+
1299+
platform_rapl_domain = rd;
1300+
1301+
return 0;
1302+
}
1303+
12421304
static int rapl_register_powercap(void)
12431305
{
12441306
struct rapl_domain *rd;
@@ -1255,6 +1317,10 @@ static int rapl_register_powercap(void)
12551317
list_for_each_entry(rp, &rapl_packages, plist)
12561318
if (rapl_package_register_powercap(rp))
12571319
goto err_cleanup_package;
1320+
1321+
/* Don't bail out if PSys is not supported */
1322+
rapl_register_psys();
1323+
12581324
return ret;
12591325

12601326
err_cleanup_package:
@@ -1289,6 +1355,9 @@ static int rapl_check_domain(int cpu, int domain)
12891355
case RAPL_DOMAIN_DRAM:
12901356
msr = MSR_DRAM_ENERGY_STATUS;
12911357
break;
1358+
case RAPL_DOMAIN_PLATFORM:
1359+
/* PSYS(PLATFORM) is not a CPU domain, so avoid printng error */
1360+
return -EINVAL;
12921361
default:
12931362
pr_err("invalid domain id %d\n", domain);
12941363
return -EINVAL;

0 commit comments

Comments
 (0)