Skip to content

Commit f1e8d75

Browse files
zhang-ruirafaeljw
authored andcommitted
powercap/intel_rapl: enumerate Psys RAPL domain together with package RAPL domain
On multi-package systems, the Psys MSR is only valid for CPUs on specific package (master package). The current code makes the assumption that package 0 is the master package, but this is not true on new platforms like SPR. Fix the problem by emuerating the Psys RAPL domain for every package, so CPUs in slave packages will read 0 for the Psys energy counter and only CPUs in master packages can get a valid reading and register the Psys RAPL domain. The sysfs I/F for the Psys RAPL domain is not changed. Signed-off-by: Zhang Rui <rui.zhang@intel.com> [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 7a57e9f commit f1e8d75

3 files changed

Lines changed: 18 additions & 74 deletions

File tree

drivers/powercap/intel_rapl_common.c

Lines changed: 14 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,14 @@ static void rapl_init_domains(struct rapl_package *rp)
544544
continue;
545545

546546
rd->rp = rp;
547-
rd->name = rapl_domain_names[i];
547+
548+
if (i == RAPL_DOMAIN_PLATFORM && rp->id > 0) {
549+
snprintf(rd->name, RAPL_DOMAIN_NAME_LENGTH, "psys-%d",
550+
cpu_data(rp->lead_cpu).phys_proc_id);
551+
} else
552+
snprintf(rd->name, RAPL_DOMAIN_NAME_LENGTH, "%s",
553+
rapl_domain_names[i]);
554+
548555
rd->id = i;
549556
rd->rpl[0].prim_id = PL1_ENABLE;
550557
rd->rpl[0].name = pl1_name;
@@ -1112,13 +1119,17 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
11121119
}
11131120
/* now register domains as children of the socket/package */
11141121
for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
1122+
struct powercap_zone *parent = rp->power_zone;
1123+
11151124
if (rd->id == RAPL_DOMAIN_PACKAGE)
11161125
continue;
1126+
if (rd->id == RAPL_DOMAIN_PLATFORM)
1127+
parent = NULL;
11171128
/* number of power limits per domain varies */
11181129
nr_pl = find_nr_power_limit(rd);
11191130
power_zone = powercap_register_zone(&rd->power_zone,
11201131
rp->priv->control_type,
1121-
rd->name, rp->power_zone,
1132+
rd->name, parent,
11221133
&zone_ops[rd->id], nr_pl,
11231134
&constraint_ops);
11241135

@@ -1145,67 +1156,6 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
11451156
return ret;
11461157
}
11471158

