Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2eda956 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "lockdep: suppress extra lockdep logging"

parents 4ecd8d60 1ed46cb3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -740,6 +740,7 @@ CONFIG_PANIC_ON_RT_THROTTLING=y
CONFIG_SCHEDSTATS=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_LOCK_TORTURE_TEST=m
CONFIG_DEBUG_SG=y
+2 −0
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ struct lockdep_map {
#ifdef CONFIG_LOCK_STAT
	int				cpu;
	unsigned long			ip;
	unsigned long			ip_caller;
#endif
};

@@ -233,6 +234,7 @@ struct held_lock {
	 */
	u64				prev_chain_key;
	unsigned long			acquire_ip;
	unsigned long			acquire_ip_caller;
	struct lockdep_map		*instance;
	struct lockdep_map		*nest_lock;
#ifdef CONFIG_LOCK_STAT
+149 −69
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@
#include <linux/nmi.h>

#include <asm/sections.h>
#include <asm/stacktrace.h>

#include "lockdep_internals.h"

@@ -72,6 +73,30 @@ module_param(lock_stat, int, 0644);
#define lock_stat 0
#endif

static int lockdep_log = 1;

static int lockdep_logging_off(void)
{
	if (lockdep_log && xchg(&lockdep_log, 0)) {
		if (!debug_locks_silent)
			return 1;
	}
	return 0;
}

#define MAX_ITR 20
#define lockdep_warn_on(cond)						\
({									\
	int __ret = 0;							\
									\
	if (!oops_in_progress && unlikely(cond)) {                      \
		if (lockdep_logging_off() && !debug_locks_silent)       \
			WARN(1, "lockdep_warn_on(%s)", #cond);          \
		__ret = 1;						\
	}								\
	__ret;								\
})

/*
 * lockdep_lock: protects the lockdep graph, the hashes and the
 *               class/list/hash allocators.
@@ -107,7 +132,7 @@ static inline int graph_unlock(void)
		 * The lockdep graph lock isn't locked while we expect it to
		 * be, we're confused now, bye!
		 */
		return DEBUG_LOCKS_WARN_ON(1);
		return lockdep_warn_on(1);
	}

	current->lockdep_recursion--;
@@ -115,6 +140,14 @@ static inline int graph_unlock(void)
	return 0;
}

static int lockdep_logging_off_graph_unlock(void)
{
	int ret = lockdep_logging_off();

	graph_unlock();
	return ret;
}

/*
 * Turn lock debugging off and return with 0 if it was off already,
 * and also release the graph lock:
@@ -146,7 +179,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
		/*
		 * Someone passed in garbage, we give up.
		 */
		DEBUG_LOCKS_WARN_ON(1);
		lockdep_warn_on(1);
		return NULL;
	}
	return lock_classes + hlock->class_idx - 1;
