History

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.

Dapeng Mi committed 10 months ago

Commit 4e955c01 parent 49606263 files · +52 −17Browse files

Unified · Split

3 files
  1. arch/x86/events/intel/core.c +42 −17
  2. arch/x86/events/perf_event.h +5 −0
  3. arch/x86/include/asm/msr-index.h +5 −0
arch/x86/events/intel/core.c+42−17
@@ -3532,17 +3532,32 @@ static int intel_alt_er(struct cpu_hw_events *cpuc, · 3531 unmodified lines
3532 struct extra_reg *extra_regs = hybrid(cpuc->pmu, extra_regs);3532 struct extra_reg *extra_regs = hybrid(cpuc->pmu, extra_regs);
3533 int alt_idx = idx;3533 int alt_idx = idx;
3534 3534
3535 if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1))3535 switch (idx) {
3536 return idx;3536 case EXTRA_REG_RSP_0 ... EXTRA_REG_RSP_1:
3537 3537 if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1))
3538 if (idx == EXTRA_REG_RSP_0)3538 return idx;
3539 alt_idx = EXTRA_REG_RSP_1;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;
3540 3544
3541 if (idx == EXTRA_REG_RSP_1)3545 case EXTRA_REG_OMR_0 ... EXTRA_REG_OMR_3:
3542 alt_idx = EXTRA_REG_RSP_0;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;
3543 3557
3544 if (config & ~extra_regs[alt_idx].valid_mask)3558 default:
3545 return idx;3559 break;
3560 }
3546 3561
3547 return alt_idx;3562 return alt_idx;
3548}3563}
@@ -3550,16 +3565,26 @@ static int intel_alt_er(struct cpu_hw_events *cpuc, · 1 unmodified line
3550static void intel_fixup_er(struct perf_event *event, int idx)3565static void intel_fixup_er(struct perf_event *event, int idx)
3551{3566{
3552 struct extra_reg *extra_regs = hybrid(event->pmu, extra_regs);3567 struct extra_reg *extra_regs = hybrid(event->pmu, extra_regs);
3553 event->hw.extra_reg.idx = idx;3568 int er_idx;
3554 3569
3555 if (idx == EXTRA_REG_RSP_0) {3570 event->hw.extra_reg.idx = idx;
3556 event->hw.config &= ~INTEL_ARCH_EVENT_MASK;3571 switch (idx) {
3557 event->hw.config |= extra_regs[EXTRA_REG_RSP_0].event;3572 case EXTRA_REG_RSP_0 ... EXTRA_REG_RSP_1:
3558 event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0;3573 er_idx = idx - EXTRA_REG_RSP_0;
3559 } else if (idx == EXTRA_REG_RSP_1) {
3560 event->hw.config &= ~INTEL_ARCH_EVENT_MASK;3574 event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
3561 event->hw.config |= extra_regs[EXTRA_REG_RSP_1].event;3575 event->hw.config |= extra_regs[er_idx].event;
3562 event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1;3576 event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0 + er_idx;
3577 break;
3578
3579 case EXTRA_REG_OMR_0 ... EXTRA_REG_OMR_3:
3580 er_idx = idx - EXTRA_REG_OMR_0;
3581 event->hw.config &= ~ARCH_PERFMON_EVENTSEL_UMASK;
3582 event->hw.config |= 1ULL << (8 + er_idx);
3583 event->hw.extra_reg.reg = MSR_OMR_0 + er_idx;
3584 break;
3585
3586 default:
3587 pr_warn("The extra reg idx %d is not supported.\n", idx);
3563 }3588 }
3564}3589}
3565 3590
arch/x86/events/perf_event.h+5−0
@@ -45,6 +45,10 @@ enum extra_reg_type { · 44 unmodified lines
45 EXTRA_REG_FE = 4, /* fe_* */45 EXTRA_REG_FE = 4, /* fe_* */
46 EXTRA_REG_SNOOP_0 = 5, /* snoop response 0 */46 EXTRA_REG_SNOOP_0 = 5, /* snoop response 0 */
47 EXTRA_REG_SNOOP_1 = 6, /* snoop response 1 */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 EXTRA_REG_MAX /* number of entries needed */53 EXTRA_REG_MAX /* number of entries needed */
50};54};
@@ -1099,6 +1103,7 @@ do { \ · 1048 unmodified lines
1099#define PMU_FL_RETIRE_LATENCY 0x200 /* Support Retire Latency in PEBS */1103#define PMU_FL_RETIRE_LATENCY 0x200 /* Support Retire Latency in PEBS */
1100#define PMU_FL_BR_CNTR 0x400 /* Support branch counter logging */1104#define PMU_FL_BR_CNTR 0x400 /* Support branch counter logging */
1101#define PMU_FL_DYN_CONSTRAINT 0x800 /* Needs dynamic constraint */1105#define PMU_FL_DYN_CONSTRAINT 0x800 /* Needs dynamic constraint */
1106#define PMU_FL_HAS_OMR 0x1000 /* has 4 equivalent OMR regs */
1102 1107
1103#define EVENT_VAR(_id) event_attr_##_id1108#define EVENT_VAR(_id) event_attr_##_id
1104#define EVENT_PTR(_id) &event_attr_##_id.attr.attr1109#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
arch/x86/include/asm/msr-index.h+5−0
@@ -263,6 +263,11 @@ · 262 unmodified lines
263#define MSR_SNOOP_RSP_0 0x00001328263#define MSR_SNOOP_RSP_0 0x00001328
264#define MSR_SNOOP_RSP_1 0x00001329264#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#define MSR_LBR_SELECT 0x000001c8271#define MSR_LBR_SELECT 0x000001c8
267#define MSR_LBR_TOS 0x000001c9272#define MSR_LBR_TOS 0x000001c9
268 273