From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751776AbbCTJux (ORCPT ); Fri, 20 Mar 2015 05:50:53 -0400 Received: from bombadil.infradead.org ([198.137.202.9]:45828 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751529AbbCTJuw (ORCPT ); Fri, 20 Mar 2015 05:50:52 -0400 Date: Fri, 20 Mar 2015 10:50:25 +0100 From: Peter Zijlstra To: Andrew Morton Cc: mingo@kernel.org, rusty@rustcorp.com.au, mathieu.desnoyers@efficios.com, oleg@redhat.com, paulmck@linux.vnet.ibm.com, torvalds@linux-foundation.org, linux-kernel@vger.kernel.org, andi@firstfloor.org, rostedt@goodmis.org, tglx@linutronix.de, Michel Lespinasse , Andrea Arcangeli , David Woodhouse , Rik van Riel Subject: Re: [PATCH 6/8] rbtree: Implement generic latch_tree Message-ID: <20150320095025.GG24151@twins.programming.kicks-ass.net> References: <20150318133626.526984618@infradead.org> <20150318134631.939369528@infradead.org> <20150318221446.14b0b04d.akpm@linux-foundation.org> <20150319072502.GR23123@twins.programming.kicks-ass.net> <20150319135833.5a844744936bd8fdafea7ed5@linux-foundation.org> <20150319220433.GS2896@worktop.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150319220433.GS2896@worktop.programming.kicks-ass.net> User-Agent: Mutt/1.5.21 (2012-12-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Mar 19, 2015 at 11:04:33PM +0100, Peter Zijlstra wrote: > On Thu, Mar 19, 2015 at 01:58:33PM -0700, Andrew Morton wrote: > > OK. This code is basically required to support perf/ftrace and > > modules, yes? Presumably small and space-constrained systems aren't > > using either, so they don't take the hit. > > > > However CONFIG_MODULES systems which aren't using perf/ftrace _do_ take > > a hit. How many systems are we talking here? All non-x86? > > No, there's plenty !x86 systems that have NMI and perf/ftrace, in fact, > ARM has them (FIQ) and there's event some ARM chips that use them for > perf (i.MX6 is one). > > But sure, we could make this depend on CONFIG_PERF_EVENTS || > CONFIG_TRACING. A little something like so. Signed-off-by: Peter Zijlstra (Intel) --- kernel/module.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) --- a/kernel/module.c +++ b/kernel/module.c @@ -102,6 +102,8 @@ DEFINE_MUTEX(module_mutex); EXPORT_SYMBOL_GPL(module_mutex); static LIST_HEAD(modules); +#if defined(CONFIG_PERF_EVENTS) || defined(CONFIG_TRACING) + /* * Use a latched RB-tree for __module_address(); this allows us to use * RCU-sched lookups of the address from any context. @@ -109,6 +111,10 @@ static LIST_HEAD(modules); * Because modules have two address ranges: init and core, we need two * latch_tree_nodes entries. We use the order they appear in struct module to * determine if we need to use the init or core values for the comparisons. + * + * This is conditional on PERF_EVENTS || TRACING because those can really hit + * __module_address() hard by doing a lot of stack unwinding; potentially from + * NMI context. */ static __always_inline unsigned long __mod_tree_val(struct latch_tree_node *n) @@ -185,7 +191,7 @@ static void mod_tree_remove(struct modul mod_tree_remove_init(mod); } -static struct module *mod_tree_find(unsigned long addr) +static struct module *mod_find(unsigned long addr) { struct latch_tree_node *ltn; @@ -194,6 +200,26 @@ static struct module *mod_tree_find(unsi return ltn ? ltn->priv : NULL; } +#else /* !(PERF_EVENTS || TRACING) */ + +static void mod_tree_insert(struct module *mod) { } +static void mod_tree_remove_init(struct module *mod) { } +static void mod_tree_remove(struct module *mod) { } + +static struct module *mod_find(unsigned long addr) +{ + struct module *mod; + + list_for_each_entry_rcu(mod, &modules, list) { + if (within_module(addr, mod)) + return mod; + } + + return NULL; +} + +#endif /* !(PERF_EVENTS || TRACING) */ + #ifdef CONFIG_KGDB_KDB struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ #endif /* CONFIG_KGDB_KDB */ @@ -3939,7 +3965,7 @@ struct module *__module_address(unsigned module_assert_mutex_or_preempt(); - mod = mod_tree_find(addr); + mod = mod_find(addr); if (mod) { BUG_ON(!within_module(addr, mod)); if (mod->state == MODULE_STATE_UNFORMED)