1148-
int rapl_add_platform_domain(struct rapl_if_priv *priv)
1149-
{
1150-
struct rapl_domain *rd;
1151-
struct powercap_zone *power_zone;
1152-
struct reg_action ra;
1153-
int ret;
1154-
1155-
ra.reg = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS];
1156-
ra.mask = ~0;
1157-
ret = priv->read_raw(0, &ra);
1158-
if (ret || !ra.value)
1159-
return -ENODEV;
1160-
1161-
ra.reg = priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT];
1162-
ra.mask = ~0;
1163-
ret = priv->read_raw(0, &ra);
1164-
if (ret || !ra.value)
1165-
return -ENODEV;
1166-
1167-
rd = kzalloc(sizeof(*rd), GFP_KERNEL);
1168-
if (!rd)
1169-
return -ENOMEM;
1170-
1171-
rd->name = rapl_domain_names[RAPL_DOMAIN_PLATFORM];
1172-
rd->id = RAPL_DOMAIN_PLATFORM;
1173-
rd->regs[RAPL_DOMAIN_REG_LIMIT] =
1174-
priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_LIMIT];
1175-
rd->regs[RAPL_DOMAIN_REG_STATUS] =
1176-
priv->regs[RAPL_DOMAIN_PLATFORM][RAPL_DOMAIN_REG_STATUS];
1177-
rd->rpl[0].prim_id = PL1_ENABLE;
1178-
rd->rpl[0].name = pl1_name;
1179-
rd->rpl[1].prim_id = PL2_ENABLE;
1180-
rd->rpl[1].name = pl2_name;
1181-
rd->rp = rapl_find_package_domain(0, priv);
1182-
1183-
power_zone = powercap_register_zone(&rd->power_zone, priv->control_type,
1184-
"psys", NULL,
1185-
&zone_ops[RAPL_DOMAIN_PLATFORM],
1186-
2, &constraint_ops);
1187-
1188-
if (IS_ERR(power_zone)) {
1189-
kfree(rd);
1190-
return PTR_ERR(power_zone);
1191-
}
1192-
1193-
priv->platform_rapl_domain = rd;
1194-
1195-
return 0;
1196-
}
1197-
EXPORT_SYMBOL_GPL(rapl_add_platform_domain);
1198-
1199-
void rapl_remove_platform_domain(struct rapl_if_priv *priv)
1200-
{
1201-
if (priv->platform_rapl_domain) {
1202-
powercap_unregister_zone(priv->control_type,
1203-
&priv->platform_rapl_domain->power_zone);
1204-
kfree(priv->platform_rapl_domain);
1205-
}
1206-
}
1207-
EXPORT_SYMBOL_GPL(rapl_remove_platform_domain);
1208-
12091159
static int rapl_check_domain(int cpu, int domain, struct rapl_package *rp)
12101160
{
12111161
struct reg_action ra;
@@ -1215,11 +1165,9 @@ static int rapl_check_domain(int cpu, int domain, struct rapl_package *rp)
12151165
case RAPL_DOMAIN_PP0:
12161166
case RAPL_DOMAIN_PP1:
12171167
case RAPL_DOMAIN_DRAM:
1168+
case RAPL_DOMAIN_PLATFORM:
12181169
ra.reg = rp->priv->regs[domain][RAPL_DOMAIN_REG_STATUS];
12191170
break;
1220-
case RAPL_DOMAIN_PLATFORM:
1221-
/* PSYS(PLATFORM) is not a CPU domain, so avoid printng error */
1222-
return -EINVAL;
12231171
default:
12241172
pr_err("invalid domain id %d\n", domain);
12251173
return -EINVAL;

drivers/powercap/intel_rapl_msr.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ static struct rapl_if_priv rapl_msr_priv = {
4444
.regs[RAPL_DOMAIN_PLATFORM] = {
4545
MSR_PLATFORM_POWER_LIMIT, MSR_PLATFORM_ENERGY_STATUS, 0, 0, 0},
4646
.limits[RAPL_DOMAIN_PACKAGE] = 2,
47+
.limits[RAPL_DOMAIN_PLATFORM] = 2,
4748
};
4849

4950
/* Handles CPU hotplug on multi-socket systems.
@@ -157,9 +158,6 @@ static int rapl_msr_probe(struct platform_device *pdev)
157158
goto out;
158159
rapl_msr_priv.pcap_rapl_online = ret;
159160

160-
/* Don't bail out if PSys is not supported */
161-
rapl_add_platform_domain(&rapl_msr_priv);
162-
163161
return 0;
164162

165163
out:
@@ -171,7 +169,6 @@ static int rapl_msr_probe(struct platform_device *pdev)
171169
static int rapl_msr_remove(struct platform_device *pdev)
172170
{
173171
cpuhp_remove_state(rapl_msr_priv.pcap_rapl_online);
174-
rapl_remove_platform_domain(&rapl_msr_priv);
175172
powercap_unregister_control_type(rapl_msr_priv.control_type);
176173
return 0;
177174
}

include/linux/intel_rapl.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,10 @@ struct rapl_power_limit {
7979

8080
struct rapl_package;
8181

82+
#define RAPL_DOMAIN_NAME_LENGTH 16
83+
8284
struct rapl_domain {
83-
const char *name;
85+
char name[RAPL_DOMAIN_NAME_LENGTH];
8486
enum rapl_domain_type id;
8587
u64 regs[RAPL_DOMAIN_REG_MAX];
8688
struct powercap_zone power_zone;
@@ -152,7 +154,4 @@ struct rapl_package *rapl_find_package_domain(int cpu, struct rapl_if_priv *priv
152154
struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv);
153155
void rapl_remove_package(struct rapl_package *rp);
154156

155-
int rapl_add_platform_domain(struct rapl_if_priv *priv);
156-
void rapl_remove_platform_domain(struct rapl_if_priv *priv);
157-
158157
#endif /* __INTEL_RAPL_H__ */

0 commit comments

Comments
 (0)