From: Ashish Kalra The existing wrmsr_on_cpus() takes a per-cpu struct msr array, requiring callers to allocate and populate per-cpu storage even when every CPU receives the same value. This is unnecessary overhead for the common case of writing a single uniform u64 to a per-CPU MSR across multiple CPUs. Add wrmsrq_on_cpus() which writes the same u64 value to the specified MSR on all CPUs in the given cpumask. Co-developed-by: Dave Hansen Signed-off-by: Dave Hansen Reviewed-by: Ackerley Tng Signed-off-by: Ashish Kalra --- arch/x86/include/asm/msr.h | 5 +++++ arch/x86/lib/msr-smp.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 9c2ea29e12a9..f5f63b4115c8 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -260,6 +260,7 @@ 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 rdmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 *q); int wrmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 q); +void wrmsrq_on_cpus(const struct cpumask *mask, u32 msr_no, u64 q); void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr __percpu *msrs); void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr __percpu *msrs); int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); @@ -289,6 +290,10 @@ static inline int wrmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 q) wrmsrq(msr_no, q); return 0; } +static inline void wrmsrq_on_cpus(const struct cpumask *mask, u32 msr_no, u64 q) +{ + wrmsrq_on_cpu(0, msr_no, q); +} static inline void rdmsr_on_cpus(const struct cpumask *m, u32 msr_no, struct msr __percpu *msrs) { diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c index b8f63419e6ae..d2c91c9bb47b 100644 --- a/arch/x86/lib/msr-smp.c +++ b/arch/x86/lib/msr-smp.c @@ -94,6 +94,26 @@ int wrmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 q) } EXPORT_SYMBOL(wrmsrq_on_cpu); +void wrmsrq_on_cpus(const struct cpumask *mask, u32 msr_no, u64 q) +{ + struct msr_info rv; + int this_cpu; + + memset(&rv, 0, sizeof(rv)); + + rv.msr_no = msr_no; + rv.reg.q = q; + + this_cpu = get_cpu(); + + if (cpumask_test_cpu(this_cpu, mask)) + __wrmsr_on_cpu(&rv); + + smp_call_function_many(mask, __wrmsr_on_cpu, &rv, 1); + put_cpu(); +} +EXPORT_SYMBOL(wrmsrq_on_cpus); + static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr __percpu *msrs, void (*msr_func) (void *info)) -- 2.43.0