=== modified file 'include/linux/lockdep.h' --- old/include/linux/lockdep.h 2017-02-02 22:58:27 +0000 +++ new/include/linux/lockdep.h 2017-02-02 23:07:50 +0000 @@ -364,7 +364,7 @@ extern struct pin_cookie lock_pin_lock(s extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie); extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); -# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, +# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, .nolockdep_call = 0, #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) === modified file 'include/linux/sched.h' --- old/include/linux/sched.h 2017-02-02 22:58:27 +0000 +++ new/include/linux/sched.h 2017-02-02 23:07:50 +0000 @@ -1746,6 +1746,9 @@ struct task_struct { # define MAX_LOCK_DEPTH 48UL u64 curr_chain_key; int lockdep_depth; +# define NOLOCKDEP_SUPPORTED 1 + unsigned int nolockdep_call:1; + unsigned int nolockdep_call_irq_saved:1; unsigned int lockdep_recursion; struct held_lock held_locks[MAX_LOCK_DEPTH]; gfp_t lockdep_reclaim_gfp; === modified file 'kernel/locking/lockdep.c' --- old/kernel/locking/lockdep.c 2017-02-02 22:58:27 +0000 +++ new/kernel/locking/lockdep.c 2017-02-02 23:07:50 +0000 @@ -3741,9 +3741,11 @@ void lock_acquire(struct lockdep_map *lo if (unlikely(current->lockdep_recursion)) return; + if (unlikely(current->nolockdep_call)) + return; + raw_local_irq_save(flags); check_flags(flags); - current->lockdep_recursion = 1; trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); __lock_acquire(lock, subclass, trylock, read, check, @@ -3761,6 +3763,9 @@ void lock_release(struct lockdep_map *lo if (unlikely(current->lockdep_recursion)) return; + if (unlikely(current->nolockdep_call)) + return; + raw_local_irq_save(flags); check_flags(flags); current->lockdep_recursion = 1; @@ -4009,6 +4014,9 @@ void lock_contended(struct lockdep_map * if (unlikely(current->lockdep_recursion)) return; + if (unlikely(current->nolockdep_call)) + return; + raw_local_irq_save(flags); check_flags(flags); current->lockdep_recursion = 1; @@ -4029,6 +4037,9 @@ void lock_acquired(struct lockdep_map *l if (unlikely(current->lockdep_recursion)) return; + if (unlikely(current->nolockdep_call)) + return; + raw_local_irq_save(flags); check_flags(flags); current->lockdep_recursion = 1; === modified file 'kernel/softirq.c' --- old/kernel/softirq.c 2017-02-02 22:58:27 +0000 +++ new/kernel/softirq.c 2017-02-02 23:07:50 +0000 @@ -335,6 +335,17 @@ asmlinkage __visible void do_softirq(voi */ void irq_enter(void) { +#ifdef CONFIG_LOCKDEP + if (unlikely(current->nolockdep_call)) { + unsigned long flags; + local_irq_save(flags); + if (current->nolockdep_call) { + current->nolockdep_call_irq_saved = 1; + current->nolockdep_call = 0; + } + local_irq_restore(flags); + } +#endif rcu_irq_enter(); if (is_idle_task(current) && !in_interrupt()) { /* @@ -406,6 +417,17 @@ void irq_exit(void) tick_irq_exit(); rcu_irq_exit(); +#ifdef CONFIG_LOCKDEP + if (unlikely(current->nolockdep_call_irq_saved)) { + unsigned long flags; + local_irq_save(flags); + if (current->nolockdep_call_irq_saved) { + current->nolockdep_call_irq_saved = 0; + current->nolockdep_call = 1; + } + local_irq_restore(flags); + } +#endif trace_hardirq_exit(); /* must be last! */ }