Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752982AbdHJMW1 (ORCPT ); Thu, 10 Aug 2017 08:22:27 -0400 Received: from terminus.zytor.com ([65.50.211.136]:57519 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752779AbdHJMWZ (ORCPT ); Thu, 10 Aug 2017 08:22:25 -0400 Date: Thu, 10 Aug 2017 05:18:50 -0700 From: tip-bot for Byungchul Park Message-ID: Cc: mingo@kernel.org, hpa@zytor.com, byungchul.park@lge.com, tglx@linutronix.de, torvalds@linux-foundation.org, linux-kernel@vger.kernel.org, peterz@infradead.org Reply-To: linux-kernel@vger.kernel.org, peterz@infradead.org, torvalds@linux-foundation.org, tglx@linutronix.de, byungchul.park@lge.com, hpa@zytor.com, mingo@kernel.org In-Reply-To: <1502089981-21272-3-git-send-email-byungchul.park@lge.com> References: <1502089981-21272-3-git-send-email-byungchul.park@lge.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:locking/core] locking/lockdep: Add a function building a chain between two classes Git-Commit-ID: 49347a986ab45eb1dafbf25170647c890f8ff192 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 Content-Length: 3586 Lines: 113 Commit-ID: 49347a986ab45eb1dafbf25170647c890f8ff192 Gitweb: http://git.kernel.org/tip/49347a986ab45eb1dafbf25170647c890f8ff192 Author: Byungchul Park AuthorDate: Mon, 7 Aug 2017 16:12:49 +0900 Committer: Ingo Molnar CommitDate: Thu, 10 Aug 2017 12:29:05 +0200 locking/lockdep: Add a function building a chain between two classes Crossrelease needs to build a chain between two classes regardless of their contexts. However, add_chain_cache() cannot be used for that purpose since it assumes that it's called in the acquisition context of the hlock. So this patch introduces a new function doing it. Signed-off-by: Byungchul Park Signed-off-by: Peter Zijlstra (Intel) Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: akpm@linux-foundation.org Cc: boqun.feng@gmail.com Cc: kernel-team@lge.com Cc: kirill@shutemov.name Cc: npiggin@gmail.com Cc: walken@google.com Cc: willy@infradead.org Link: http://lkml.kernel.org/r/1502089981-21272-3-git-send-email-byungchul.park@lge.com Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index e029f2f..bdf6b31 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -2151,6 +2151,76 @@ static int check_no_collision(struct task_struct *curr, } /* + * This is for building a chain between just two different classes, + * instead of adding a new hlock upon current, which is done by + * add_chain_cache(). + * + * This can be called in any context with two classes, while + * add_chain_cache() must be done within the lock owener's context + * since it uses hlock which might be racy in another context. + */ +static inline int add_chain_cache_classes(unsigned int prev, + unsigned int next, + unsigned int irq_context, + u64 chain_key) +{ + struct hlist_head *hash_head = chainhashentry(chain_key); + struct lock_chain *chain; + + /* + * Allocate a new chain entry from the static array, and add + * it to the hash: + */ + + /* + * We might need to take the graph lock, ensure we've got IRQs + * disabled to make this an IRQ-safe lock.. for recursion reasons + * lockdep won't complain about its own locking errors. + */ + if (DEBUG_LOCKS_WARN_ON(!irqs_disabled())) + return 0; + + if (unlikely(nr_lock_chains >= MAX_LOCKDEP_CHAINS)) { + if (!debug_locks_off_graph_unlock()) + return 0; + + print_lockdep_off("BUG: MAX_LOCKDEP_CHAINS too low!"); + dump_stack(); + return 0; + } + + chain = lock_chains + nr_lock_chains++; + chain->chain_key = chain_key; + chain->irq_context = irq_context; + chain->depth = 2; + if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) { + chain->base = nr_chain_hlocks; + nr_chain_hlocks += chain->depth; + chain_hlocks[chain->base] = prev - 1; + chain_hlocks[chain->base + 1] = next -1; + } +#ifdef CONFIG_DEBUG_LOCKDEP + /* + * Important for check_no_collision(). + */ + else { + if (!debug_locks_off_graph_unlock()) + return 0; + + print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); + dump_stack(); + return 0; + } +#endif + + hlist_add_head_rcu(&chain->entry, hash_head); + debug_atomic_inc(chain_lookup_misses); + inc_chains(); + + return 1; +} + +/* * Adds a dependency chain into chain hashtable. And must be called with * graph_lock held. *