From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758775AbcDAGh1 (ORCPT ); Fri, 1 Apr 2016 02:37:27 -0400 Received: from terminus.zytor.com ([198.137.202.10]:32776 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758133AbcDAGhY (ORCPT ); Fri, 1 Apr 2016 02:37:24 -0400 Date: Thu, 31 Mar 2016 23:36:43 -0700 From: tip-bot for Alfredo Alvarez Fernandez Message-ID: Cc: hpa@zytor.com, tglx@linutronix.de, linux-kernel@vger.kernel.org, alfredoalvarezfernandez@gmail.com, mingo@kernel.org, torvalds@linux-foundation.org, peterz@infradead.org Reply-To: peterz@infradead.org, torvalds@linux-foundation.org, mingo@kernel.org, alfredoalvarezfernandez@gmail.com, linux-kernel@vger.kernel.org, tglx@linutronix.de, hpa@zytor.com In-Reply-To: <1459357416-19190-1-git-send-email-alfredoalvarezernandez@gmail.com> References: <1459357416-19190-1-git-send-email-alfredoalvarezernandez@gmail.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:core/urgent] locking/lockdep: Print chain_key collision information Git-Commit-ID: 39e2e173fb1f900959d3a25c21c65fa88b06c6ee 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: 39e2e173fb1f900959d3a25c21c65fa88b06c6ee Gitweb: http://git.kernel.org/tip/39e2e173fb1f900959d3a25c21c65fa88b06c6ee Author: Alfredo Alvarez Fernandez AuthorDate: Wed, 30 Mar 2016 19:03:36 +0200 Committer: Ingo Molnar CommitDate: Thu, 31 Mar 2016 15:03:58 +0200 locking/lockdep: Print chain_key collision information A sequence of pairs [class_idx -> corresponding chain_key iteration] is printed for both the current held_lock chain and the cached chain. That exposes the two different class_idx sequences that led to that particular hash value. This helps with debugging hash chain collision reports. Signed-off-by: Alfredo Alvarez Fernandez Acked-by: Peter Zijlstra (Intel) Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-fsdevel@vger.kernel.org Cc: sedat.dilek@gmail.com Cc: tytso@mit.edu Link: http://lkml.kernel.org/r/1459357416-19190-1-git-send-email-alfredoalvarezernandez@gmail.com Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 53ab2f8..2324ba5 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -2000,6 +2000,77 @@ static inline int get_first_held_lock(struct task_struct *curr, } /* + * Returns the next chain_key iteration + */ +static u64 print_chain_key_iteration(int class_idx, u64 chain_key) +{ + u64 new_chain_key = iterate_chain_key(chain_key, class_idx); + + printk(" class_idx:%d -> chain_key:%016Lx", + class_idx, + (unsigned long long)new_chain_key); + return new_chain_key; +} + +static void +print_chain_keys_held_locks(struct task_struct *curr, struct held_lock *hlock_next) +{ + struct held_lock *hlock; + u64 chain_key = 0; + int depth = curr->lockdep_depth; + int i; + + printk("depth: %u\n", depth + 1); + for (i = get_first_held_lock(curr, hlock_next); i < depth; i++) { + hlock = curr->held_locks + i; + chain_key = print_chain_key_iteration(hlock->class_idx, chain_key); + + print_lock(hlock); + } + + print_chain_key_iteration(hlock_next->class_idx, chain_key); + print_lock(hlock_next); +} + +static void print_chain_keys_chain(struct lock_chain *chain) +{ + int i; + u64 chain_key = 0; + int class_id; + + printk("depth: %u\n", chain->depth); + for (i = 0; i < chain->depth; i++) { + class_id = chain_hlocks[chain->base + i]; + chain_key = print_chain_key_iteration(class_id + 1, chain_key); + + print_lock_name(lock_classes + class_id); + printk("\n"); + } +} + +static void print_collision(struct task_struct *curr, + struct held_lock *hlock_next, + struct lock_chain *chain) +{ + printk("\n"); + printk("======================\n"); + printk("[chain_key collision ]\n"); + print_kernel_ident(); + printk("----------------------\n"); + printk("%s/%d: ", current->comm, task_pid_nr(current)); + printk("Hash chain already cached but the contents don't match!\n"); + + printk("Held locks:"); + print_chain_keys_held_locks(curr, hlock_next); + + printk("Locks in cached chain:"); + print_chain_keys_chain(chain); + + printk("\nstack backtrace:\n"); + dump_stack(); +} + +/* * Checks whether the chain and the current held locks are consistent * in depth and also in content. If they are not it most likely means * that there was a collision during the calculation of the chain_key. @@ -2014,14 +2085,18 @@ static int check_no_collision(struct task_struct *curr, i = get_first_held_lock(curr, hlock); - if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1))) + if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1))) { + print_collision(curr, hlock, chain); return 0; + } for (j = 0; j < chain->depth - 1; j++, i++) { id = curr->held_locks[i].class_idx - 1; - if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id)) + if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id)) { + print_collision(curr, hlock, chain); return 0; + } } #endif return 1;