[33/45] lockdep: Swap storage for pin_count and refereneces

Submitted by Chris Wilson on April 25, 2019, 9:19 a.m.

Details

Message ID 20190425092004.9995-33-chris@chris-wilson.co.uk
State New
Headers show
Series "Series without cover letter" ( rev: 2 1 ) in Intel GFX

Browsing this patch as part of:
"Series without cover letter" rev 1 in Intel GFX
<< prev patch [33/45] next patch >>

Commit Message

Chris Wilson April 25, 2019, 9:19 a.m.
As a lockmap takes a reference for every ww_mutex used together, this
can be an arbitrarily large number and under control of userspace --
easily overflowing the limit of 4096.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 include/linux/lockdep.h  |  4 ++--
 kernel/locking/lockdep.c | 15 +++++++++------
 2 files changed, 11 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 79c3873d58ac..2dc4a61d7355 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -262,8 +262,8 @@  struct held_lock {
 	unsigned int read:2;        /* see lock_acquire() comment */
 	unsigned int check:1;       /* see lock_acquire() comment */
 	unsigned int hardirqs_off:1;
-	unsigned int references:12;					/* 32 bits */
-	unsigned int pin_count;
+	unsigned int pin_count:12;					/* 32 bits */
+	unsigned int references;
 };
 
 /*
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e221be724fe8..e83bfc520a28 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -3613,9 +3613,9 @@  static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
 		if (hlock->class_idx == class_idx && nest_lock) {
 			if (hlock->references) {
 				/*
-				 * Check: unsigned int references:12, overflow.
+				 * Check: unsigned int references overflow.
 				 */
-				if (DEBUG_LOCKS_WARN_ON(hlock->references == (1 << 12)-1))
+				if (DEBUG_LOCKS_WARN_ON(hlock->references == UINT_MAX))
 					return 0;
 
 				hlock->references++;
@@ -4053,11 +4053,14 @@  static struct pin_cookie __lock_pin_lock(struct lockdep_map *lock)
 
 		if (match_held_lock(hlock, lock)) {
 			/*
-			 * Grab 16bits of randomness; this is sufficient to not
-			 * be guessable and still allows some pin nesting in
-			 * our u32 pin_count.
+			 * Grab 6bits of randomness; this is barely sufficient
+			 * to not be guessable and still allows some 32 levels
+			 * of pin nesting in our u12 pin_count.
 			 */
-			cookie.val = 1 + (prandom_u32() >> 16);
+			cookie.val = 1 + (prandom_u32() >> 26);
+			if (DEBUG_LOCKS_WARN_ON(hlock->pin_count + cookie.val >= 1 << 12))
+				return NIL_COOKIE;
+
 			hlock->pin_count += cookie.val;
 			return cookie;
 		}