locking/lockdep: Improve noinstr vs errors
authorPeter Zijlstra <peterz@infradead.org>
Mon, 21 Jun 2021 11:12:38 +0000 (13:12 +0200)
committerIngo Molnar <mingo@kernel.org>
Tue, 22 Jun 2021 11:56:43 +0000 (13:56 +0200)
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
include/linux/debug_locks.h
kernel/locking/lockdep.c
lib/debug_locks.c

index 2915f56..edb5c18 100644 (file)
@@ -27,8 +27,10 @@ extern int debug_locks_off(void);
        int __ret = 0;                                                  \
                                                                        \
        if (!oops_in_progress && unlikely(c)) {                         \
        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);         \
                if (debug_locks_off() && !debug_locks_silent)           \
                        WARN(1, "DEBUG_LOCKS_WARN_ON(%s)", #c);         \
+               instrumentation_end();                                  \
                __ret = 1;                                              \
        }                                                               \
        __ret;                                                          \
                __ret = 1;                                              \
        }                                                               \
        __ret;                                                          \
index 7641bd4..e323130 100644 (file)
@@ -843,7 +843,7 @@ static int count_matching_names(struct lock_class *new_class)
 }
 
 /* used from NMI context -- must be lockless */
 }
 
 /* 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;
 look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass)
 {
        struct lockdep_subclass_key *key;
@@ -851,12 +851,14 @@ look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass)
        struct lock_class *class;
 
        if (unlikely(subclass >= MAX_LOCKDEP_SUBCLASSES)) {
        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();
                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;
        }
 
                return NULL;
        }
 
index 06d3135..a75ee30 100644 (file)
@@ -36,7 +36,7 @@ EXPORT_SYMBOL_GPL(debug_locks_silent);
 /*
  * Generic 'turn off all lock debugging' function:
  */
 /*
  * 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) {
 {
        if (debug_locks && __debug_locks_off()) {
                if (!debug_locks_silent) {