All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] locking/lockdep: Zap lock classes even with lock debugging disabled
@ 2019-04-03 23:35 Bart Van Assche
  2019-04-04  9:36 ` Peter Zijlstra
  2019-04-10 12:13 ` [tip:locking/urgent] " tip-bot for Bart Van Assche
  0 siblings, 2 replies; 3+ messages in thread
From: Bart Van Assche @ 2019-04-03 23:35 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Thomas Gleixner, linux-kernel, Bart Van Assche,
	Will Deacon, Waiman Long, shenghui

Commit a0b0fd53e1e6 ("locking/lockdep: Free lock classes that are no longer
in use") changed the behavior of lockdep_free_key_range() from
unconditionally zapping lock classes into only zapping lock classes if
debug_lock == true. Not zapping lock classes if debug_lock == false leaves
dangling pointers in several lockdep datastructures, e.g. lock_class::name
in the all_lock_classes list. The shell command "cat /proc/lockdep" causes
the kernel to iterate the all_lock_classes list. Hence the "unable to
handle kernel paging request" issue that Shenghui encountered by running
cat /proc/lockdep. Since the new behavior can cause cat /proc/lockdep to
crash, restore the pre-v5.1 behavior.

This patch avoids that cat /proc/lockdep triggers the following crash
with debug_lock == false:

BUG: unable to handle kernel paging request at fffffbfff40ca448
PGD 13bfde067 P4D 13bfde067 PUD 13bf7a067 PMD 1167d3067 PTE 0
Oops: 0000 [#1] PREEMPT SMP KASAN
CPU: 4 PID: 4529 Comm: cat Tainted: G    B   W  O      5.1.0-rc1-dbg+ #4
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
RIP: 0010:__asan_load1+0x28/0x50
Call Trace:
 string+0xac/0x180
 vsnprintf+0x23e/0x820
 seq_vprintf+0x82/0xc0
 seq_printf+0x92/0xb0
 print_name+0x34/0xb0
 l_show+0x184/0x200
 seq_read+0x59e/0x6c0
 proc_reg_read+0x11f/0x170
 __vfs_read+0x4d/0x90
 vfs_read+0xc5/0x1f0
 ksys_read+0xab/0x130
 __x64_sys_read+0x43/0x50
 do_syscall_64+0x71/0x210
 entry_SYSCALL_64_after_hwframe+0x49/0xbe

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Waiman Long <longman@redhat.com>
Cc: shenghui <shhuiw@foxmail.com>
Reported-by: shenghui <shhuiw@foxmail.com>
Fixes: a0b0fd53e1e6 ("locking/lockdep: Free lock classes that are no longer in use") # v5.1-rc1.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
Changes compared to v1:
- Restored lockdep recursion protection.
- Made patch description more detailed.

 kernel/locking/lockdep.c | 29 ++++++++++++-----------------
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 34cdcbedda49..e16766ff184b 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -4689,8 +4689,8 @@ static void free_zapped_rcu(struct rcu_head *ch)
 		return;
 
 	raw_local_irq_save(flags);
-	if (!graph_lock())
-		goto out_irq;
+	arch_spin_lock(&lockdep_lock);
+	current->lockdep_recursion = 1;
 
 	/* closed head */
 	pf = delayed_free.pf + (delayed_free.index ^ 1);
@@ -4702,8 +4702,8 @@ static void free_zapped_rcu(struct rcu_head *ch)
 	 */
 	call_rcu_zapped(delayed_free.pf + delayed_free.index);
 
-	graph_unlock();
-out_irq:
+	current->lockdep_recursion = 0;
+	arch_spin_unlock(&lockdep_lock);
 	raw_local_irq_restore(flags);
 }
 
@@ -4744,21 +4744,17 @@ static void lockdep_free_key_range_reg(void *start, unsigned long size)
 {
 	struct pending_free *pf;
 	unsigned long flags;
-	int locked;
 
 	init_data_structures_once();
 
 	raw_local_irq_save(flags);
-	locked = graph_lock();
-	if (!locked)
-		goto out_irq;
-
+	arch_spin_lock(&lockdep_lock);
+	current->lockdep_recursion = 1;
 	pf = get_pending_free();
 	__lockdep_free_key_range(pf, start, size);
 	call_rcu_zapped(pf);
-
-	graph_unlock();
-out_irq:
+	current->lockdep_recursion = 0;
+	arch_spin_unlock(&lockdep_lock);
 	raw_local_irq_restore(flags);
 
 	/*
@@ -4911,9 +4907,8 @@ void lockdep_unregister_key(struct lock_class_key *key)
 		return;
 
 	raw_local_irq_save(flags);
-	if (!graph_lock())
-		goto out_irq;
-
+	arch_spin_lock(&lockdep_lock);
+	current->lockdep_recursion = 1;
 	pf = get_pending_free();
 	hlist_for_each_entry_rcu(k, hash_head, hash_entry) {
 		if (k == key) {
@@ -4925,8 +4920,8 @@ void lockdep_unregister_key(struct lock_class_key *key)
 	WARN_ON_ONCE(!found);
 	__lockdep_free_key_range(pf, key, 1);
 	call_rcu_zapped(pf);
-	graph_unlock();
-out_irq:
+	current->lockdep_recursion = 0;
+	arch_spin_unlock(&lockdep_lock);
 	raw_local_irq_restore(flags);
 
 	/* Wait until is_dynamic_key() has finished accessing k->hash_entry. */
-- 
2.21.0.196.g041f5ea1cf98


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] locking/lockdep: Zap lock classes even with lock debugging disabled
  2019-04-03 23:35 [PATCH v2] locking/lockdep: Zap lock classes even with lock debugging disabled Bart Van Assche
@ 2019-04-04  9:36 ` Peter Zijlstra
  2019-04-10 12:13 ` [tip:locking/urgent] " tip-bot for Bart Van Assche
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Zijlstra @ 2019-04-04  9:36 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Ingo Molnar, Thomas Gleixner, linux-kernel, Will Deacon,
	Waiman Long, shenghui

On Wed, Apr 03, 2019 at 04:35:52PM -0700, Bart Van Assche wrote:
> Commit a0b0fd53e1e6 ("locking/lockdep: Free lock classes that are no longer
> in use") changed the behavior of lockdep_free_key_range() from
> unconditionally zapping lock classes into only zapping lock classes if
> debug_lock == true. Not zapping lock classes if debug_lock == false leaves
> dangling pointers in several lockdep datastructures, e.g. lock_class::name
> in the all_lock_classes list. The shell command "cat /proc/lockdep" causes
> the kernel to iterate the all_lock_classes list. Hence the "unable to
> handle kernel paging request" issue that Shenghui encountered by running
> cat /proc/lockdep. Since the new behavior can cause cat /proc/lockdep to
> crash, restore the pre-v5.1 behavior.
> 
> This patch avoids that cat /proc/lockdep triggers the following crash
> with debug_lock == false:
> 
> BUG: unable to handle kernel paging request at fffffbfff40ca448
> PGD 13bfde067 P4D 13bfde067 PUD 13bf7a067 PMD 1167d3067 PTE 0
> Oops: 0000 [#1] PREEMPT SMP KASAN
> CPU: 4 PID: 4529 Comm: cat Tainted: G    B   W  O      5.1.0-rc1-dbg+ #4
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
> RIP: 0010:__asan_load1+0x28/0x50
> Call Trace:
>  string+0xac/0x180
>  vsnprintf+0x23e/0x820
>  seq_vprintf+0x82/0xc0
>  seq_printf+0x92/0xb0
>  print_name+0x34/0xb0
>  l_show+0x184/0x200
>  seq_read+0x59e/0x6c0
>  proc_reg_read+0x11f/0x170
>  __vfs_read+0x4d/0x90
>  vfs_read+0xc5/0x1f0
>  ksys_read+0xab/0x130
>  __x64_sys_read+0x43/0x50
>  do_syscall_64+0x71/0x210
>  entry_SYSCALL_64_after_hwframe+0x49/0xbe
> 
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Waiman Long <longman@redhat.com>
> Cc: shenghui <shhuiw@foxmail.com>
> Reported-by: shenghui <shhuiw@foxmail.com>
> Fixes: a0b0fd53e1e6 ("locking/lockdep: Free lock classes that are no longer in use") # v5.1-rc1.
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>

Thanks!

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [tip:locking/urgent] locking/lockdep: Zap lock classes even with lock debugging disabled
  2019-04-03 23:35 [PATCH v2] locking/lockdep: Zap lock classes even with lock debugging disabled Bart Van Assche
  2019-04-04  9:36 ` Peter Zijlstra
@ 2019-04-10 12:13 ` tip-bot for Bart Van Assche
  1 sibling, 0 replies; 3+ messages in thread
From: tip-bot for Bart Van Assche @ 2019-04-10 12:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: shhuiw, tglx, longman, mingo, hpa, bvanassche, peterz,
	will.deacon, linux-kernel, torvalds

Commit-ID:  90c1cba2b3b3851c151229f61801919b2904d437
Gitweb:     https://git.kernel.org/tip/90c1cba2b3b3851c151229f61801919b2904d437
Author:     Bart Van Assche <bvanassche@acm.org>
AuthorDate: Wed, 3 Apr 2019 16:35:52 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 10 Apr 2019 13:45:59 +0200

locking/lockdep: Zap lock classes even with lock debugging disabled

The following commit:

  a0b0fd53e1e6 ("locking/lockdep: Free lock classes that are no longer in use")

changed the behavior of lockdep_free_key_range() from
unconditionally zapping lock classes into only zapping lock classes if
debug_lock == true. Not zapping lock classes if debug_lock == false leaves
dangling pointers in several lockdep datastructures, e.g. lock_class::name
in the all_lock_classes list.

The shell command "cat /proc/lockdep" causes the kernel to iterate the
all_lock_classes list. Hence the "unable to handle kernel paging request" cash
that Shenghui encountered by running cat /proc/lockdep.

Since the new behavior can cause cat /proc/lockdep to crash, restore the
pre-v5.1 behavior.

This patch avoids that cat /proc/lockdep triggers the following crash
with debug_lock == false:

  BUG: unable to handle kernel paging request at fffffbfff40ca448
  RIP: 0010:__asan_load1+0x28/0x50
  Call Trace:
   string+0xac/0x180
   vsnprintf+0x23e/0x820
   seq_vprintf+0x82/0xc0
   seq_printf+0x92/0xb0
   print_name+0x34/0xb0
   l_show+0x184/0x200
   seq_read+0x59e/0x6c0
   proc_reg_read+0x11f/0x170
   __vfs_read+0x4d/0x90
   vfs_read+0xc5/0x1f0
   ksys_read+0xab/0x130
   __x64_sys_read+0x43/0x50
   do_syscall_64+0x71/0x210
   entry_SYSCALL_64_after_hwframe+0x49/0xbe

Reported-by: shenghui <shhuiw@foxmail.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Waiman Long <longman@redhat.com>
Cc: Will Deacon <will.deacon@arm.com>
Fixes: a0b0fd53e1e6 ("locking/lockdep: Free lock classes that are no longer in use") # v5.1-rc1.
Link: https://lkml.kernel.org/r/20190403233552.124673-1-bvanassche@acm.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/locking/lockdep.c | 29 ++++++++++++-----------------
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 34cdcbedda49..e16766ff184b 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -4689,8 +4689,8 @@ static void free_zapped_rcu(struct rcu_head *ch)
 		return;
 
 	raw_local_irq_save(flags);
-	if (!graph_lock())
-		goto out_irq;
+	arch_spin_lock(&lockdep_lock);
+	current->lockdep_recursion = 1;
 
 	/* closed head */
 	pf = delayed_free.pf + (delayed_free.index ^ 1);
@@ -4702,8 +4702,8 @@ static void free_zapped_rcu(struct rcu_head *ch)
 	 */
 	call_rcu_zapped(delayed_free.pf + delayed_free.index);
 
-	graph_unlock();
-out_irq:
+	current->lockdep_recursion = 0;
+	arch_spin_unlock(&lockdep_lock);
 	raw_local_irq_restore(flags);
 }
 
@@ -4744,21 +4744,17 @@ static void lockdep_free_key_range_reg(void *start, unsigned long size)
 {
 	struct pending_free *pf;
 	unsigned long flags;
-	int locked;
 
 	init_data_structures_once();
 
 	raw_local_irq_save(flags);
-	locked = graph_lock();
-	if (!locked)
-		goto out_irq;
-
+	arch_spin_lock(&lockdep_lock);
+	current->lockdep_recursion = 1;
 	pf = get_pending_free();
 	__lockdep_free_key_range(pf, start, size);
 	call_rcu_zapped(pf);
-
-	graph_unlock();
-out_irq:
+	current->lockdep_recursion = 0;
+	arch_spin_unlock(&lockdep_lock);
 	raw_local_irq_restore(flags);
 
 	/*
@@ -4911,9 +4907,8 @@ void lockdep_unregister_key(struct lock_class_key *key)
 		return;
 
 	raw_local_irq_save(flags);
-	if (!graph_lock())
-		goto out_irq;
-
+	arch_spin_lock(&lockdep_lock);
+	current->lockdep_recursion = 1;
 	pf = get_pending_free();
 	hlist_for_each_entry_rcu(k, hash_head, hash_entry) {
 		if (k == key) {
@@ -4925,8 +4920,8 @@ void lockdep_unregister_key(struct lock_class_key *key)
 	WARN_ON_ONCE(!found);
 	__lockdep_free_key_range(pf, key, 1);
 	call_rcu_zapped(pf);
-	graph_unlock();
-out_irq:
+	current->lockdep_recursion = 0;
+	arch_spin_unlock(&lockdep_lock);
 	raw_local_irq_restore(flags);
 
 	/* Wait until is_dynamic_key() has finished accessing k->hash_entry. */

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-04-10 12:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-03 23:35 [PATCH v2] locking/lockdep: Zap lock classes even with lock debugging disabled Bart Van Assche
2019-04-04  9:36 ` Peter Zijlstra
2019-04-10 12:13 ` [tip:locking/urgent] " tip-bot for Bart Van Assche

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.