@@ -413,7 +446,7 @@ static int save_trace(struct stack_trace *trace)
	nr_stack_trace_entries += trace->nr_entries;

	if (nr_stack_trace_entries >= MAX_STACK_TRACE_ENTRIES-1) {
		if (!debug_locks_off_graph_unlock())
		if (!lockdep_logging_off_graph_unlock())
			return 0;

		print_lockdep_off("BUG: MAX_STACK_TRACE_ENTRIES too low!");
@@ -720,10 +753,8 @@ static bool assign_lock_key(struct lockdep_map *lock)
		lock->key = (void *)lock;
	else {
		/* Debug-check: all keys must be persistent! */
		debug_locks_off();
		pr_err("INFO: trying to register non-static key.\n");
		pr_err("the code is fine but needs lockdep annotation.\n");
		pr_err("turning off the locking correctness validator.\n");
		dump_stack();
		return false;
	}
@@ -1193,7 +1224,7 @@ static noinline int print_circular_bug(struct lock_list *this,
	struct lock_list *first_parent;
	int depth;

	if (!debug_locks_off_graph_unlock() || debug_locks_silent)
	if (!lockdep_logging_off_graph_unlock() || debug_locks_silent)
		return 0;

	if (!save_trace(&this->trace))
@@ -1508,7 +1539,7 @@ print_bad_irq_dependency(struct task_struct *curr,
			 enum lock_usage_bit bit2,
			 const char *irqclass)
{
	if (!debug_locks_off_graph_unlock() || debug_locks_silent)
	if (!lockdep_logging_off_graph_unlock() || debug_locks_silent)
		return 0;

	pr_warn("\n");
@@ -1737,7 +1768,7 @@ static int
print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
		   struct held_lock *next)
{
	if (!debug_locks_off_graph_unlock() || debug_locks_silent)
	if (!lockdep_logging_off_graph_unlock() || debug_locks_silent)
		return 0;

	pr_warn("\n");
@@ -2000,7 +2031,7 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
	}
	return 1;
out_bug:
	if (!debug_locks_off_graph_unlock())
	if (!lockdep_logging_off_graph_unlock())
		return 0;

	/*
@@ -2130,7 +2161,7 @@ static int check_no_collision(struct task_struct *curr,

	i = get_first_held_lock(curr, hlock);

	if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1))) {
	if (lockdep_warn_on(chain->depth != curr->lockdep_depth - (i - 1))) {
		print_collision(curr, hlock, chain);
		return 0;
	}
@@ -2138,7 +2169,7 @@ static int check_no_collision(struct task_struct *curr,
	for (j = 0; j < chain->depth - 1; j++, i++) {
		id = curr->held_locks[i].class_idx - 1;

		if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id)) {
		if (lockdep_warn_on(chain_hlocks[chain->base + j] != id)) {
			print_collision(curr, hlock, chain);
			return 0;
		}
@@ -2399,7 +2430,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
		int ret = check_deadlock(curr, hlock, lock, hlock->read);

		if (!ret)
			return 0;
			return 1;
		/*
		 * Mark recursive read, as we jump over it when
		 * building dependencies (just like we jump over
@@ -2413,7 +2444,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
		 */
		if (!chain_head && ret != 2) {
			if (!check_prevs_add(curr, hlock))
				return 0;
				return 1;
		}

		graph_unlock();
@@ -2507,7 +2538,7 @@ static int
print_usage_bug(struct task_struct *curr, struct held_lock *this,
		enum lock_usage_bit prev_bit, enum lock_usage_bit new_bit)
{
	if (!debug_locks_off_graph_unlock() || debug_locks_silent)
	if (!lockdep_logging_off_graph_unlock() || debug_locks_silent)
		return 0;

	pr_warn("\n");
@@ -2572,7 +2603,7 @@ print_irq_inversion_bug(struct task_struct *curr,
	struct lock_list *middle = NULL;
	int depth;

	if (!debug_locks_off_graph_unlock() || debug_locks_silent)
	if (!lockdep_logging_off_graph_unlock() || debug_locks_silent)
		return 0;

	pr_warn("\n");
@@ -2992,40 +3023,41 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock)
			if (curr->hardirq_context)
				if (!mark_lock(curr, hlock,
						LOCK_USED_IN_HARDIRQ_READ))
					return 0;
					goto out;
			if (curr->softirq_context)
				if (!mark_lock(curr, hlock,
						LOCK_USED_IN_SOFTIRQ_READ))
					return 0;
					goto out;
		} else {
			if (curr->hardirq_context)
				if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ))
					return 0;
					goto out;
			if (curr->softirq_context)
				if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ))
					return 0;
					goto out;
		}
	}
	if (!hlock->hardirqs_off) {
		if (hlock->read) {
			if (!mark_lock(curr, hlock,
					LOCK_ENABLED_HARDIRQ_READ))
				return 0;
				goto out;
			if (curr->softirqs_enabled)
				if (!mark_lock(curr, hlock,
						LOCK_ENABLED_SOFTIRQ_READ))
					return 0;
					goto out;
		} else {
			if (!mark_lock(curr, hlock,
					LOCK_ENABLED_HARDIRQ))
				return 0;
				goto out;
			if (curr->softirqs_enabled)
				if (!mark_lock(curr, hlock,
						LOCK_ENABLED_SOFTIRQ))
					return 0;
					goto out;
		}
	}

out:
	return 1;
}

@@ -3132,7 +3164,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
		debug_atomic_dec(nr_unused_locks);
		break;
	default:
		if (!debug_locks_off_graph_unlock())
		if (!lockdep_logging_off_graph_unlock())
			return 0;
		WARN_ON(1);
		return 0;
