From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757280AbbDPOuc (ORCPT ); Thu, 16 Apr 2015 10:50:32 -0400 Received: from www.linutronix.de ([62.245.132.108]:44377 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753985AbbDPOuY (ORCPT ); Thu, 16 Apr 2015 10:50:24 -0400 Message-ID: <552FCC2D.4050304@linutronix.de> Date: Thu, 16 Apr 2015 16:50:21 +0200 From: Sebastian Andrzej Siewior User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.5.0 MIME-Version: 1.0 To: Peter Zijlstra CC: linux-kernel@vger.kernel.org, Ingo Molnar , Andreas Messerschmid Subject: Re: [PATCH] lockdep: make print_lock_name() robust against non-existing lock_class References: <1429104276-22412-1-git-send-email-bigeasy@linutronix.de> <20150415141440.GQ23123@twins.programming.kicks-ass.net> In-Reply-To: <20150415141440.GQ23123@twins.programming.kicks-ass.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 04/15/2015 04:14 PM, Peter Zijlstra wrote: > On Wed, Apr 15, 2015 at 03:24:36PM +0200, Sebastian Andrzej Siewior wrote: >> During sysrq's show-held-locks command it is possible that hlock_class() >> returns NULL for a given lock. The result is then (after the warning): >> >> |BUG: unable to handle kernel NULL pointer dereference at 0000001c >> |IP: [] get_usage_chars+0x5/0x100 >> |Call Trace: >> | [] print_lock_name+0x23/0x60 >> | [] print_lock+0x5d/0x7e >> | [] lockdep_print_held_locks+0x74/0xe0 >> | [] debug_show_all_locks+0x132/0x1b0 >> | [] sysrq_handle_showlocks+0x8/0x10 >> >> This *might* happen because the thread on the other CPU drops the lock >> after we are looking ->lockdep_depth and ->held_locks points no longer >> to a lock that is held. >> The fix here is to simply ignore it and continue. > > Hmm, but in that case we might equally run into the hlock_class() debug > check which would kill all of lockdep. > > Note that lock_release_nested() with CONFIG_DEBUG_LOCKDEP will actually > clear those fields. > > Would something like the below work for you? Andreas confirmed that it works for him on v3.18 with minor adjustment. <--- + struct held_lock lock = READ_ONCE(*hlock); + unsigned int class_idx = lock.class_idx; ---> So, yes, thanks. > --- > kernel/locking/lockdep.c | 13 ++++++++++++- > 1 file changed, 12 insertions(+), 1 deletion(-) > > diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c > index ba77ab5f64dd..0ef89f830ff4 100644 > --- a/kernel/locking/lockdep.c > +++ b/kernel/locking/lockdep.c > @@ -551,7 +551,18 @@ static void print_lockdep_cache(struct lockdep_map *lock) > > static void print_lock(struct held_lock *hlock) > { > - print_lock_name(hlock_class(hlock)); > + /* > + * We can be called locklessly through debug_show_all_locks() so be > + * extra careful, the hlock might have been released and cleared. > + */ > + unsigned int class_idx = READ_ONCE(hlock->class_idx); > + > + if (!class_idx || (class_idx - 1) >= MAX_LOCKDEP_KEYS) { > + printk("\n"); > + return; > + } > + > + print_lock_name(lock_classes + class_idx - 1); > printk(", at: "); > print_ip_sym(hlock->acquire_ip); > } > Sebastian