Skip to content

Commit bf44b90

Browse files
zhang-ruirafaeljw
authored andcommitted
powercap: intel_rapl: Make cpu optional for rapl_package
MSR RAPL Interface always removes a rapl_package when all the CPUs in that rapl_package are offlined. This is because it relies on an online CPU to access the MSR. But for RAPL Interface using MMIO registers, when all the cpus within the rapl_package are offlined, 1. the register can still be accessed 2. monitoring and setting the Power Pimits for the rapl_package is still meaningful because of uncore power. This means that, a valid rapl_package doesn't rely on one or more cpus being onlined. For this sense, make cpu optional for rapl_package. A rapl_package can be registered either using a CPU id to represent the physical package/die, or using the physical package id directly. Note that, the thermal throttling interrupt is not disabled via MSR_IA32_PACKAGE_THERM_INTERRUPT for such rapl_package at the moment. If it is still needed in the future, this can be achieved by selecting an onlined CPU using the physical package id. Note that, processor_thermal_rapl, the current MMIO RAPL Interface driver, can also be converted to register using a package id instead. But this is not done right now because processor_thermal_rapl driver works on single-package systems only, and offlining the only package will not happen. So keep the previous logic. Signed-off-by: Zhang Rui <[email protected]> Tested-by: Wang Wendy <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 693c1d7 commit bf44b90

File tree

4 files changed

+60
-44
lines changed

4 files changed

+60
-44
lines changed

drivers/powercap/intel_rapl_common.c

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,12 @@ static const struct powercap_zone_constraint_ops constraint_ops = {
532532
.get_name = get_constraint_name,
533533
};
534534

535+
/* Return the id used for read_raw/write_raw callback */
536+
static int get_rid(struct rapl_package *rp)
537+
{
538+
return rp->lead_cpu >= 0 ? rp->lead_cpu : rp->id;
539+
}
540+
535541
/* called after domain detection and package level data are set */
536542
static void rapl_init_domains(struct rapl_package *rp)
537543
{
@@ -550,10 +556,12 @@ static void rapl_init_domains(struct rapl_package *rp)
550556

551557
if (i == RAPL_DOMAIN_PLATFORM && rp->id > 0) {
552558
snprintf(rd->name, RAPL_DOMAIN_NAME_LENGTH, "psys-%d",
553-
topology_physical_package_id(rp->lead_cpu));
554-
} else
559+
rp->lead_cpu >= 0 ? topology_physical_package_id(rp->lead_cpu) :
560+
rp->id);
561+
} else {
555562
snprintf(rd->name, RAPL_DOMAIN_NAME_LENGTH, "%s",
556563
rapl_domain_names[i]);
564+
}
557565

558566
rd->id = i;
559567

@@ -725,7 +733,6 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
725733
enum rapl_primitives prim_fixed = prim_fixups(rd, prim);
726734
struct rapl_primitive_info *rpi = get_rpi(rd->rp, prim_fixed);
727735
struct reg_action ra;
728-
int cpu;
729736

730737
if (!rpi || !rpi->name || rpi->flag & RAPL_PRIMITIVE_DUMMY)
731738
return -EINVAL;
@@ -734,8 +741,6 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
734741
if (!ra.reg)
735742
return -EINVAL;
736743

737-
cpu = rd->rp->lead_cpu;
738-
739744
/* non-hardware data are collected by the polling thread */
740745
if (rpi->flag & RAPL_PRIMITIVE_DERIVED) {
741746
*data = rd->rdd.primitives[prim];
@@ -744,8 +749,8 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
744749

745750
ra.mask = rpi->mask;
746751

747-
if (rd->rp->priv->read_raw(cpu, &ra)) {
748-
pr_debug("failed to read reg 0x%llx on cpu %d\n", ra.reg, cpu);
752+
if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra)) {
753+
pr_debug("failed to read reg 0x%llx for %s:%s\n", ra.reg, rd->rp->name, rd->name);
749754
return -EIO;
750755
}
751756

