| From eb68ed122d6c4ff90d1084734af3684d700e1135 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 21 Jun 2021 13:12:38 +0200 |
| Subject: locking/lockdep: Improve noinstr vs errors |
| |
| From: Peter Zijlstra <peterz@infradead.org> |
| |
| [ Upstream commit 49faa77759b211fff344898edc23bb780707fff5 ] |
| |
| Better handle the failure paths. |
| |
| vmlinux.o: warning: objtool: debug_locks_off()+0x23: call to console_verbose() leaves .noinstr.text section |
| vmlinux.o: warning: objtool: debug_locks_off()+0x19: call to __kasan_check_write() leaves .noinstr.text section |
| |
| debug_locks_off+0x19/0x40: |
| instrument_atomic_write at include/linux/instrumented.h:86 |
| (inlined by) __debug_locks_off at include/linux/debug_locks.h:17 |
| (inlined by) debug_locks_off at lib/debug_locks.c:41 |
| |
| Fixes: 6eebad1ad303 ("lockdep: __always_inline more for noinstr") |
| Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Link: https://lore.kernel.org/r/20210621120120.784404944@infradead.org |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/linux/debug_locks.h | 2 ++ |
| kernel/locking/lockdep.c | 4 +++- |
| lib/debug_locks.c | 2 +- |
| 3 files changed, 6 insertions(+), 2 deletions(-) |
| |
| diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h |
| index 2915f56ad421..edb5c186b0b7 100644 |
| --- a/include/linux/debug_locks.h |
| +++ b/include/linux/debug_locks.h |
| @@ -27,8 +27,10 @@ extern int debug_locks_off(void); |
| int __ret = 0; \ |
| \ |
| if (!oops_in_progress && unlikely(c)) { \ |
| + instrumentation_begin(); \ |
| if (debug_locks_off() && !debug_locks_silent) \ |
| WARN(1, "DEBUG_LOCKS_WARN_ON(%s)", #c); \ |
| + instrumentation_end(); \ |
| __ret = 1; \ |
| } \ |
| __ret; \ |
| diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c |
| index f39c383c7180..5bf6b1659215 100644 |
| --- a/kernel/locking/lockdep.c |
| +++ b/kernel/locking/lockdep.c |
| @@ -842,7 +842,7 @@ static int count_matching_names(struct lock_class *new_class) |
| } |
| |
| /* used from NMI context -- must be lockless */ |
| -static __always_inline struct lock_class * |
| +static noinstr struct lock_class * |
| look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass) |
| { |
| struct lockdep_subclass_key *key; |
| @@ -850,12 +850,14 @@ look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass) |
| struct lock_class *class; |
| |
| if (unlikely(subclass >= MAX_LOCKDEP_SUBCLASSES)) { |
| + instrumentation_begin(); |
| debug_locks_off(); |
| printk(KERN_ERR |
| "BUG: looking up invalid subclass: %u\n", subclass); |
| printk(KERN_ERR |
| "turning off the locking correctness validator.\n"); |
| dump_stack(); |
| + instrumentation_end(); |
| return NULL; |
| } |
| |
| diff --git a/lib/debug_locks.c b/lib/debug_locks.c |
| index 06d3135bd184..a75ee30b77cb 100644 |
| --- a/lib/debug_locks.c |
| +++ b/lib/debug_locks.c |
| @@ -36,7 +36,7 @@ EXPORT_SYMBOL_GPL(debug_locks_silent); |
| /* |
| * Generic 'turn off all lock debugging' function: |
| */ |
| -noinstr int debug_locks_off(void) |
| +int debug_locks_off(void) |
| { |
| if (debug_locks && __debug_locks_off()) { |
| if (!debug_locks_silent) { |
| -- |
| 2.30.2 |
| |