@@ -3171,7 +3203,7 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name,
	/*
	 * Can't be having no nameless bastards around this place!
	 */
	if (DEBUG_LOCKS_WARN_ON(!name)) {
	if (lockdep_warn_on(!name)) {
		lock->name = "NULL";
		return;
	}
@@ -3181,17 +3213,22 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name,
	/*
	 * No key, no joy, we need to hash something.
	 */
	if (DEBUG_LOCKS_WARN_ON(!key))
	if (lockdep_warn_on(!key))
		return;
	/*
	 * Sanity check, the lock-class key must be persistent:
	 */
	if (!static_obj(key)) {
		/*
		 * to make sure register_lock_class returns NULL
		 * for a non static key
		 */
		lock->key = key;
		printk("BUG: key %px not in .data!\n", key);
		/*
		 * What it says above ^^^^^, I suggest you read it.
		 */
		DEBUG_LOCKS_WARN_ON(1);
		lockdep_warn_on(1);
		return;
	}
	lock->key = key;
@@ -3202,7 +3239,7 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name,
	if (subclass) {
		unsigned long flags;

		if (DEBUG_LOCKS_WARN_ON(current->lockdep_recursion))
		if (lockdep_warn_on(current->lockdep_recursion))
			return;

		raw_local_irq_save(flags);
@@ -3228,9 +3265,7 @@ print_lock_nested_lock_not_held(struct task_struct *curr,
				struct held_lock *hlock,
				unsigned long ip)
{
	if (!debug_locks_off())
		return 0;
	if (debug_locks_silent)
	if (!lockdep_logging_off() || debug_locks_silent)
		return 0;

	pr_warn("\n");
@@ -3259,6 +3294,33 @@ print_lock_nested_lock_not_held(struct task_struct *curr,

static int __lock_is_held(const struct lockdep_map *lock, int read);

static unsigned long lockdep_walk_stack(unsigned long addr)
{
	int ret;
	struct stackframe frame;
	struct task_struct *tsk = current;
	bool end_search = false;
	int counter = 0;

	frame.fp = (unsigned long)__builtin_frame_address(0);
	frame.pc = (unsigned long)lockdep_walk_stack;

	while (counter < MAX_ITR) {
		counter++;
		if (frame.pc == addr)
			end_search = true;

		ret = unwind_frame(tsk, &frame);
		if ((ret < 0) || end_search)
			break;
	}

	if (unlikely(ret < 0) || unlikely(counter == MAX_ITR))
		return 0;
	else
		return frame.pc;
}

/*
 * This gets called for every mutex_lock*()/spin_lock*() operation.
 * We maintain the dependency maps and validate the locking attempt:
@@ -3266,7 +3328,8 @@ static int __lock_is_held(const struct lockdep_map *lock, int read);
static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
			  int trylock, int read, int check, int hardirqs_off,
			  struct lockdep_map *nest_lock, unsigned long ip,
			  int references, int pin_count)
			  int references, int pin_count,
			  unsigned long ip_caller)
{
	struct task_struct *curr = current;
	struct lock_class *class = NULL;
@@ -3347,7 +3410,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
	 * Plain impossible, we just registered it and checked it weren't no
	 * NULL like.. I bet this mushroom I ate was good!
	 */
	if (DEBUG_LOCKS_WARN_ON(!class))
	if (lockdep_warn_on(!class))
		return 0;
	hlock->class_idx = class_idx;
	hlock->acquire_ip = ip;
@@ -3364,13 +3427,16 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
	hlock->holdtime_stamp = lockstat_clock();
#endif
	hlock->pin_count = pin_count;
	if (!ip_caller)
		hlock->acquire_ip_caller = lockdep_walk_stack(ip);
	else
		hlock->acquire_ip_caller = ip_caller;

	if (check && !mark_irqflags(curr, hlock))
		return 0;

	/* mark it as used: */
	if (!mark_lock(curr, hlock, LOCK_USED))
		return 0;
	mark_lock(curr, hlock, LOCK_USED);

	/*
	 * Calculate the chain hash: it's the combined hash of all the
@@ -3393,7 +3459,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
		/*
		 * How can we have a chain hash when we ain't got no keys?!
		 */
		if (DEBUG_LOCKS_WARN_ON(chain_key != 0))
		if (lockdep_warn_on(chain_key != 0))
			return 0;
		chain_head = 1;
	}
@@ -3441,9 +3507,7 @@ static int
print_unlock_imbalance_bug(struct task_struct *curr, struct lockdep_map *lock,
			   unsigned long ip)
{
	if (!debug_locks_off())
		return 0;
	if (debug_locks_silent)
	if (!lockdep_logging_off() || debug_locks_silent)
		return 0;

	pr_warn("\n");
@@ -3492,7 +3556,7 @@ static int match_held_lock(const struct held_lock *hlock,
		 * State got messed up, follow the sites that change ->references
		 * and try to make sense of it.
		 */
		if (DEBUG_LOCKS_WARN_ON(!hlock->nest_lock))
		if (lockdep_warn_on(!hlock->nest_lock))
			return 0;

		if (hlock->class_idx == class - lock_classes + 1)
@@ -3550,7 +3614,8 @@ static int reacquire_held_locks(struct task_struct *curr, unsigned int depth,
				    hlock->read, hlock->check,
				    hlock->hardirqs_off,
				    hlock->nest_lock, hlock->acquire_ip,
				    hlock->references, hlock->pin_count))
				    hlock->references, hlock->pin_count,
				    hlock->acquire_ip_caller))
			return 1;
	}
	return 0;
@@ -3572,7 +3637,7 @@ __lock_set_class(struct lockdep_map *lock, const char *name,
	 * This function is about (re)setting the class of a held lock,
	 * yet we're not actually holding any locks. Naughty user!
	 */
	if (DEBUG_LOCKS_WARN_ON(!depth))
	if (lockdep_warn_on(!depth))
		return 0;

	hlock = find_held_lock(curr, lock, depth, &i);
@@ -3581,6 +3646,9 @@ __lock_set_class(struct lockdep_map *lock, const char *name,

	lockdep_init_map(lock, name, key, 0);
	class = register_lock_class(lock, subclass, 0);
	if (!class)
		return 0;

	hlock->class_idx = class - lock_classes + 1;

	curr->lockdep_depth = i;
@@ -3593,7 +3661,7 @@ __lock_set_class(struct lockdep_map *lock, const char *name,
	 * I took it apart and put it back together again, except now I have
	 * these 'spare' parts.. where shall I put them.
	 */
	if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth))
	if (lockdep_warn_on(curr->lockdep_depth != depth))
		return 0;
	return 1;
}
@@ -3613,7 +3681,7 @@ static int __lock_downgrade(struct lockdep_map *lock, unsigned long ip)
	 * This function is about (re)setting the class of a held lock,
	 * yet we're not actually holding any locks. Naughty user!
	 */
	if (DEBUG_LOCKS_WARN_ON(!depth))
	if (lockdep_warn_on(!depth))
		return 0;

	hlock = find_held_lock(curr, lock, depth, &i);
@@ -3623,9 +3691,12 @@ static int __lock_downgrade(struct lockdep_map *lock, unsigned long ip)
	curr->lockdep_depth = i;
	curr->curr_chain_key = hlock->prev_chain_key;

	if (lockdep_logging_off())
		WARN(hlock->read, "downgrading a read lock");

	hlock->read = 1;
	hlock->acquire_ip = ip;
	hlock->acquire_ip_caller = lockdep_walk_stack(ip);

	if (reacquire_held_locks(curr, depth, i))
		return 0;
@@ -3634,7 +3705,7 @@ static int __lock_downgrade(struct lockdep_map *lock, unsigned long ip)
	 * I took it apart and put it back together again, except now I have
	 * these 'spare' parts.. where shall I put them.
	 */
	if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth))
	if (lockdep_warn_on(curr->lockdep_depth != depth))
		return 0;
	return 1;
}
@@ -3662,7 +3733,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip)
	 * So we're all set to release this lock.. wait what lock? We don't
	 * own any locks, you've been drinking again?
	 */
	if (DEBUG_LOCKS_WARN_ON(depth <= 0))
	if (lockdep_warn_on(depth <= 0))
		return print_unlock_imbalance_bug(curr, lock, ip);

	/*
@@ -3676,6 +3747,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip)
	if (hlock->instance == lock)
		lock_release_holdtime(hlock);

	if (lockdep_logging_off())
		WARN(hlock->pin_count, "releasing a pinned lock\n");

	if (hlock->references) {
@@ -3706,7 +3778,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip)
	 * We had N bottles of beer on the wall, we drank one, but now
	 * there's not N-1 bottles of beer left on the wall...
	 */
	if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth - 1))
	if (lockdep_warn_on(curr->lockdep_depth != depth - 1))
		return 0;

	return 1;