@@ -766,15 +771,13 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
766771
{
767772
enum rapl_primitives prim_fixed = prim_fixups(rd, prim);
768773
struct rapl_primitive_info *rpi = get_rpi(rd->rp, prim_fixed);
769-
int cpu;
770774
u64 bits;
771775
struct reg_action ra;
772776
int ret;
773777

774778
if (!rpi || !rpi->name || rpi->flag & RAPL_PRIMITIVE_DUMMY)
775779
return -EINVAL;
776780

777-
cpu = rd->rp->lead_cpu;
778781
bits = rapl_unit_xlate(rd, rpi->unit, value, 1);
779782
bits <<= rpi->shift;
780783
bits &= rpi->mask;
@@ -785,7 +788,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
785788
ra.mask = rpi->mask;
786789
ra.value = bits;
787790

788-
ret = rd->rp->priv->write_raw(cpu, &ra);
791+
ret = rd->rp->priv->write_raw(get_rid(rd->rp), &ra);
789792

790793
return ret;
791794
}
@@ -835,9 +838,9 @@ static int rapl_check_unit_core(struct rapl_domain *rd)
835838

836839
ra.reg = rd->regs[RAPL_DOMAIN_REG_UNIT];
837840
ra.mask = ~0;
838-
if (rd->rp->priv->read_raw(rd->rp->lead_cpu, &ra)) {
839-
pr_err("Failed to read power unit REG 0x%llx on CPU %d, exit.\n",
840-
ra.reg, rd->rp->lead_cpu);
841+
if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra)) {
842+
pr_err("Failed to read power unit REG 0x%llx on %s:%s, exit.\n",
843+
ra.reg, rd->rp->name, rd->name);
841844
return -ENODEV;
842845
}
843846

@@ -863,9 +866,9 @@ static int rapl_check_unit_atom(struct rapl_domain *rd)
863866

864867
ra.reg = rd->regs[RAPL_DOMAIN_REG_UNIT];
865868
ra.mask = ~0;
866-
if (rd->rp->priv->read_raw(rd->rp->lead_cpu, &ra)) {
867-
pr_err("Failed to read power unit REG 0x%llx on CPU %d, exit.\n",
868-
ra.reg, rd->rp->lead_cpu);
869+
if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra)) {
870+
pr_err("Failed to read power unit REG 0x%llx on %s:%s, exit.\n",
871+
ra.reg, rd->rp->name, rd->name);
869872
return -ENODEV;
870873
}
871874

@@ -911,6 +914,9 @@ static void power_limit_irq_save_cpu(void *info)
911914

912915
static void package_power_limit_irq_save(struct rapl_package *rp)
913916
{
917+
if (rp->lead_cpu < 0)
918+
return;
919+
914920
if (!boot_cpu_has(X86_FEATURE_PTS) || !boot_cpu_has(X86_FEATURE_PLN))
915921
return;
916922

@@ -925,6 +931,9 @@ static void package_power_limit_irq_restore(struct rapl_package *rp)
925931
{
926932
u32 l, h;
927933

934+
if (rp->lead_cpu < 0)
935+
return;
936+
928937
if (!boot_cpu_has(X86_FEATURE_PTS) || !boot_cpu_has(X86_FEATURE_PLN))
929938
return;
930939

@@ -1263,7 +1272,7 @@ static int rapl_check_domain(int domain, struct rapl_package *rp)
12631272
*/
12641273

12651274
ra.mask = ENERGY_STATUS_MASK;
1266-
if (rp->priv->read_raw(rp->lead_cpu, &ra) || !ra.value)
1275+
if (rp->priv->read_raw(get_rid(rp), &ra) || !ra.value)
12671276
return -ENODEV;
12681277

12691278
return 0;
@@ -1401,13 +1410,18 @@ void rapl_remove_package(struct rapl_package *rp)
14011410
EXPORT_SYMBOL_GPL(rapl_remove_package);
14021411

14031412
/* caller to ensure CPU hotplug lock is held */
1404-
struct rapl_package *rapl_find_package_domain(int cpu, struct rapl_if_priv *priv)
1413+
struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu)
14051414
{
1406-
int id = topology_logical_die_id(cpu);
14071415
struct rapl_package *rp;
1416+
int uid;
1417+
1418+
if (id_is_cpu)
1419+
uid = topology_logical_die_id(id);
1420+
else
1421+
uid = id;
14081422

14091423
list_for_each_entry(rp, &rapl_packages, plist) {
1410-
if (rp->id == id
1424+
if (rp->id == uid
14111425
&& rp->priv->control_type == priv->control_type)
14121426
return rp;
14131427
}
@@ -1417,33 +1431,35 @@ struct rapl_package *rapl_find_package_domain(int cpu, struct rapl_if_priv *priv
14171431
EXPORT_SYMBOL_GPL(rapl_find_package_domain);
14181432

14191433
/* called from CPU hotplug notifier, hotplug lock held */
1420-
struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv)
1434+
struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu)
14211435
{
1422-
int id = topology_logical_die_id(cpu);
14231436
struct rapl_package *rp;
14241437
int ret;
14251438

14261439
rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL);
14271440
if (!rp)
14281441
return ERR_PTR(-ENOMEM);
14291442

1430-
/* add the new package to the list */
1431-
rp->id = id;
1432-
rp->lead_cpu = cpu;
1433-
rp->priv = priv;
1443+
if (id_is_cpu) {
1444+
rp->id = topology_logical_die_id(id);
1445+
rp->lead_cpu = id;
1446+
if (topology_max_die_per_package() > 1)
1447+
snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH, "package-%d-die-%d",
1448+
topology_physical_package_id(id), topology_die_id(id));
1449+
else
1450+
snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH, "package-%d",
1451+
topology_physical_package_id(id));
1452+
} else {
1453+
rp->id = id;
1454+
rp->lead_cpu = -1;
1455+
snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH, "package-%d", id);
1456+
}
14341457

