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

Configure Feed

Select the types of activity you want to include in your feed.

perf/x86/intel: Support the 4 new OMR MSRs introduced in DMR and NVL

Diamond Rapids (DMR) and Nova Lake (NVL) introduce an enhanced
Off-Module Response (OMR) facility, replacing the Off-Core Response (OCR)
Performance Monitoring of previous processors.

Legacy microarchitectures used the OCR facility to evaluate off-core and
multi-core off-module transactions. The newly named OMR facility improves
OCR capabilities for scalable coverage of new memory systems in
multi-core module systems.

Similar to OCR, 4 additional off-module configuration MSRs
(OFFMODULE_RSP_0 to OFFMODULE_RSP_3) are introduced to specify attributes
of off-module transactions. When multiple identical OMR events are
created, they need to occupy the same OFFMODULE_RSP_x MSR. To ensure
these multiple identical OMR events can work simultaneously, the
intel_alt_er() and intel_fixup_er() helpers are enhanced to rotate these
OMR events across different OFFMODULE_RSP_* MSRs, similar to previous OCR
events.

For more details about OMR, please refer to section 16.1 "OFF-MODULE
RESPONSE (OMR) FACILITY" in ISE documentation.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260114011750.350569-2-dapeng1.mi@linux.intel.com

authored by

Dapeng Mi and committed by
Peter Zijlstra
4e955c08 4960626f

+52 -17
+42 -17
arch/x86/events/intel/core.c
··· 3532 3532 struct extra_reg *extra_regs = hybrid(cpuc->pmu, extra_regs); 3533 3533 int alt_idx = idx; 3534 3534 3535 - if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1)) 3536 - return idx; 3535 + switch (idx) { 3536 + case EXTRA_REG_RSP_0 ... EXTRA_REG_RSP_1: 3537 + if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1)) 3538 + return idx; 3539 + if (++alt_idx > EXTRA_REG_RSP_1) 3540 + alt_idx = EXTRA_REG_RSP_0; 3541 + if (config & ~extra_regs[alt_idx].valid_mask) 3542 + return idx; 3543 + break; 3537 3544 3538 - if (idx == EXTRA_REG_RSP_0) 3539 - alt_idx = EXTRA_REG_RSP_1; 3545 + case EXTRA_REG_OMR_0 ... EXTRA_REG_OMR_3: 3546 + if (!(x86_pmu.flags & PMU_FL_HAS_OMR)) 3547 + return idx; 3548 + if (++alt_idx > EXTRA_REG_OMR_3) 3549 + alt_idx = EXTRA_REG_OMR_0; 3550 + /* 3551 + * Subtracting EXTRA_REG_OMR_0 ensures to get correct 3552 + * OMR extra_reg entries which start from 0. 3553 + */ 3554 + if (config & ~extra_regs[alt_idx - EXTRA_REG_OMR_0].valid_mask) 3555 + return idx; 3556 + break; 3540 3557 3541 - if (idx == EXTRA_REG_RSP_1) 3542 - alt_idx = EXTRA_REG_RSP_0; 3543 - 3544 - if (config & ~extra_regs[alt_idx].valid_mask) 3545 - return idx; 3558 + default: 3559 + break; 3560 + } 3546 3561 3547 3562 return alt_idx; 3548 3563 } ··· 3565 3550 static void intel_fixup_er(struct perf_event *event, int idx) 3566 3551 { 3567 3552 struct extra_reg *extra_regs = hybrid(event->pmu, extra_regs); 3568 - event->hw.extra_reg.idx = idx; 3553 + int er_idx; 3569 3554 3570 - if (idx == EXTRA_REG_RSP_0) { 3555 + event->hw.extra_reg.idx = idx; 3556 + switch (idx) { 3557 + case EXTRA_REG_RSP_0 ... EXTRA_REG_RSP_1: 3558 + er_idx = idx - EXTRA_REG_RSP_0; 3571 3559 event->hw.config &= ~INTEL_ARCH_EVENT_MASK; 3572 - event->hw.config |= extra_regs[EXTRA_REG_RSP_0].event; 3573 - event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; 3574 - } else if (idx == EXTRA_REG_RSP_1) { 3575 - event->hw.config &= ~INTEL_ARCH_EVENT_MASK; 3576 - event->hw.config |= extra_regs[EXTRA_REG_RSP_1].event; 3577 - event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; 3560 + event->hw.config |= extra_regs[er_idx].event; 3561 + event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0 + er_idx; 3562 + break; 3563 + 3564 + case EXTRA_REG_OMR_0 ... EXTRA_REG_OMR_3: 3565 + er_idx = idx - EXTRA_REG_OMR_0; 3566 + event->hw.config &= ~ARCH_PERFMON_EVENTSEL_UMASK; 3567 + event->hw.config |= 1ULL << (8 + er_idx); 3568 + event->hw.extra_reg.reg = MSR_OMR_0 + er_idx; 3569 + break; 3570 + 3571 + default: 3572 + pr_warn("The extra reg idx %d is not supported.\n", idx); 3578 3573 } 3579 3574 } 3580 3575
+5
arch/x86/events/perf_event.h
··· 45 45 EXTRA_REG_FE = 4, /* fe_* */ 46 46 EXTRA_REG_SNOOP_0 = 5, /* snoop response 0 */ 47 47 EXTRA_REG_SNOOP_1 = 6, /* snoop response 1 */ 48 + EXTRA_REG_OMR_0 = 7, /* OMR 0 */ 49 + EXTRA_REG_OMR_1 = 8, /* OMR 1 */ 50 + EXTRA_REG_OMR_2 = 9, /* OMR 2 */ 51 + EXTRA_REG_OMR_3 = 10, /* OMR 3 */ 48 52 49 53 EXTRA_REG_MAX /* number of entries needed */ 50 54 }; ··· 1103 1099 #define PMU_FL_RETIRE_LATENCY 0x200 /* Support Retire Latency in PEBS */ 1104 1100 #define PMU_FL_BR_CNTR 0x400 /* Support branch counter logging */ 1105 1101 #define PMU_FL_DYN_CONSTRAINT 0x800 /* Needs dynamic constraint */ 1102 + #define PMU_FL_HAS_OMR 0x1000 /* has 4 equivalent OMR regs */ 1106 1103 1107 1104 #define EVENT_VAR(_id) event_attr_##_id 1108 1105 #define EVENT_PTR(_id) &event_attr_##_id.attr.attr
+5
arch/x86/include/asm/msr-index.h
··· 263 263 #define MSR_SNOOP_RSP_0 0x00001328 264 264 #define MSR_SNOOP_RSP_1 0x00001329 265 265 266 + #define MSR_OMR_0 0x000003e0 267 + #define MSR_OMR_1 0x000003e1 268 + #define MSR_OMR_2 0x000003e2 269 + #define MSR_OMR_3 0x000003e3 270 + 266 271 #define MSR_LBR_SELECT 0x000001c8 267 272 #define MSR_LBR_TOS 0x000001c9 268 273