From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751978AbcFWIoA (ORCPT ); Thu, 23 Jun 2016 04:44:00 -0400 Received: from bombadil.infradead.org ([198.137.202.9]:60172 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751634AbcFWIn6 (ORCPT ); Thu, 23 Jun 2016 04:43:58 -0400 Date: Thu, 23 Jun 2016 10:43:53 +0200 From: Peter Zijlstra To: David Carrillo-Cisneros Cc: linux-kernel@vger.kernel.org, "x86@kernel.org" , Ingo Molnar , Andi Kleen , Kan Liang Subject: Re: [PATCH v02 4/5] perf/x86/intel: MSR_LAST_BRANCH_FROM_x quirk for ctx switch Message-ID: <20160623084353.GH30154@twins.programming.kicks-ass.net> References: <1466533874-52003-1-git-send-email-davidcc@google.com> <1466533874-52003-5-git-send-email-davidcc@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1466533874-52003-5-git-send-email-davidcc@google.com> User-Agent: Mutt/1.5.23.1 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Jun 21, 2016 at 11:31:13AM -0700, David Carrillo-Cisneros wrote: > @@ -297,7 +312,8 @@ static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx) > tos = task_ctx->tos; > for (i = 0; i < tos; i++) { > lbr_idx = (tos - i) & mask; > - wrmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]); > + wrmsrl(x86_pmu.lbr_from + lbr_idx, > + lbr_from_signext_quirk_wr(task_ctx->lbr_from[i])); > wrmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]); > if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO) > wrmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]); > @@ -321,7 +337,8 @@ static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx) > tos = intel_pmu_lbr_tos(); > for (i = 0; i < tos; i++) { > lbr_idx = (tos - i) & mask; > - rdmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]); > + rdmsrl(x86_pmu.lbr_from + lbr_idx, val); > + task_ctx->lbr_from[i] = lbr_from_signext_quirk_rd(val); > rdmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]); > if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO) > rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]); > @@ -499,6 +516,8 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) > int lbr_flags = lbr_desc[lbr_format]; > > rdmsrl(x86_pmu.lbr_from + lbr_idx, from); > + from = lbr_from_signext_quirk_rd(from); > + > rdmsrl(x86_pmu.lbr_to + lbr_idx, to); > > if (lbr_format == LBR_FORMAT_INFO && need_info) { I did this on top... --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -288,12 +288,42 @@ inline u64 lbr_from_signext_quirk_wr(u64 u64 lbr_from_signext_quirk_rd(u64 val) { - if (static_branch_unlikely(&lbr_from_quirk_key)) + if (static_branch_unlikely(&lbr_from_quirk_key)) { /* * Quirk is on when TSX is not enabled. Therefore TSX * flags must be read as OFF. */ val &= ~(LBR_FROM_FLAG_IN_TX | LBR_FROM_FLAG_ABORT); + } + return val; +} + +static inline void wrlbr_from(unsigned int idx, u64 val) +{ + val = lbr_from_signext_quirk_wr(val); + wrmsrl(x86_pmu.lbr_from + idx, val); +} + +static inline void wrlbr_to(unsigned int idx, u64 val) +{ + wrmsrl(x86_pmu.lbr_to + idx, val); +} + +static inline u64 rdlbr_from(unsigned int idx) +{ + u64 val; + + rdmsrl(x86_pmu.lbr_from + idx, val); + + return lbr_from_signext_quirk_rd(val); +} + +static inline u64 rdlbr_to(unsigned int idx) +{ + u64 val; + + rdmsrl(x86_pmu.lbr_from + idx, val); + return val; } @@ -313,9 +343,9 @@ static void __intel_pmu_lbr_restore(stru tos = task_ctx->tos; for (i = 0; i < tos; i++) { lbr_idx = (tos - i) & mask; - wrmsrl(x86_pmu.lbr_from + lbr_idx, - lbr_from_signext_quirk_wr(task_ctx->lbr_from[i])); - wrmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]); + wrlbr_from(lbr_idx, task_ctx->lbr_from[i]); + wrlbr_to (lbr_idx, task_ctx->lbr_to[i]); + if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO) wrmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]); } @@ -325,9 +355,9 @@ static void __intel_pmu_lbr_restore(stru static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx) { - int i; unsigned lbr_idx, mask; - u64 tos, val; + u64 tos; + int i; if (task_ctx->lbr_callstack_users == 0) { task_ctx->lbr_stack_state = LBR_NONE; @@ -338,9 +368,8 @@ static void __intel_pmu_lbr_save(struct tos = intel_pmu_lbr_tos(); for (i = 0; i < tos; i++) { lbr_idx = (tos - i) & mask; - rdmsrl(x86_pmu.lbr_from + lbr_idx, val); - task_ctx->lbr_from[i] = lbr_from_signext_quirk_rd(val); - rdmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]); + task_ctx->lbr_from[i] = rdlbr_from(lbr_idx); + task_ctx->lbr_to[i] = rdlbr_to(lbr_idx); if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO) rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]); } @@ -516,10 +545,8 @@ static void intel_pmu_lbr_read_64(struct u16 cycles = 0; int lbr_flags = lbr_desc[lbr_format]; - rdmsrl(x86_pmu.lbr_from + lbr_idx, from); - from = lbr_from_signext_quirk_rd(from); - - rdmsrl(x86_pmu.lbr_to + lbr_idx, to); + from = rdlbr_from(lbr_idx); + to = rdlbr_to(lbr_idx); if (lbr_format == LBR_FORMAT_INFO && need_info) { u64 info;