From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S945117AbdDTLbo (ORCPT ); Thu, 20 Apr 2017 07:31:44 -0400 Received: from terminus.zytor.com ([65.50.211.136]:57047 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S944650AbdDTLbj (ORCPT ); Thu, 20 Apr 2017 07:31:39 -0400 Date: Thu, 20 Apr 2017 04:29:05 -0700 From: "tip-bot for Peter Zijlstra (Intel)" Message-ID: Cc: mingo@kernel.org, rostedt@goodmis.org, peterz@infradead.org, linux-kernel@vger.kernel.org, tglx@linutronix.de, bigeasy@linutronix.de, hpa@zytor.com Reply-To: bigeasy@linutronix.de, tglx@linutronix.de, hpa@zytor.com, linux-kernel@vger.kernel.org, peterz@infradead.org, rostedt@goodmis.org, mingo@kernel.org In-Reply-To: <20170418103422.590118425@infradead.org> References: <20170418103422.590118425@infradead.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:smp/hotplug] jump_label: Pull get_online_cpus() into generic code Git-Commit-ID: 82947f31231157d8ab70fa8961f23fd3887a3327 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 82947f31231157d8ab70fa8961f23fd3887a3327 Gitweb: http://git.kernel.org/tip/82947f31231157d8ab70fa8961f23fd3887a3327 Author: Peter Zijlstra (Intel) AuthorDate: Tue, 18 Apr 2017 19:05:03 +0200 Committer: Thomas Gleixner CommitDate: Thu, 20 Apr 2017 13:08:57 +0200 jump_label: Pull get_online_cpus() into generic code This change does two things: - it moves the get_online_cpus() call into generic code, with the aim of later providing some static_key ops that avoid it. - as a side effect it inverts the lock order between cpu_hotplug_lock and jump_label_mutex. Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Cc: Sebastian Siewior Cc: Steven Rostedt Cc: jbaron@akamai.com Link: http://lkml.kernel.org/r/20170418103422.590118425@infradead.org --- arch/mips/kernel/jump_label.c | 2 -- arch/sparc/kernel/jump_label.c | 2 -- arch/tile/kernel/jump_label.c | 2 -- arch/x86/kernel/jump_label.c | 2 -- kernel/jump_label.c | 14 ++++++++++++++ 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/arch/mips/kernel/jump_label.c b/arch/mips/kernel/jump_label.c index 3e586da..32e3168 100644 --- a/arch/mips/kernel/jump_label.c +++ b/arch/mips/kernel/jump_label.c @@ -58,7 +58,6 @@ void arch_jump_label_transform(struct jump_entry *e, insn.word = 0; /* nop */ } - get_online_cpus(); mutex_lock(&text_mutex); if (IS_ENABLED(CONFIG_CPU_MICROMIPS)) { insn_p->halfword[0] = insn.word >> 16; @@ -70,7 +69,6 @@ void arch_jump_label_transform(struct jump_entry *e, (unsigned long)insn_p + sizeof(*insn_p)); mutex_unlock(&text_mutex); - put_online_cpus(); } #endif /* HAVE_JUMP_LABEL */ diff --git a/arch/sparc/kernel/jump_label.c b/arch/sparc/kernel/jump_label.c index 07933b9..93adde1 100644 --- a/arch/sparc/kernel/jump_label.c +++ b/arch/sparc/kernel/jump_label.c @@ -41,12 +41,10 @@ void arch_jump_label_transform(struct jump_entry *entry, val = 0x01000000; } - get_online_cpus(); mutex_lock(&text_mutex); *insn = val; flushi(insn); mutex_unlock(&text_mutex); - put_online_cpus(); } #endif diff --git a/arch/tile/kernel/jump_label.c b/arch/tile/kernel/jump_label.c index 07802d5..93931a4 100644 --- a/arch/tile/kernel/jump_label.c +++ b/arch/tile/kernel/jump_label.c @@ -45,14 +45,12 @@ static void __jump_label_transform(struct jump_entry *e, void arch_jump_label_transform(struct jump_entry *e, enum jump_label_type type) { - get_online_cpus(); mutex_lock(&text_mutex); __jump_label_transform(e, type); flush_icache_range(e->code, e->code + sizeof(tilegx_bundle_bits)); mutex_unlock(&text_mutex); - put_online_cpus(); } __init_or_module void arch_jump_label_transform_static(struct jump_entry *e, diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c index c37bd0f..ab4f491 100644 --- a/arch/x86/kernel/jump_label.c +++ b/arch/x86/kernel/jump_label.c @@ -105,11 +105,9 @@ static void __jump_label_transform(struct jump_entry *entry, void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type) { - get_online_cpus(); mutex_lock(&text_mutex); __jump_label_transform(entry, type, NULL, 0); mutex_unlock(&text_mutex); - put_online_cpus(); } static enum { diff --git a/kernel/jump_label.c b/kernel/jump_label.c index 6c9cb20..f3afe07 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef HAVE_JUMP_LABEL @@ -124,6 +125,12 @@ void static_key_slow_inc(struct static_key *key) return; } + /* + * A number of architectures need to synchronize I$ across + * the all CPUs, for that to be serialized against CPU hot-plug + * we need to avoid CPUs coming online. + */ + get_online_cpus(); jump_label_lock(); if (atomic_read(&key->enabled) == 0) { atomic_set(&key->enabled, -1); @@ -133,6 +140,7 @@ void static_key_slow_inc(struct static_key *key) atomic_inc(&key->enabled); } jump_label_unlock(); + put_online_cpus(); } EXPORT_SYMBOL_GPL(static_key_slow_inc); @@ -146,6 +154,7 @@ static void __static_key_slow_dec(struct static_key *key, * returns is unbalanced, because all other static_key_slow_inc() * instances block while the update is in progress. */ + get_online_cpus(); if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) { WARN(atomic_read(&key->enabled) < 0, "jump label: negative count!\n"); @@ -159,6 +168,7 @@ static void __static_key_slow_dec(struct static_key *key, jump_label_update(key); } jump_label_unlock(); + put_online_cpus(); } static void jump_label_update_timeout(struct work_struct *work) @@ -592,6 +602,10 @@ jump_label_module_notify(struct notifier_block *self, unsigned long val, switch (val) { case MODULE_STATE_COMING: + /* + * XXX do we need get_online_cpus() ? the module isn't + * executable yet, so nothing should be looking at our code. + */ jump_label_lock(); ret = jump_label_add_module(mod); if (ret) {