@@ -3755,7 +3827,9 @@ static struct pin_cookie __lock_pin_lock(struct lockdep_map *lock)
		}
	}

	if (lockdep_logging_off())
		WARN(1, "pinning an unheld lock\n");

	return cookie;
}

@@ -3776,6 +3850,7 @@ static void __lock_repin_lock(struct lockdep_map *lock, struct pin_cookie cookie
		}
	}

	if (lockdep_logging_off())
		WARN(1, "pinning an unheld lock\n");
}

@@ -3791,18 +3866,25 @@ static void __lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie cookie
		struct held_lock *hlock = curr->held_locks + i;

		if (match_held_lock(hlock, lock)) {
			if (WARN(!hlock->pin_count, "unpinning an unpinned lock\n"))
			if (!hlock->pin_count) {
				if (lockdep_logging_off())
					WARN(1, "unpinning an unpinned lock\n");
				return;
			}

			hlock->pin_count -= cookie.val;

			if (WARN((int)hlock->pin_count < 0, "pin count corrupted\n"))
			if ((int)hlock->pin_count < 0) {
				if (lockdep_logging_off())
					WARN(1, "pin count corrupted\n");
				hlock->pin_count = 0;
			}

			return;
		}
	}

	if (lockdep_logging_off())
		WARN(1, "unpinning an unheld lock\n");
}