1458+
rp->priv = priv;
14351459
ret = rapl_config(rp);
14361460
if (ret)
14371461
goto err_free_package;
14381462

1439-
if (topology_max_die_per_package() > 1)
1440-
snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH,
1441-
"package-%d-die-%d",
1442-
topology_physical_package_id(cpu), topology_die_id(cpu));
1443-
else
1444-
snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH, "package-%d",
1445-
topology_physical_package_id(cpu));
1446-
14471463
/* check if the package contains valid domains */
14481464
if (rapl_detect_domains(rp)) {
14491465
ret = -ENODEV;

drivers/powercap/intel_rapl_msr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ static int rapl_cpu_online(unsigned int cpu)
6868
{
6969
struct rapl_package *rp;
7070

71-
rp = rapl_find_package_domain(cpu, rapl_msr_priv);
71+
rp = rapl_find_package_domain(cpu, rapl_msr_priv, true);
7272
if (!rp) {
73-
rp = rapl_add_package(cpu, rapl_msr_priv);
73+
rp = rapl_add_package(cpu, rapl_msr_priv, true);
7474
if (IS_ERR(rp))
7575
return PTR_ERR(rp);
7676
}
@@ -83,7 +83,7 @@ static int rapl_cpu_down_prep(unsigned int cpu)
8383
struct rapl_package *rp;
8484
int lead_cpu;
8585

86-
rp = rapl_find_package_domain(cpu, rapl_msr_priv);
86+
rp = rapl_find_package_domain(cpu, rapl_msr_priv, true);
8787
if (!rp)
8888
return 0;
8989

drivers/thermal/intel/int340x_thermal/processor_thermal_rapl.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ static int rapl_mmio_cpu_online(unsigned int cpu)
2727
if (topology_physical_package_id(cpu))
2828
return 0;
2929

30-
rp = rapl_find_package_domain(cpu, &rapl_mmio_priv);
30+
rp = rapl_find_package_domain(cpu, &rapl_mmio_priv, true);
3131
if (!rp) {
32-
rp = rapl_add_package(cpu, &rapl_mmio_priv);
32+
rp = rapl_add_package(cpu, &rapl_mmio_priv, true);
3333
if (IS_ERR(rp))
3434
return PTR_ERR(rp);
3535
}
@@ -42,7 +42,7 @@ static int rapl_mmio_cpu_down_prep(unsigned int cpu)
4242
struct rapl_package *rp;
4343
int lead_cpu;
4444

45-
rp = rapl_find_package_domain(cpu, &rapl_mmio_priv);
45+
rp = rapl_find_package_domain(cpu, &rapl_mmio_priv, true);
4646
if (!rp)
4747
return 0;
4848

include/linux/intel_rapl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ struct rapl_if_priv {
135135
u64 reg_unit;
136136
u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
137137
int limits[RAPL_DOMAIN_MAX];
138-
int (*read_raw)(int cpu, struct reg_action *ra);
139-
int (*write_raw)(int cpu, struct reg_action *ra);
138+
int (*read_raw)(int id, struct reg_action *ra);
139+
int (*write_raw)(int id, struct reg_action *ra);
140140
void *defaults;
141141
void *rpi;
142142
};
@@ -161,8 +161,8 @@ struct rapl_package {
161161
struct rapl_if_priv *priv;
162162
};
163163

164-
struct rapl_package *rapl_find_package_domain(int cpu, struct rapl_if_priv *priv);
165-
struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv);
164+
struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu);
165+
struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu);
166166
void rapl_remove_package(struct rapl_package *rp);
167167

168168
#endif /* __INTEL_RAPL_H__ */

0 commit comments

Comments
 (0)