Skip to content

Commit cd65188

Browse files
committed
Merge: perf/x86/intel: Support RDPMC metrics clear mode
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7051 JIRA: https://issues.redhat.com/browse/RHEL-47448 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]> Approved-by: Lenny Szubowicz <[email protected]> Approved-by: David Arcari <[email protected]> Approved-by: ashelat <[email protected]> Approved-by: CKI KWF Bot <[email protected]> Merged-by: Jarod Wilson <[email protected]>
2 parents fa6cbde + 7489689 commit cd65188

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

28512851
idx = INTEL_PMC_IDX_FIXED_SLOTS;
2852+
2853+
if (event->attr.config1 & INTEL_TD_CFG_METRIC_CLEAR)
2854+
bits |= INTEL_FIXED_3_METRICS_CLEAR;
28522855
}
28532856

28542857
intel_set_masks(event, idx);
@@ -4132,7 +4135,12 @@ static int intel_pmu_hw_config(struct perf_event *event)
41324135
* is used in a metrics group, it too cannot support sampling.
41334136
*/
41344137
if (intel_pmu_has_cap(event, PERF_CAP_METRICS_IDX) && is_topdown_event(event)) {
4135-
if (event->attr.config1 || event->attr.config2)
4138+
/* The metrics_clear can only be set for the slots event */
4139+
if (event->attr.config1 &&
4140+
(!is_slots_event(event) || (event->attr.config1 & ~INTEL_TD_CFG_METRIC_CLEAR)))
4141+
return -EINVAL;
4142+
4143+
if (event->attr.config2)
41364144
return -EINVAL;
41374145

41384146
/*
@@ -4741,6 +4749,8 @@ PMU_FORMAT_ATTR(in_tx, "config:32" );
47414749
PMU_FORMAT_ATTR(in_tx_cp, "config:33" );
47424750
PMU_FORMAT_ATTR(eq, "config:36" ); /* v6 + */
47434751

4752+
PMU_FORMAT_ATTR(metrics_clear, "config1:0"); /* PERF_CAPABILITIES.RDPMC_METRICS_CLEAR */
4753+
47444754
static ssize_t umask2_show(struct device *dev,
47454755
struct device_attribute *attr,
47464756
char *page)
@@ -4760,6 +4770,7 @@ static struct device_attribute format_attr_umask2 =
47604770
static struct attribute *format_evtsel_ext_attrs[] = {
47614771
&format_attr_umask2.attr,
47624772
&format_attr_eq.attr,
4773+
&format_attr_metrics_clear.attr,
47634774
NULL
47644775
};
47654776

@@ -4784,6 +4795,13 @@ evtsel_ext_is_visible(struct kobject *kobj, struct attribute *attr, int i)
47844795
if (i == 1)
47854796
return (mask & ARCH_PERFMON_EVENTSEL_EQ) ? attr->mode : 0;
47864797

4798+
/* PERF_CAPABILITIES.RDPMC_METRICS_CLEAR */
4799+
if (i == 2) {
4800+
union perf_capabilities intel_cap = hybrid(dev_get_drvdata(dev), intel_cap);
4801+
4802+
return intel_cap.rdpmc_metrics_clear ? attr->mode : 0;
4803+
}
4804+
47874805
return 0;
47884806
}
47894807

arch/x86/events/perf_event.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ union perf_capabilities {
636636
u64 pebs_output_pt_available:1;
637637
u64 pebs_timing_info:1;
638638
u64 anythread_deprecated:1;
639+
u64 rdpmc_metrics_clear:1;
639640
};
640641
u64 capabilities;
641642
};

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)
@@ -378,6 +379,9 @@ static inline bool use_fixed_pseudo_encoding(u64 code)
378379
#define INTEL_TD_METRIC_MAX INTEL_TD_METRIC_MEM_BOUND
379380
#define INTEL_TD_METRIC_NUM 8
380381

382+
#define INTEL_TD_CFG_METRIC_CLEAR_BIT 0
383+
#define INTEL_TD_CFG_METRIC_CLEAR BIT_ULL(INTEL_TD_CFG_METRIC_CLEAR_BIT)
384+
381385
static inline bool is_metric_idx(int idx)
382386
{
383387
return (unsigned)(idx - INTEL_PMC_IDX_METRIC_BASE) < INTEL_TD_METRIC_NUM;

0 commit comments

Comments
 (0)