[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1545816338-1171-7-git-send-email-wei.w.wang@intel.com>
Date: Wed, 26 Dec 2018 17:25:34 +0800
From: Wei Wang <wei.w.wang@...el.com>
To: linux-kernel@...r.kernel.org, kvm@...r.kernel.org,
pbonzini@...hat.com, ak@...ux.intel.com, peterz@...radead.org
Cc: kan.liang@...el.com, mingo@...hat.com, rkrcmar@...hat.com,
like.xu@...el.com, wei.w.wang@...el.com, jannh@...gle.com,
arei.gonglei@...wei.com
Subject: [PATCH v4 06/10] perf/x86: no counter allocation support
In some cases, an event may be created without needing a counter
allocation. For example, an lbr event may be created by the host
only to help save/restore the lbr stack on the vCPU context switching.
This patch adds a "no_counter" attr boolean to let the callers
explicitly tell the perf core that no counter is needed.
Signed-off-by: Wei Wang <wei.w.wang@...el.com>
---
arch/x86/events/core.c | 12 ++++++++++++
include/linux/perf_event.h | 5 +++++
include/uapi/linux/perf_event.h | 3 ++-
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 374a197..c09f03b 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -410,6 +410,9 @@ int x86_setup_perfctr(struct perf_event *event)
struct hw_perf_event *hwc = &event->hw;
u64 config;
+ if (is_no_counter_event(event))
+ return 0;
+
if (!is_sampling_event(event)) {
hwc->sample_period = x86_pmu.max_period;
hwc->last_period = hwc->sample_period;
@@ -1209,6 +1212,12 @@ static int x86_pmu_add(struct perf_event *event, int flags)
hwc = &event->hw;
n0 = cpuc->n_events;
+
+ if (is_no_counter_event(event)) {
+ n = n0;
+ goto done_collect;
+ }
+
ret = n = collect_events(cpuc, event, false);
if (ret < 0)
goto out;
@@ -1387,6 +1396,9 @@ static void x86_pmu_del(struct perf_event *event, int flags)
if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
goto do_del;
+ if (is_no_counter_event(event))
+ goto do_del;
+
/*
* Not a TXN, therefore cleanup properly.
*/
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 53c500f..e58a997 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1009,6 +1009,11 @@ static inline bool is_sampling_event(struct perf_event *event)
return event->attr.sample_period != 0;
}
+static inline bool is_no_counter_event(struct perf_event *event)
+{
+ return event->attr.no_counter;
+}
+
/*
* Return 1 for a software event, 0 for a hardware event
*/
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 9de8780..ec97a70 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -372,7 +372,8 @@ struct perf_event_attr {
context_switch : 1, /* context switch data */
write_backward : 1, /* Write ring buffer from end to beginning */
namespaces : 1, /* include namespaces data */
- __reserved_1 : 35;
+ no_counter : 1, /* no counter allocation */
+ __reserved_1 : 34;
union {
__u32 wakeup_events; /* wakeup every n events */
--
2.7.4
Powered by blists - more mailing lists