All of lore.kernel.org
 help / color / mirror / Atom feed
From: Like Xu <like.xu@linux.intel.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: like.xu@intel.com, wei.w.wang@intel.com,
	Andi Kleen <ak@linux.intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Kan Liang <kan.liang@linux.intel.com>,
	Ingo Molnar <mingo@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: [RFC] [PATCH v2 1/5] perf/x86: avoid host changing counter state for kvm_intel events holder
Date: Sat, 23 Mar 2019 22:18:04 +0800	[thread overview]
Message-ID: <1553350688-39627-2-git-send-email-like.xu@linux.intel.com> (raw)
In-Reply-To: <1553350688-39627-1-git-send-email-like.xu@linux.intel.com>

When an perf_event is used by intel vPMU, the vPMU would be responsible
for updating its event_base and config_base. Just checking the writes not
including reading helps perf_events run as usual.

Signed-off-by: Wei Wang <wei.w.wang@intel.com>
Signed-off-by: Like Xu <like.xu@linux.intel.com>
---
 arch/x86/events/core.c       | 37 +++++++++++++++++++++++++++++++++----
 arch/x86/events/intel/core.c |  5 +++--
 arch/x86/events/perf_event.h | 13 +++++++++----
 3 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index e2b1447..d4b5fc0 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -1120,6 +1120,35 @@ static void x86_pmu_enable(struct pmu *pmu)
 static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
 
 /*
+ * If this is an event used by intel vPMU,
+ * intel_kvm_pmu would be responsible for updating the HW.
+ */
+void x86_perf_event_set_event_base(struct perf_event *event,
+	unsigned long val)
+{
+	if (event->attr.exclude_host &&
+			boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+		return;
+
+	wrmsrl(event->hw.event_base, val);
+}
+
+void x86_perf_event_set_config_base(struct perf_event *event,
+	unsigned long val, bool set_extra_config)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (event->attr.exclude_host &&
+			boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+		return;
+
+	if (set_extra_config)
+		wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
+
+	wrmsrl(event->hw.config_base, val);
+}
+
+/*
  * Set the next IRQ period, based on the hwc->period_left value.
  * To be called with the event disabled in hw:
  */
@@ -1169,17 +1198,17 @@ int x86_perf_event_set_period(struct perf_event *event)
 	 */
 	local64_set(&hwc->prev_count, (u64)-left);
 
-	wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
+	x86_perf_event_set_event_base(event,
+		(u64)(-left) & x86_pmu.cntval_mask);
 
 	/*
 	 * Due to erratum on certan cpu we need
 	 * a second write to be sure the register
 	 * is updated properly
 	 */
-	if (x86_pmu.perfctr_second_write) {
-		wrmsrl(hwc->event_base,
+	if (x86_pmu.perfctr_second_write)
+		x86_perf_event_set_event_base(event,
 			(u64)(-left) & x86_pmu.cntval_mask);
-	}
 
 	perf_event_update_userpage(event);
 
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 8baa441..817257c 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2061,6 +2061,7 @@ static inline void intel_pmu_ack_status(u64 ack)
 
 static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
 {
+	struct perf_event *event = container_of(hwc, struct perf_event, hw);
 	int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
 	u64 ctrl_val, mask;
 
@@ -2068,7 +2069,7 @@ static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
 
 	rdmsrl(hwc->config_base, ctrl_val);
 	ctrl_val &= ~mask;
-	wrmsrl(hwc->config_base, ctrl_val);
+	x86_perf_event_set_config_base(event, ctrl_val, false);
 }
 
 static inline bool event_is_checkpointed(struct perf_event *event)
@@ -2148,7 +2149,7 @@ static void intel_pmu_enable_fixed(struct perf_event *event)
 	rdmsrl(hwc->config_base, ctrl_val);
 	ctrl_val &= ~mask;
 	ctrl_val |= bits;
-	wrmsrl(hwc->config_base, ctrl_val);
+	x86_perf_event_set_config_base(event, ctrl_val, false);
 }
 
 static void intel_pmu_enable_event(struct perf_event *event)
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index a759557..3029960 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -726,6 +726,11 @@ static inline bool x86_pmu_has_lbr_callstack(void)
 
 int x86_perf_event_set_period(struct perf_event *event);
 
+void x86_perf_event_set_config_base(struct perf_event *event,
+	unsigned long val, bool set_extra_config);
+void x86_perf_event_set_event_base(struct perf_event *event,
+	unsigned long val);
+
 /*
  * Generalized hw caching related hw_event table, filled
  * in on a per model basis. A value of 0 means
@@ -785,11 +790,11 @@ static inline int x86_pmu_rdpmc_index(int index)
 static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
 					  u64 enable_mask)
 {
+	struct perf_event *event = container_of(hwc, struct perf_event, hw);
 	u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask);
 
-	if (hwc->extra_reg.reg)
-		wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
-	wrmsrl(hwc->config_base, (hwc->config | enable_mask) & ~disable_mask);
+	x86_perf_event_set_config_base(event,
+		(hwc->config | enable_mask) & ~disable_mask, true);
 }
 
 void x86_pmu_enable_all(int added);
@@ -804,7 +809,7 @@ static inline void x86_pmu_disable_event(struct perf_event *event)
 {
 	struct hw_perf_event *hwc = &event->hw;
 
-	wrmsrl(hwc->config_base, hwc->config);
+	x86_perf_event_set_config_base(event, hwc->config, false);
 }
 
 void x86_pmu_enable_event(struct perf_event *event);
-- 
1.8.3.1

  reply	other threads:[~2019-03-23 14:18 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-23 14:18 [RFC] [PATCH v2 0/5] Intel Virtual PMU Optimization Like Xu
2019-03-23 14:18 ` Like Xu [this message]
2019-03-23 14:18 ` [RFC] [PATCH v2 2/5] KVM/x86/vPMU: add pmc operations for vmx and count to track release Like Xu
2019-03-23 14:18 ` [RFC] [PATCH v2 3/5] KVM/x86/vPMU: add Intel vPMC enable/disable and save/restore support Like Xu
2019-03-23 14:18 ` [RFC] [PATCH v2 4/5] KVM/x86/vPMU: add vCPU scheduling support for hw-assigned vPMC Like Xu
2019-03-23 14:18 ` [RFC] [PATCH v2 5/5] KVM/x86/vPMU: not do reprogram_counter for Intel " Like Xu
2019-03-23 17:28 ` [RFC] [PATCH v2 0/5] Intel Virtual PMU Optimization Peter Zijlstra
2019-03-23 23:15   ` Andi Kleen
2019-03-25  6:07     ` Like Xu
2019-03-25  6:47   ` Like Xu
2019-03-25  7:19     ` Peter Zijlstra
2019-03-25 15:58       ` Andi Kleen
2019-04-01  9:08       ` Wei Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1553350688-39627-2-git-send-email-like.xu@linux.intel.com \
    --to=like.xu@linux.intel.com \
    --cc=ak@linux.intel.com \
    --cc=kan.liang@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=like.xu@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=wei.w.wang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.