Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752217AbdC0Sqo (ORCPT ); Mon, 27 Mar 2017 14:46:44 -0400 Received: from mga01.intel.com ([192.55.52.88]:25922 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751692AbdC0SqL (ORCPT ); Mon, 27 Mar 2017 14:46:11 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,232,1486454400"; d="scan'208";a="71036339" From: kan.liang@intel.com To: peterz@infradead.org, tglx@linutronix.de, mingo@redhat.com, linux-kernel@vger.kernel.org Cc: bp@alien8.de, acme@kernel.org, eranian@google.com, jolsa@kernel.org, ak@linux.intel.com, Kan Liang Subject: [PATCH V3 1/2] x86/msr: add msr_set/clear_bit_on_cpu/cpus access functions Date: Mon, 27 Mar 2017 11:30:47 -0700 Message-Id: <1490639448-4147-2-git-send-email-kan.liang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1490639448-4147-1-git-send-email-kan.liang@intel.com> References: <1490639448-4147-1-git-send-email-kan.liang@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4221 Lines: 156 From: Kan Liang To flip a MSR bit on many CPUs or specific CPU, currently it has to do read-modify-write operation on the MSR through rd/wrmsr_on_cpu(s). It actually sends two IPIs to the given CPU. It is necessory to extend the single operation - msr_set/clear_bit - on many CPUs or given CPU. It only sends one IPI to the given CPU, and simplify MSR content manipulation. The new functions wrap the smp_call_function* boilerplate code. Signed-off-by: Kan Liang --- arch/x86/include/asm/msr.h | 25 +++++++++++++++ arch/x86/lib/msr-smp.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 898dba2..bfd83ab 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -25,6 +25,7 @@ struct msr_info { struct msr reg; struct msr *msrs; int err; + u8 bit; }; struct msr_regs_info { @@ -314,6 +315,10 @@ int msr_set_bit(u32 msr, u8 bit); int msr_clear_bit(u32 msr, u8 bit); #ifdef CONFIG_SMP +int msr_set_bit_on_cpu(unsigned int cpu, u32 msr, u8 bit); +int msr_clear_bit_on_cpu(unsigned int cpu, u32 msr, u8 bit); +void msr_set_bit_on_cpus(const struct cpumask *mask, u32 msr, u8 bit); +void msr_clear_bit_on_cpus(const struct cpumask *mask, u32 msr, u8 bit); int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q); @@ -327,6 +332,26 @@ int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q); int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); #else /* CONFIG_SMP */ +static inline int msr_set_bit_on_cpu(unsigned int cpu, u32 msr, u8 bit) +{ + return msr_set_bit(msr, bit); +} + +static inline int msr_clear_bit_on_cpu(unsigned int cpu, u32 msr, u8 bit) +{ + return msr_clear_bit(msr, bit); +} + +static inline void msr_set_bit_on_cpus(const struct cpumask *mask, u32 msr, u8 bit) +{ + msr_set_bit(msr, bit); +} + +static inline void msr_clear_bit_on_cpus(const struct cpumask *mask, u32 msr, u8 bit) +{ + msr_clear_bit(msr, bit); +} + static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) { rdmsr(msr_no, *l, *h); diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c index ce68b6a..8e704d9 100644 --- a/arch/x86/lib/msr-smp.c +++ b/arch/x86/lib/msr-smp.c @@ -3,6 +3,82 @@ #include #include +static void __msr_set_bit_on_cpu(void *info) +{ + struct msr_info *bit_info = info; + + msr_set_bit(bit_info->msr_no, bit_info->bit); +} + +static void __msr_clear_bit_on_cpu(void *info) +{ + struct msr_info *bit_info = info; + + msr_clear_bit(bit_info->msr_no, bit_info->bit); +} + +int msr_set_bit_on_cpu(unsigned int cpu, u32 msr, u8 bit) +{ + struct msr_info info; + int err; + + info.msr_no = msr; + info.bit = bit; + + err = smp_call_function_single(cpu, __msr_set_bit_on_cpu, &info, 1); + + return err; +} +EXPORT_SYMBOL(msr_set_bit_on_cpu); + +int msr_clear_bit_on_cpu(unsigned int cpu, u32 msr, u8 bit) +{ + struct msr_info info; + int err; + + info.msr_no = msr; + info.bit = bit; + + err = smp_call_function_single(cpu, __msr_clear_bit_on_cpu, &info, 1); + + return err; +} +EXPORT_SYMBOL(msr_clear_bit_on_cpu); + +void msr_set_bit_on_cpus(const struct cpumask *mask, u32 msr, u8 bit) +{ + struct msr_info info; + int this_cpu; + + info.msr_no = msr; + info.bit = bit; + + this_cpu = get_cpu(); + if (cpumask_test_cpu(this_cpu, mask)) + __msr_set_bit_on_cpu(&info); + + smp_call_function_many(mask, __msr_set_bit_on_cpu, &info, 1); + put_cpu(); +} +EXPORT_SYMBOL(msr_set_bit_on_cpus); + +void msr_clear_bit_on_cpus(const struct cpumask *mask, u32 msr, u8 bit) +{ + struct msr_info info; + int this_cpu; + + info.msr_no = msr; + info.bit = bit; + + this_cpu = get_cpu(); + if (cpumask_test_cpu(this_cpu, mask)) + __msr_clear_bit_on_cpu(&info); + + smp_call_function_many(mask, __msr_clear_bit_on_cpu, &info, 1); + put_cpu(); +} +EXPORT_SYMBOL(msr_clear_bit_on_cpus); + static void __rdmsr_on_cpu(void *info) { struct msr_info *rv = info; -- 2.7.4