Skip to content

Commit 7489689

Browse files
committed
perf/x86/intel: Support RDPMC metrics clear mode
JIRA: https://issues.redhat.com/browse/RHEL-47448 upstream ======== commit 0e45818 Author: Kan Liang <[email protected]> Date: Wed Dec 11 08:03:17 2024 -0800 description =========== The new RDPMC enhancement, metrics clear mode, is to clear the PERF_METRICS-related resources as well as the fixed-function performance monitoring counter 3 after the read is performed. It is available for ring 3. The feature is enumerated by the IA32_PERF_CAPABILITIES.RDPMC_CLEAR_METRICS[bit 19]. To enable the feature, the IA32_FIXED_CTR_CTRL.METRICS_CLEAR_EN[bit 14] must be set. Two ways were considered to enable the feature. - Expose a knob in the sysfs globally. One user may affect the measurement of other users when changing the knob. The solution is dropped. - Introduce a new event format, metrics_clear, for the slots event to disable/enable the feature only for the current process. Users can utilize the feature as needed. The latter solution is implemented in the patch. The current KVM doesn't support the perf metrics yet. For virtualization, the feature can be enabled later separately. Suggested-by: Andi Kleen <[email protected]> Signed-off-by: Kan Liang <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Andi Kleen <[email protected]> Reviewed-by: Ian Rogers <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Michael Petlan <[email protected]>
1 parent 79919c3 commit 7489689

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

arch/x86/events/intel/core.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2815,6 +2815,9 @@ static void intel_pmu_enable_fixed(struct perf_event *event)
28152815
return;
28162816

28172817
idx = INTEL_PMC_IDX_FIXED_SLOTS;
2818+
2819+
if (event->attr.config1 & INTEL_TD_CFG_METRIC_CLEAR)
2820+
bits |= INTEL_FIXED_3_METRICS_CLEAR;
28182821
}
28192822

28202823
intel_set_masks(event, idx);
@@ -4070,7 +4073,12 @@ static int intel_pmu_hw_config(struct perf_event *event)
40704073
* is used in a metrics group, it too cannot support sampling.
40714074
*/
40724075
if (intel_pmu_has_cap(event, PERF_CAP_METRICS_IDX) && is_topdown_event(event)) {
4073-
if (event->attr.config1 || event->attr.config2)
4076+
/* The metrics_clear can only be set for the slots event */
4077+
if (event->attr.config1 &&
4078+
(!is_slots_event(event) || (event->attr.config1 & ~INTEL_TD_CFG_METRIC_CLEAR)))
4079+
return -EINVAL;
4080+
4081+
if (event->attr.config2)
40744082
return -EINVAL;
40754083

40764084
/*
@@ -4679,6 +4687,8 @@ PMU_FORMAT_ATTR(in_tx, "config:32" );
46794687
PMU_FORMAT_ATTR(in_tx_cp, "config:33" );
46804688
PMU_FORMAT_ATTR(eq, "config:36" ); /* v6 + */
46814689

4690+
PMU_FORMAT_ATTR(metrics_clear, "config1:0"); /* PERF_CAPABILITIES.RDPMC_METRICS_CLEAR */
4691+
46824692
static ssize_t umask2_show(struct device *dev,
46834693
struct device_attribute *attr,
46844694
char *page)
@@ -4698,6 +4708,7 @@ static struct device_attribute format_attr_umask2 =
46984708
static struct attribute *format_evtsel_ext_attrs[] = {
46994709
&format_attr_umask2.attr,
47004710
&format_attr_eq.attr,
4711+
&format_attr_metrics_clear.attr,
47014712
NULL
47024713
};
47034714

@@ -4722,6 +4733,13 @@ evtsel_ext_is_visible(struct kobject *kobj, struct attribute *attr, int i)
47224733
if (i == 1)
47234734
return (mask & ARCH_PERFMON_EVENTSEL_EQ) ? attr->mode : 0;
47244735

4736+
/* PERF_CAPABILITIES.RDPMC_METRICS_CLEAR */
4737+
if (i == 2) {
4738+
union perf_capabilities intel_cap = hybrid(dev_get_drvdata(dev), intel_cap);
4739+
4740+
return intel_cap.rdpmc_metrics_clear ? attr->mode : 0;
4741+
}
4742+
47254743
return 0;
47264744
}
47274745

arch/x86/events/perf_event.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ union perf_capabilities {
624624
u64 pebs_output_pt_available:1;
625625
u64 pebs_timing_info:1;
626626
u64 anythread_deprecated:1;
627+
u64 rdpmc_metrics_clear:1;
627628
};
628629
u64 capabilities;
629630
};

arch/x86/include/asm/perf_event.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#define INTEL_FIXED_0_USER (1ULL << 1)
4242
#define INTEL_FIXED_0_ANYTHREAD (1ULL << 2)
4343
#define INTEL_FIXED_0_ENABLE_PMI (1ULL << 3)
44+
#define INTEL_FIXED_3_METRICS_CLEAR (1ULL << 2)
4445

4546
#define HSW_IN_TX (1ULL << 32)
4647
#define HSW_IN_TX_CHECKPOINTED (1ULL << 33)
@@ -372,6 +373,9 @@ static inline bool use_fixed_pseudo_encoding(u64 code)
372373
#define INTEL_TD_METRIC_MAX INTEL_TD_METRIC_MEM_BOUND
373374
#define INTEL_TD_METRIC_NUM 8
374375

376+
#define INTEL_TD_CFG_METRIC_CLEAR_BIT 0
377+
#define INTEL_TD_CFG_METRIC_CLEAR BIT_ULL(INTEL_TD_CFG_METRIC_CLEAR_BIT)
378+
375379
static inline bool is_metric_idx(int idx)
376380
{
377381
return (unsigned)(idx - INTEL_PMC_IDX_METRIC_BASE) < INTEL_TD_METRIC_NUM;

0 commit comments

Comments
 (0)