Skip to content

Commit 0e45818

Browse files
Kan LiangPeter Zijlstra
authored andcommitted
perf/x86/intel: Support RDPMC metrics clear mode
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 <ak@linux.intel.com> Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Andi Kleen <ak@linux.intel.com> Reviewed-by: Ian Rogers <irogers@google.com> Link: https://lkml.kernel.org/r/20241211160318.235056-1-kan.liang@linux.intel.com
1 parent 02c5636 commit 0e45818

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
@@ -2816,6 +2816,9 @@ static void intel_pmu_enable_fixed(struct perf_event *event)
28162816
return;
28172817

28182818
idx = INTEL_PMC_IDX_FIXED_SLOTS;
2819+
2820+
if (event->attr.config1 & INTEL_TD_CFG_METRIC_CLEAR)
2821+
bits |= INTEL_FIXED_3_METRICS_CLEAR;
28192822
}
28202823

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

40774085
/*
@@ -4680,6 +4688,8 @@ PMU_FORMAT_ATTR(in_tx, "config:32" );
46804688
PMU_FORMAT_ATTR(in_tx_cp, "config:33" );
46814689
PMU_FORMAT_ATTR(eq, "config:36" ); /* v6 + */
46824690

4691+
PMU_FORMAT_ATTR(metrics_clear, "config1:0"); /* PERF_CAPABILITIES.RDPMC_METRICS_CLEAR */
4692+
46834693
static ssize_t umask2_show(struct device *dev,
46844694
struct device_attribute *attr,
46854695
char *page)
@@ -4699,6 +4709,7 @@ static struct device_attribute format_attr_umask2 =
46994709
static struct attribute *format_evtsel_ext_attrs[] = {
47004710
&format_attr_umask2.attr,
47014711
&format_attr_eq.attr,
4712+
&format_attr_metrics_clear.attr,
47024713
NULL
47034714
};
47044715

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

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

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)