@@ -3901,7 +3983,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
	current->lockdep_recursion = 1;
	trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
	__lock_acquire(lock, subclass, trylock, read, check,
		       irqs_disabled_flags(flags), nest_lock, ip, 0, 0);
		       irqs_disabled_flags(flags), nest_lock, ip, 0, 0, 0);
	current->lockdep_recursion = 0;
	raw_local_irq_restore(flags);
}
@@ -4005,9 +4087,7 @@ static int
print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock,
			   unsigned long ip)
{
	if (!debug_locks_off())
		return 0;
	if (debug_locks_silent)
	if (!lockdep_logging_off() || debug_locks_silent)
		return 0;

	pr_warn("\n");
@@ -4044,7 +4124,7 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip)
	 * Whee, we contended on this lock, except it seems we're not
	 * actually trying to acquire anything much at all..
	 */
	if (DEBUG_LOCKS_WARN_ON(!depth))
	if (lockdep_warn_on(!depth))
		return;

	hlock = find_held_lock(curr, lock, depth, &i);
@@ -4086,7 +4166,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip)
	 * Yay, we acquired ownership of this lock we didn't try to
	 * acquire, how the heck did that happen?
	 */
	if (DEBUG_LOCKS_WARN_ON(!depth))
	if (lockdep_warn_on(!depth))
		return;

	hlock = find_held_lock(curr, lock, depth, &i);
@@ -4119,6 +4199,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip)

	lock->cpu = cpu;
	lock->ip = ip;
	lock->ip_caller = lockdep_walk_stack(ip);
}

void lock_contended(struct lockdep_map *lock, unsigned long ip)
@@ -4298,7 +4379,7 @@ void lockdep_reset_lock(struct lockdep_map *lock)
				match |= class == lock->class_cache[j];

			if (unlikely(match)) {
				if (debug_locks_off_graph_unlock()) {
				if (lockdep_logging_off_graph_unlock()) {
					/*
					 * We all just reset everything, how did it match?
					 */
@@ -4347,9 +4428,7 @@ static void
print_freed_lock_bug(struct task_struct *curr, const void *mem_from,
		     const void *mem_to, struct held_lock *hlock)
{
	if (!debug_locks_off())
		return;
	if (debug_locks_silent)
	if (!lockdep_logging_off() || debug_locks_silent)
		return;

	pr_warn("\n");
@@ -4405,9 +4484,7 @@ EXPORT_SYMBOL_GPL(debug_check_no_locks_freed);

static void print_held_locks_bug(void)
{
	if (!debug_locks_off())
		return;
	if (debug_locks_silent)
	if (!lockdep_logging_off() || debug_locks_silent)
		return;

	pr_warn("\n");
@@ -4474,7 +4551,7 @@ asmlinkage __visible void lockdep_sys_exit(void)
	struct task_struct *curr = current;

	if (unlikely(curr->lockdep_depth)) {
		if (!debug_locks_off())
		if (!lockdep_logging_off())
			return;
		pr_warn("\n");
		pr_warn("================================================\n");
@@ -4497,6 +4574,9 @@ void lockdep_rcu_suspicious(const char *file, const int line, const char *s)
{
	struct task_struct *curr = current;

	if (!lockdep_logging_off())
		return;

	/* Note: the following can be executed concurrently, so be careful. */
	pr_warn("\n");
	pr_warn("=============================\n");