Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf/x86/rapl: Fix psys-energy event on Intel SPR platform

There are several things special for the RAPL Psys energy counter, on
Intel Sapphire Rapids platform.
1. it contains one Psys master package, and only CPUs on the master
package can read valid value of the Psys energy counter, reading the
MSR on CPUs in the slave package returns 0.
2. The master package does not have to be Physical package 0. And when
all the CPUs on the Psys master package are offlined, we lose the Psys
energy counter, at runtime.
3. The Psys energy counter can be disabled by BIOS, while all the other
energy counters are not affected.

It is not easy to handle all of these in the current RAPL PMU design
because
a) perf_msr_probe() validates the MSR on some random CPU, which may either
be in the Psys master package or in the Psys slave package.
b) all the RAPL events share the same PMU, and there is not API to remove
the psys-energy event cleanly, without affecting the other events in
the same PMU.

This patch addresses the problems in a simple way.

First, by setting .no_check bit for RAPL Psys MSR, the psys-energy event
is always added, so we don't have to check the Psys ENERGY_STATUS MSR on
master package.

Then, by removing rapl_not_visible(), the psys-energy event is always
available in sysfs. This does not affect the previous code because, for
the RAPL MSRs with .no_check cleared, the .is_visible() callback is always
overriden in the perf_msr_probe() function.

Note, although RAPL PMU is die-based, and the Psys energy counter MSR on
Intel SPR is package scope, this is not a problem because there is only
one die in each package on SPR.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Link: https://lkml.kernel.org/r/20210204161816.12649-3-rui.zhang@intel.com

authored by

Zhang Rui and committed by
Peter Zijlstra
838342a6 b6f78d3f

+9 -12
+9 -12
arch/x86/events/rapl.c
··· 454 454 NULL, 455 455 }; 456 456 457 - static umode_t 458 - rapl_not_visible(struct kobject *kobj, struct attribute *attr, int i) 459 - { 460 - return 0; 461 - } 462 - 463 457 static struct attribute_group rapl_events_cores_group = { 464 458 .name = "events", 465 459 .attrs = rapl_events_cores, 466 - .is_visible = rapl_not_visible, 467 460 }; 468 461 469 462 static struct attribute *rapl_events_pkg[] = { ··· 469 476 static struct attribute_group rapl_events_pkg_group = { 470 477 .name = "events", 471 478 .attrs = rapl_events_pkg, 472 - .is_visible = rapl_not_visible, 473 479 }; 474 480 475 481 static struct attribute *rapl_events_ram[] = { ··· 481 489 static struct attribute_group rapl_events_ram_group = { 482 490 .name = "events", 483 491 .attrs = rapl_events_ram, 484 - .is_visible = rapl_not_visible, 485 492 }; 486 493 487 494 static struct attribute *rapl_events_gpu[] = { ··· 493 502 static struct attribute_group rapl_events_gpu_group = { 494 503 .name = "events", 495 504 .attrs = rapl_events_gpu, 496 - .is_visible = rapl_not_visible, 497 505 }; 498 506 499 507 static struct attribute *rapl_events_psys[] = { ··· 505 515 static struct attribute_group rapl_events_psys_group = { 506 516 .name = "events", 507 517 .attrs = rapl_events_psys, 508 - .is_visible = rapl_not_visible, 509 518 }; 510 519 511 520 static bool test_msr(int idx, void *data) ··· 521 532 [PERF_RAPL_RAM] = { MSR_DRAM_ENERGY_STATUS, &rapl_events_ram_group, test_msr, false, RAPL_MSR_MASK }, 522 533 [PERF_RAPL_PP1] = { MSR_PP1_ENERGY_STATUS, &rapl_events_gpu_group, test_msr, false, RAPL_MSR_MASK }, 523 534 [PERF_RAPL_PSYS] = { MSR_PLATFORM_ENERGY_STATUS, &rapl_events_psys_group, test_msr, false, RAPL_MSR_MASK }, 535 + }; 536 + 537 + static struct perf_msr intel_rapl_spr_msrs[] = { 538 + [PERF_RAPL_PP0] = { MSR_PP0_ENERGY_STATUS, &rapl_events_cores_group, test_msr, false, RAPL_MSR_MASK }, 539 + [PERF_RAPL_PKG] = { MSR_PKG_ENERGY_STATUS, &rapl_events_pkg_group, test_msr, false, RAPL_MSR_MASK }, 540 + [PERF_RAPL_RAM] = { MSR_DRAM_ENERGY_STATUS, &rapl_events_ram_group, test_msr, false, RAPL_MSR_MASK }, 541 + [PERF_RAPL_PP1] = { MSR_PP1_ENERGY_STATUS, &rapl_events_gpu_group, test_msr, false, RAPL_MSR_MASK }, 542 + [PERF_RAPL_PSYS] = { MSR_PLATFORM_ENERGY_STATUS, &rapl_events_psys_group, test_msr, true, RAPL_MSR_MASK }, 524 543 }; 525 544 526 545 /* ··· 761 764 BIT(PERF_RAPL_PSYS), 762 765 .unit_quirk = RAPL_UNIT_QUIRK_INTEL_SPR, 763 766 .msr_power_unit = MSR_RAPL_POWER_UNIT, 764 - .rapl_msrs = intel_rapl_msrs, 767 + .rapl_msrs = intel_rapl_spr_msrs, 765 768 }; 766 769 767 770 static struct rapl_model model_amd_fam17h = {