From: Byungchul Park <byungchul.park@lge.com>
To: lkp@lists.01.org
Subject: Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2
Date: Tue, 10 Oct 2017 14:57:01 +0900 [thread overview]
Message-ID: <20171010055701.GE3323@X58A-UD3R> (raw)
In-Reply-To: <20171004083430.kajx4yvppalb7lgz@hirez.programming.kicks-ass.net>
[-- Attachment #1: Type: text/plain, Size: 4393 bytes --]
On Wed, Oct 04, 2017 at 10:34:30AM +0200, Peter Zijlstra wrote:
> Right, and print_circular_bug() uses @trace before it ever can be set,
> although I suspect the intention is that that only ever gets called from
> commit_xhlock() where we pass in an initialized @trace. A comment
> would've been good :/
>
> So the whole point of that trace wankery here is to not do save_trace()
> when we'll not in fact use the stack trace.
>
> It seems to me we can do that much saner by actually initializing our
> @trace buffer and testing if it contains an actual stacktrace.
>
> Also killed that verbose thing, because dropping that graph_lock thing
> hurts my brain -- although I think it should work.
>
> Does this make the corruption thing go away?
The commit ae813308f(locking/lockdep: Avoid creating redundant links)
seems to introduce the bug.
But as you may think, another commit ce07a9415(locking/lockdep: Make
check_prev_add() able to handle external stack_trace) is also fragile.
So I like your following patch which makes code robust.
Acked-by: byungchul.park(a)lge.com
> ---
> kernel/locking/lockdep.c | 48 ++++++++++++++++++++----------------------------
> 1 file changed, 20 insertions(+), 28 deletions(-)
>
> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index 44c8d0d17170..e36e652d996f 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c
> @@ -1873,10 +1873,10 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
> struct held_lock *next, int distance, struct stack_trace *trace,
> int (*save)(struct stack_trace *trace))
> {
> + struct lock_list *uninitialized_var(target_entry);
> struct lock_list *entry;
> - int ret;
> struct lock_list this;
> - struct lock_list *uninitialized_var(target_entry);
> + int ret;
>
> /*
> * Prove that the new <prev> -> <next> dependency would not
> @@ -1890,8 +1890,17 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
> this.class = hlock_class(next);
> this.parent = NULL;
> ret = check_noncircular(&this, hlock_class(prev), &target_entry);
> - if (unlikely(!ret))
> + if (unlikely(!ret)) {
> + if (!trace->entries) {
> + /*
> + * If @save fails here, the printing might trigger
> + * a WARN but because of the !nr_entries it should
> + * not do bad things.
> + */
> + save(trace);
> + }
> return print_circular_bug(&this, target_entry, next, prev, trace);
> + }
> else if (unlikely(ret < 0))
> return print_bfs_bug(ret);
>
> @@ -1938,7 +1947,7 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
> return print_bfs_bug(ret);
>
>
> - if (save && !save(trace))
> + if (!trace->entries && !save(trace))
> return 0;
>
> /*
> @@ -1958,20 +1967,6 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
> if (!ret)
> return 0;
>
> - /*
> - * Debugging printouts:
> - */
> - if (verbose(hlock_class(prev)) || verbose(hlock_class(next))) {
> - graph_unlock();
> - printk("\n new dependency: ");
> - print_lock_name(hlock_class(prev));
> - printk(KERN_CONT " => ");
> - print_lock_name(hlock_class(next));
> - printk(KERN_CONT "\n");
> - dump_stack();
> - if (!graph_lock())
> - return 0;
> - }
> return 2;
> }
>
> @@ -1986,8 +1981,12 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
> {
> int depth = curr->lockdep_depth;
> struct held_lock *hlock;
> - struct stack_trace trace;
> - int (*save)(struct stack_trace *trace) = save_trace;
> + struct stack_trace trace = {
> + .nr_entries = 0,
> + .max_entries = 0,
> + .entries = NULL,
> + .skip = 0,
> + };
>
> /*
> * Debugging checks.
> @@ -2018,17 +2017,10 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
> */
> if (hlock->read != 2 && hlock->check) {
> int ret = check_prev_add(curr, hlock, next,
> - distance, &trace, save);
> + distance, &trace, save_trace);
> if (!ret)
> return 0;
>
> - /*
> - * Stop saving stack_trace if save_trace() was
> - * called at least once:
> - */
> - if (save && ret == 2)
> - save = NULL;
> -
> /*
> * Stop after the first non-trylock entry,
> * as non-trylock entries have added their
WARNING: multiple messages have this Message-ID (diff)
From: Byungchul Park <byungchul.park@lge.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>,
Fengguang Wu <fengguang.wu@intel.com>,
Ingo Molnar <mingo@kernel.org>,
linux-kernel@vger.kernel.org, LKP <lkp@01.org>,
kernel-team@lge.com
Subject: Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2
Date: Tue, 10 Oct 2017 14:57:01 +0900 [thread overview]
Message-ID: <20171010055701.GE3323@X58A-UD3R> (raw)
In-Reply-To: <20171004083430.kajx4yvppalb7lgz@hirez.programming.kicks-ass.net>
On Wed, Oct 04, 2017 at 10:34:30AM +0200, Peter Zijlstra wrote:
> Right, and print_circular_bug() uses @trace before it ever can be set,
> although I suspect the intention is that that only ever gets called from
> commit_xhlock() where we pass in an initialized @trace. A comment
> would've been good :/
>
> So the whole point of that trace wankery here is to not do save_trace()
> when we'll not in fact use the stack trace.
>
> It seems to me we can do that much saner by actually initializing our
> @trace buffer and testing if it contains an actual stacktrace.
>
> Also killed that verbose thing, because dropping that graph_lock thing
> hurts my brain -- although I think it should work.
>
> Does this make the corruption thing go away?
The commit ae813308f(locking/lockdep: Avoid creating redundant links)
seems to introduce the bug.
But as you may think, another commit ce07a9415(locking/lockdep: Make
check_prev_add() able to handle external stack_trace) is also fragile.
So I like your following patch which makes code robust.
Acked-by: byungchul.park@lge.com
> ---
> kernel/locking/lockdep.c | 48 ++++++++++++++++++++----------------------------
> 1 file changed, 20 insertions(+), 28 deletions(-)
>
> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index 44c8d0d17170..e36e652d996f 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c
> @@ -1873,10 +1873,10 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
> struct held_lock *next, int distance, struct stack_trace *trace,
> int (*save)(struct stack_trace *trace))
> {
> + struct lock_list *uninitialized_var(target_entry);
> struct lock_list *entry;
> - int ret;
> struct lock_list this;
> - struct lock_list *uninitialized_var(target_entry);
> + int ret;
>
> /*
> * Prove that the new <prev> -> <next> dependency would not
> @@ -1890,8 +1890,17 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
> this.class = hlock_class(next);
> this.parent = NULL;
> ret = check_noncircular(&this, hlock_class(prev), &target_entry);
> - if (unlikely(!ret))
> + if (unlikely(!ret)) {
> + if (!trace->entries) {
> + /*
> + * If @save fails here, the printing might trigger
> + * a WARN but because of the !nr_entries it should
> + * not do bad things.
> + */
> + save(trace);
> + }
> return print_circular_bug(&this, target_entry, next, prev, trace);
> + }
> else if (unlikely(ret < 0))
> return print_bfs_bug(ret);
>
> @@ -1938,7 +1947,7 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
> return print_bfs_bug(ret);
>
>
> - if (save && !save(trace))
> + if (!trace->entries && !save(trace))
> return 0;
>
> /*
> @@ -1958,20 +1967,6 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
> if (!ret)
> return 0;
>
> - /*
> - * Debugging printouts:
> - */
> - if (verbose(hlock_class(prev)) || verbose(hlock_class(next))) {
> - graph_unlock();
> - printk("\n new dependency: ");
> - print_lock_name(hlock_class(prev));
> - printk(KERN_CONT " => ");
> - print_lock_name(hlock_class(next));
> - printk(KERN_CONT "\n");
> - dump_stack();
> - if (!graph_lock())
> - return 0;
> - }
> return 2;
> }
>
> @@ -1986,8 +1981,12 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
> {
> int depth = curr->lockdep_depth;
> struct held_lock *hlock;
> - struct stack_trace trace;
> - int (*save)(struct stack_trace *trace) = save_trace;
> + struct stack_trace trace = {
> + .nr_entries = 0,
> + .max_entries = 0,
> + .entries = NULL,
> + .skip = 0,
> + };
>
> /*
> * Debugging checks.
> @@ -2018,17 +2017,10 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
> */
> if (hlock->read != 2 && hlock->check) {
> int ret = check_prev_add(curr, hlock, next,
> - distance, &trace, save);
> + distance, &trace, save_trace);
> if (!ret)
> return 0;
>
> - /*
> - * Stop saving stack_trace if save_trace() was
> - * called at least once:
> - */
> - if (save && ret == 2)
> - save = NULL;
> -
> /*
> * Stop after the first non-trylock entry,
> * as non-trylock entries have added their
next prev parent reply other threads:[~2017-10-10 5:57 UTC|newest]
Thread overview: 102+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-03 14:06 [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2 Fengguang Wu
2017-10-03 14:06 ` Fengguang Wu
2017-10-03 14:31 ` Josh Poimboeuf
2017-10-03 14:31 ` Josh Poimboeuf
2017-10-03 14:41 ` Josh Poimboeuf
2017-10-03 14:41 ` Josh Poimboeuf
2017-10-03 15:05 ` Josh Poimboeuf
2017-10-03 15:05 ` Josh Poimboeuf
2017-10-03 16:28 ` Josh Poimboeuf
2017-10-03 16:28 ` Josh Poimboeuf
2017-10-03 17:34 ` Josh Poimboeuf
2017-10-03 17:34 ` Josh Poimboeuf
2017-10-03 21:44 ` Tetsuo Handa
2017-10-03 21:44 ` Tetsuo Handa
2017-10-04 21:06 ` Josh Poimboeuf
2017-10-04 21:06 ` Josh Poimboeuf
2017-10-04 21:30 ` Linus Torvalds
2017-10-04 21:30 ` Linus Torvalds
2017-10-04 22:15 ` Josh Poimboeuf
2017-10-04 22:15 ` Josh Poimboeuf
2017-10-04 22:40 ` Josh Poimboeuf
2017-10-04 22:40 ` Josh Poimboeuf
2017-10-05 11:02 ` Tetsuo Handa
2017-10-05 11:02 ` Tetsuo Handa
2017-10-05 13:57 ` Josh Poimboeuf
2017-10-05 13:57 ` Josh Poimboeuf
2017-10-04 8:34 ` Peter Zijlstra
2017-10-04 8:34 ` Peter Zijlstra
2017-10-10 5:57 ` Byungchul Park [this message]
2017-10-10 5:57 ` Byungchul Park
2017-10-03 16:54 ` Linus Torvalds
2017-10-03 16:54 ` Linus Torvalds
2017-10-03 16:57 ` Linus Torvalds
2017-10-03 16:57 ` Linus Torvalds
2017-10-10 5:48 ` Byungchul Park
2017-10-10 5:48 ` Byungchul Park
2017-10-10 16:22 ` Linus Torvalds
2017-10-10 16:22 ` Linus Torvalds
2017-10-10 16:56 ` Linus Torvalds
2017-10-10 16:56 ` Linus Torvalds
2017-10-10 18:14 ` Peter Zijlstra
2017-10-10 18:14 ` Peter Zijlstra
2017-10-10 18:38 ` Linus Torvalds
2017-10-10 18:38 ` Linus Torvalds
2017-10-11 1:14 ` Byungchul Park
2017-10-11 1:14 ` Byungchul Park
2017-10-11 2:36 ` Byungchul Park
2017-10-11 2:36 ` Byungchul Park
2017-10-11 0:56 ` Byungchul Park
2017-10-11 0:56 ` Byungchul Park
2017-10-11 1:02 ` Byungchul Park
2017-10-11 1:02 ` Byungchul Park
2017-10-12 1:15 ` Byungchul Park
2017-10-12 1:15 ` Byungchul Park
2017-10-03 17:18 ` Ingo Molnar
2017-10-03 17:18 ` Ingo Molnar
2017-10-04 9:20 ` Peter Zijlstra
2017-10-04 9:20 ` Peter Zijlstra
2017-10-04 10:31 ` Ingo Molnar
2017-10-04 10:31 ` Ingo Molnar
2017-10-04 14:15 ` Josh Poimboeuf
2017-10-04 14:15 ` Josh Poimboeuf
2017-10-10 5:30 ` Byungchul Park
2017-10-10 5:30 ` Byungchul Park
2017-10-05 13:01 ` Josh Poimboeuf
2017-10-05 13:01 ` Josh Poimboeuf
2017-10-05 14:54 ` Josh Poimboeuf
2017-10-05 14:54 ` Josh Poimboeuf
2017-10-09 10:50 ` Peter Zijlstra
2017-10-09 10:50 ` Peter Zijlstra
2017-10-09 12:21 ` Fengguang Wu
2017-10-09 12:21 ` Fengguang Wu
2017-10-09 12:54 ` Peter Zijlstra
2017-10-09 12:54 ` Peter Zijlstra
2017-10-09 12:59 ` Fengguang Wu
2017-10-09 12:59 ` Fengguang Wu
2017-10-09 13:03 ` Josh Poimboeuf
2017-10-09 13:03 ` Josh Poimboeuf
2017-10-09 12:55 ` Fengguang Wu
2017-10-09 12:55 ` Fengguang Wu
2017-10-09 13:26 ` Josh Poimboeuf
2017-10-09 13:26 ` Josh Poimboeuf
2017-10-09 14:17 ` Fengguang Wu
2017-10-09 14:17 ` Fengguang Wu
2017-10-09 15:28 ` Peter Zijlstra
2017-10-09 15:28 ` Peter Zijlstra
2017-10-09 15:41 ` Fengguang Wu
2017-10-09 15:41 ` Fengguang Wu
2017-10-09 15:44 ` Peter Zijlstra
2017-10-09 15:44 ` Peter Zijlstra
2017-10-09 15:47 ` Fengguang Wu
2017-10-09 15:47 ` Fengguang Wu
2017-10-10 5:08 ` Byungchul Park
2017-10-10 5:08 ` Byungchul Park
2017-10-12 8:47 ` Peter Zijlstra
2017-10-12 8:47 ` Peter Zijlstra
2017-10-12 9:21 ` Fengguang Wu
2017-10-12 9:21 ` Fengguang Wu
2017-10-12 9:28 ` Fengguang Wu
2017-10-12 9:28 ` Fengguang Wu
2017-10-12 11:45 ` Peter Zijlstra
2017-10-12 11:45 ` Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171010055701.GE3323@X58A-UD3R \
--to=byungchul.park@lge.com \
--cc=lkp@lists.01.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.