public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] tighten lglock lockdep annotations
@ 2013-03-05  2:17 Michel Lespinasse
  2013-03-05  2:17 ` [PATCH 1/2] lockdep: introduce lock_acquire_exclusive/shared helper macros Michel Lespinasse
  2013-03-05  2:17 ` [PATCH 2/2] lglock: update lockdep annotations to report recursive local locks Michel Lespinasse
  0 siblings, 2 replies; 8+ messages in thread
From: Michel Lespinasse @ 2013-03-05  2:17 UTC (permalink / raw)
  To: linux-kernel, Peter Zijlstra, Ingo Molnar, Oleg Nesterov,
	Lai Jiangshan, Srivatsa S. Bhat, paulmck, Rusty Russell, rostedt,
	tglx, Andrew Morton, Andi Kleen

Oleg Nesterov recently noticed that the lockdep annotations in lglock.c
are not sufficient to detect some obvious deadlocks, such as
lg_local_lock(LOCK) + lg_local_lock(LOCK) or
spin_lock(X) + lg_local_lock(Y) vs lg_local_lock(Y) + spin_lock(X).

Both issues can be fixed by indicating to lockdep that lglock's local
locks are not recursive.

Patch 1 introduces helper macros for lockdep annotations.

Patch 2 makes sure to use the appropriate helper macros to indicate that
the lglock local lock is a shared, non-recursive lock.

Michel Lespinasse (2):
  lockdep: introduce lock_acquire_exclusive/shared helper macros
  lglock: update lockdep annotations to report recursive local locks

 include/linux/lockdep.h | 92 +++++++++++++------------------------------------
 kernel/lglock.c         | 12 +++----
 2 files changed, 29 insertions(+), 75 deletions(-)

-- 
1.8.1.3

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

* [PATCH 1/2] lockdep: introduce lock_acquire_exclusive/shared helper macros
  2013-03-05  2:17 [PATCH 0/2] tighten lglock lockdep annotations Michel Lespinasse
@ 2013-03-05  2:17 ` Michel Lespinasse
  2013-03-05 15:19   ` Lai Jiangshan
  2013-03-05 17:06   ` Oleg Nesterov
  2013-03-05  2:17 ` [PATCH 2/2] lglock: update lockdep annotations to report recursive local locks Michel Lespinasse
  1 sibling, 2 replies; 8+ messages in thread
From: Michel Lespinasse @ 2013-03-05  2:17 UTC (permalink / raw)
  To: linux-kernel, Peter Zijlstra, Ingo Molnar, Oleg Nesterov,
	Lai Jiangshan, Srivatsa S. Bhat, paulmck, Rusty Russell, rostedt,
	tglx, Andrew Morton, Andi Kleen

In lockdep.h, the spinlock/mutex/rwsem/rwlock/lock_map acquire macros
have different definitions based on the value of CONFIG_PROVE_LOCKING.
We have separate ifdefs for each of these definitions, which seems
redundant.

Introduce lock_acquire_{exclusive,shared,shared_recursive} helpers
which will have different definitions based on CONFIG_PROVE_LOCKING.
Then all other helper macros can be defined based on the above ones,
which reduces the amount of ifdefined code.

Signed-off-by: Michel Lespinasse <walken@google.com>

---
 include/linux/lockdep.h | 92 +++++++++++++------------------------------------
 1 file changed, 23 insertions(+), 69 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index f1e877b79ed8..cfc2f119779a 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -365,7 +365,7 @@ extern void lockdep_trace_alloc(gfp_t mask);
 
 #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
 
-#else /* !LOCKDEP */
+#else /* !CONFIG_LOCKDEP */
 
 static inline void lockdep_off(void)
 {
@@ -479,82 +479,36 @@ static inline void print_irqtrace_events(struct task_struct *curr)
  * on the per lock-class debug mode:
  */
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-# ifdef CONFIG_PROVE_LOCKING
-#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, NULL, i)
-#  define spin_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 2, n, i)
-# else
-#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, NULL, i)
-#  define spin_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 1, NULL, i)
-# endif
-# define spin_release(l, n, i)			lock_release(l, n, i)
+#ifdef CONFIG_PROVE_LOCKING
+ #define lock_acquire_exclusive(l, s, t, n, i)		lock_acquire(l, s, t, 0, 2, n, i)
+ #define lock_acquire_shared(l, s, t, n, i)		lock_acquire(l, s, t, 1, 2, n, i)
+ #define lock_acquire_shared_recursive(l, s, t, n, i)	lock_acquire(l, s, t, 2, 2, n, i)
 #else
-# define spin_acquire(l, s, t, i)		do { } while (0)
-# define spin_release(l, n, i)			do { } while (0)
+ #define lock_acquire_exclusive(l, s, t, n, i)		lock_acquire(l, s, t, 0, 1, n, i)
+ #define lock_acquire_shared(l, s, t, n, i)		lock_acquire(l, s, t, 1, 1, n, i)
+ #define lock_acquire_shared_recursive(l, s, t, n, i)	lock_acquire(l, s, t, 2, 1, n, i)
 #endif
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-# ifdef CONFIG_PROVE_LOCKING
-#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, NULL, i)
-#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 2, NULL, i)
-# else
-#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, NULL, i)
-#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 1, NULL, i)
-# endif
-# define rwlock_release(l, n, i)		lock_release(l, n, i)
-#else
-# define rwlock_acquire(l, s, t, i)		do { } while (0)
-# define rwlock_acquire_read(l, s, t, i)	do { } while (0)
-# define rwlock_release(l, n, i)		do { } while (0)
-#endif
+#define spin_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
+#define spin_acquire_nest(l, s, t, n, i)	lock_acquire_exclusive(l, s, t, n, i)
+#define spin_release(l, n, i)			lock_release(l, n, i)
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-# ifdef CONFIG_PROVE_LOCKING
-#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, NULL, i)
-#  define mutex_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 2, n, i)
-# else
-#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, NULL, i)
-#  define mutex_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 1, n, i)
-# endif
-# define mutex_release(l, n, i)			lock_release(l, n, i)
-#else
-# define mutex_acquire(l, s, t, i)		do { } while (0)
-# define mutex_acquire_nest(l, s, t, n, i)	do { } while (0)
-# define mutex_release(l, n, i)			do { } while (0)
-#endif
+#define rwlock_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
+#define rwlock_acquire_read(l, s, t, i)		lock_acquire_shared_recursive(l, s, t, NULL, i)
+#define rwlock_release(l, n, i)			lock_release(l, n, i)
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-# ifdef CONFIG_PROVE_LOCKING
-#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, NULL, i)
-#  define rwsem_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 2, n, i)
-#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 2, NULL, i)
-# else
-#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, NULL, i)
-#  define rwsem_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 1, n, i)
-#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 1, NULL, i)
-# endif
+#define mutex_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
+#define mutex_acquire_nest(l, s, t, n, i)	lock_acquire_exclusive(l, s, t, n, i)
+#define mutex_release(l, n, i)			lock_release(l, n, i)
+
+#define rwsem_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
+#define rwsem_acquire_nest(l, s, t, n, i)	lock_acquire_exclusive(l, s, t, n, i)
+#define rwsem_acquire_read(l, s, t, i)		lock_acquire_shared(l, s, t, NULL, i)
 # define rwsem_release(l, n, i)			lock_release(l, n, i)
-#else
-# define rwsem_acquire(l, s, t, i)		do { } while (0)
-# define rwsem_acquire_nest(l, s, t, n, i)	do { } while (0)
-# define rwsem_acquire_read(l, s, t, i)		do { } while (0)
-# define rwsem_release(l, n, i)			do { } while (0)
-#endif
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-# ifdef CONFIG_PROVE_LOCKING
-#  define lock_map_acquire(l)		lock_acquire(l, 0, 0, 0, 2, NULL, _THIS_IP_)
-#  define lock_map_acquire_read(l)	lock_acquire(l, 0, 0, 2, 2, NULL, _THIS_IP_)
-# else
-#  define lock_map_acquire(l)		lock_acquire(l, 0, 0, 0, 1, NULL, _THIS_IP_)
-#  define lock_map_acquire_read(l)	lock_acquire(l, 0, 0, 2, 1, NULL, _THIS_IP_)
-# endif
+#define lock_map_acquire(l)			lock_acquire_exclusive(l, 0, 0, NULL, _THIS_IP_)
+#define lock_map_acquire_read(l)		lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_)
 # define lock_map_release(l)			lock_release(l, 1, _THIS_IP_)
-#else
-# define lock_map_acquire(l)			do { } while (0)
-# define lock_map_acquire_read(l)		do { } while (0)
-# define lock_map_release(l)			do { } while (0)
-#endif
 
 #ifdef CONFIG_PROVE_LOCKING
 # define might_lock(lock) 						\
-- 
1.8.1.3

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

* [PATCH 2/2] lglock: update lockdep annotations to report recursive local locks
  2013-03-05  2:17 [PATCH 0/2] tighten lglock lockdep annotations Michel Lespinasse
  2013-03-05  2:17 ` [PATCH 1/2] lockdep: introduce lock_acquire_exclusive/shared helper macros Michel Lespinasse
@ 2013-03-05  2:17 ` Michel Lespinasse
  2013-03-05 17:42   ` Oleg Nesterov
  1 sibling, 1 reply; 8+ messages in thread
From: Michel Lespinasse @ 2013-03-05  2:17 UTC (permalink / raw)
  To: linux-kernel, Peter Zijlstra, Ingo Molnar, Oleg Nesterov,
	Lai Jiangshan, Srivatsa S. Bhat, paulmck, Rusty Russell, rostedt,
	tglx, Andrew Morton, Andi Kleen

Oleg Nesterov recently noticed that the lockdep annotations in lglock.c
are not sufficient to detect some obvious deadlocks, such as
lg_local_lock(LOCK) + lg_local_lock(LOCK) or
spin_lock(X) + lg_local_lock(Y) vs lg_local_lock(Y) + spin_lock(X).

Both issues are easily fixed by indicating to lockdep that lglock's local
locks are not recursive. We shouldn't use the rwlock acquire/release
functions here, as lglock doesn't share the same semantics. Instead
we can base our lockdep annotations on the lock_acquire_shared
(for local lglock) and lock_acquire_exclusive (for global lglock)
helpers.

I am not proposing new lglock specific helpers as I don't see the point
of the existing second level of helpers :)

Signed-off-by: Michel Lespinasse <walken@google.com>

---
 kernel/lglock.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/kernel/lglock.c b/kernel/lglock.c
index 6535a667a5a7..86ae2aebf004 100644
--- a/kernel/lglock.c
+++ b/kernel/lglock.c
@@ -21,7 +21,7 @@ void lg_local_lock(struct lglock *lg)
 	arch_spinlock_t *lock;
 
 	preempt_disable();
-	rwlock_acquire_read(&lg->lock_dep_map, 0, 0, _RET_IP_);
+	lock_acquire_shared(&lg->lock_dep_map, 0, 0, NULL, _RET_IP_);
 	lock = this_cpu_ptr(lg->lock);
 	arch_spin_lock(lock);
 }
@@ -31,7 +31,7 @@ void lg_local_unlock(struct lglock *lg)
 {
 	arch_spinlock_t *lock;
 
-	rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
+	lock_release(&lg->lock_dep_map, 1, _RET_IP_);
 	lock = this_cpu_ptr(lg->lock);
 	arch_spin_unlock(lock);
 	preempt_enable();
@@ -43,7 +43,7 @@ void lg_local_lock_cpu(struct lglock *lg, int cpu)
 	arch_spinlock_t *lock;
 
 	preempt_disable();
-	rwlock_acquire_read(&lg->lock_dep_map, 0, 0, _RET_IP_);
+	lock_acquire_shared(&lg->lock_dep_map, 0, 0, NULL, _RET_IP_);
 	lock = per_cpu_ptr(lg->lock, cpu);
 	arch_spin_lock(lock);
 }
@@ -53,7 +53,7 @@ void lg_local_unlock_cpu(struct lglock *lg, int cpu)
 {
 	arch_spinlock_t *lock;
 
-	rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
+	lock_release(&lg->lock_dep_map, 1, _RET_IP_);
 	lock = per_cpu_ptr(lg->lock, cpu);
 	arch_spin_unlock(lock);
 	preempt_enable();
@@ -65,7 +65,7 @@ void lg_global_lock(struct lglock *lg)
 	int i;
 
 	preempt_disable();
-	rwlock_acquire(&lg->lock_dep_map, 0, 0, _RET_IP_);
+	lock_acquire_exclusive(&lg->lock_dep_map, 0, 0, NULL, _RET_IP_);
 	for_each_possible_cpu(i) {
 		arch_spinlock_t *lock;
 		lock = per_cpu_ptr(lg->lock, i);
@@ -78,7 +78,7 @@ void lg_global_unlock(struct lglock *lg)
 {
 	int i;
 
-	rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
+	lock_release(&lg->lock_dep_map, 1, _RET_IP_);
 	for_each_possible_cpu(i) {
 		arch_spinlock_t *lock;
 		lock = per_cpu_ptr(lg->lock, i);
-- 
1.8.1.3

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

* Re: [PATCH 1/2] lockdep: introduce lock_acquire_exclusive/shared helper macros
  2013-03-05  2:17 ` [PATCH 1/2] lockdep: introduce lock_acquire_exclusive/shared helper macros Michel Lespinasse
@ 2013-03-05 15:19   ` Lai Jiangshan
  2013-03-05 15:40     ` Michel Lespinasse
  2013-03-05 17:06   ` Oleg Nesterov
  1 sibling, 1 reply; 8+ messages in thread
From: Lai Jiangshan @ 2013-03-05 15:19 UTC (permalink / raw)
  To: Michel Lespinasse
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Oleg Nesterov,
	Srivatsa S. Bhat, paulmck, Rusty Russell, rostedt, tglx,
	Andrew Morton, Andi Kleen



On 05/03/13 10:17, Michel Lespinasse wrote:
> In lockdep.h, the spinlock/mutex/rwsem/rwlock/lock_map acquire macros
> have different definitions based on the value of CONFIG_PROVE_LOCKING.
> We have separate ifdefs for each of these definitions, which seems
> redundant.
> 
> Introduce lock_acquire_{exclusive,shared,shared_recursive} helpers
> which will have different definitions based on CONFIG_PROVE_LOCKING.
> Then all other helper macros can be defined based on the above ones,
> which reduces the amount of ifdefined code.
> 
> Signed-off-by: Michel Lespinasse <walken@google.com>
> 
> ---
>  include/linux/lockdep.h | 92 +++++++++++++------------------------------------
>  1 file changed, 23 insertions(+), 69 deletions(-)
> 
> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
> index f1e877b79ed8..cfc2f119779a 100644
> --- a/include/linux/lockdep.h
> +++ b/include/linux/lockdep.h
> @@ -365,7 +365,7 @@ extern void lockdep_trace_alloc(gfp_t mask);
>  
>  #define lockdep_recursing(tsk)	((tsk)->lockdep_recursion)
>  
> -#else /* !LOCKDEP */
> +#else /* !CONFIG_LOCKDEP */
>  
>  static inline void lockdep_off(void)
>  {
> @@ -479,82 +479,36 @@ static inline void print_irqtrace_events(struct task_struct *curr)
>   * on the per lock-class debug mode:
>   */
>  
> -#ifdef CONFIG_DEBUG_LOCK_ALLOC
> -# ifdef CONFIG_PROVE_LOCKING
> -#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, NULL, i)
> -#  define spin_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 2, n, i)
> -# else
> -#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, NULL, i)
> -#  define spin_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 1, NULL, i)
> -# endif
> -# define spin_release(l, n, i)			lock_release(l, n, i)
> +#ifdef CONFIG_PROVE_LOCKING
> + #define lock_acquire_exclusive(l, s, t, n, i)		lock_acquire(l, s, t, 0, 2, n, i)
> + #define lock_acquire_shared(l, s, t, n, i)		lock_acquire(l, s, t, 1, 2, n, i)
> + #define lock_acquire_shared_recursive(l, s, t, n, i)	lock_acquire(l, s, t, 2, 2, n, i)

Hi, Michel

I don't like the name lock_acquire_shared_recursive().
(I mean the name is wrong, ......)

In the lockdep design, lock_acquire(l, s, t, 2, 2, n, i) is used for
read-preference locks(rwlock) and all types of RCU. not for "recursive"
read-preference implies "recursive".

But the name lock_acquire_shared_recursive() don't tell us it is
read-preference.

Example if we do have a lock which is write-preference but allow read_lock recursive,
it will be still deadlock in this way, "recursive" does not help:

cpu0: spin_lock(a);				recursiveable_read_lock(b)
cpu1: recursiveable_read_lock(b); 		spin_lock(a);
cpu2:				write_lock(b);


I also noticed the lockdep annotations problem of lglock. and patch2 is good,
so for patch2: Reviewed-by: Lai Jiangshan <laijs@cn.fujitsu.com> 


Thanks,
Lai

>  #else
> -# define spin_acquire(l, s, t, i)		do { } while (0)
> -# define spin_release(l, n, i)			do { } while (0)
> + #define lock_acquire_exclusive(l, s, t, n, i)		lock_acquire(l, s, t, 0, 1, n, i)
> + #define lock_acquire_shared(l, s, t, n, i)		lock_acquire(l, s, t, 1, 1, n, i)
> + #define lock_acquire_shared_recursive(l, s, t, n, i)	lock_acquire(l, s, t, 2, 1, n, i)
>  #endif
>  
> -#ifdef CONFIG_DEBUG_LOCK_ALLOC
> -# ifdef CONFIG_PROVE_LOCKING
> -#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, NULL, i)
> -#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 2, NULL, i)
> -# else
> -#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, NULL, i)
> -#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 1, NULL, i)
> -# endif
> -# define rwlock_release(l, n, i)		lock_release(l, n, i)
> -#else
> -# define rwlock_acquire(l, s, t, i)		do { } while (0)
> -# define rwlock_acquire_read(l, s, t, i)	do { } while (0)
> -# define rwlock_release(l, n, i)		do { } while (0)
> -#endif
> +#define spin_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
> +#define spin_acquire_nest(l, s, t, n, i)	lock_acquire_exclusive(l, s, t, n, i)
> +#define spin_release(l, n, i)			lock_release(l, n, i)
>  
> -#ifdef CONFIG_DEBUG_LOCK_ALLOC
> -# ifdef CONFIG_PROVE_LOCKING
> -#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, NULL, i)
> -#  define mutex_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 2, n, i)
> -# else
> -#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, NULL, i)
> -#  define mutex_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 1, n, i)
> -# endif
> -# define mutex_release(l, n, i)			lock_release(l, n, i)
> -#else
> -# define mutex_acquire(l, s, t, i)		do { } while (0)
> -# define mutex_acquire_nest(l, s, t, n, i)	do { } while (0)
> -# define mutex_release(l, n, i)			do { } while (0)
> -#endif
> +#define rwlock_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
> +#define rwlock_acquire_read(l, s, t, i)		lock_acquire_shared_recursive(l, s, t, NULL, i)
> +#define rwlock_release(l, n, i)			lock_release(l, n, i)
>  
> -#ifdef CONFIG_DEBUG_LOCK_ALLOC
> -# ifdef CONFIG_PROVE_LOCKING
> -#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, NULL, i)
> -#  define rwsem_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 2, n, i)
> -#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 2, NULL, i)
> -# else
> -#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, NULL, i)
> -#  define rwsem_acquire_nest(l, s, t, n, i)	lock_acquire(l, s, t, 0, 1, n, i)
> -#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 1, NULL, i)
> -# endif
> +#define mutex_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
> +#define mutex_acquire_nest(l, s, t, n, i)	lock_acquire_exclusive(l, s, t, n, i)
> +#define mutex_release(l, n, i)			lock_release(l, n, i)
> +
> +#define rwsem_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
> +#define rwsem_acquire_nest(l, s, t, n, i)	lock_acquire_exclusive(l, s, t, n, i)
> +#define rwsem_acquire_read(l, s, t, i)		lock_acquire_shared(l, s, t, NULL, i)
>  # define rwsem_release(l, n, i)			lock_release(l, n, i)
> -#else
> -# define rwsem_acquire(l, s, t, i)		do { } while (0)
> -# define rwsem_acquire_nest(l, s, t, n, i)	do { } while (0)
> -# define rwsem_acquire_read(l, s, t, i)		do { } while (0)
> -# define rwsem_release(l, n, i)			do { } while (0)
> -#endif
>  
> -#ifdef CONFIG_DEBUG_LOCK_ALLOC
> -# ifdef CONFIG_PROVE_LOCKING
> -#  define lock_map_acquire(l)		lock_acquire(l, 0, 0, 0, 2, NULL, _THIS_IP_)
> -#  define lock_map_acquire_read(l)	lock_acquire(l, 0, 0, 2, 2, NULL, _THIS_IP_)
> -# else
> -#  define lock_map_acquire(l)		lock_acquire(l, 0, 0, 0, 1, NULL, _THIS_IP_)
> -#  define lock_map_acquire_read(l)	lock_acquire(l, 0, 0, 2, 1, NULL, _THIS_IP_)
> -# endif
> +#define lock_map_acquire(l)			lock_acquire_exclusive(l, 0, 0, NULL, _THIS_IP_)
> +#define lock_map_acquire_read(l)		lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_)
>  # define lock_map_release(l)			lock_release(l, 1, _THIS_IP_)
> -#else
> -# define lock_map_acquire(l)			do { } while (0)
> -# define lock_map_acquire_read(l)		do { } while (0)
> -# define lock_map_release(l)			do { } while (0)
> -#endif
>  
>  #ifdef CONFIG_PROVE_LOCKING
>  # define might_lock(lock) 						\


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

* Re: [PATCH 1/2] lockdep: introduce lock_acquire_exclusive/shared helper macros
  2013-03-05 15:19   ` Lai Jiangshan
@ 2013-03-05 15:40     ` Michel Lespinasse
  0 siblings, 0 replies; 8+ messages in thread
From: Michel Lespinasse @ 2013-03-05 15:40 UTC (permalink / raw)
  To: Lai Jiangshan
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Oleg Nesterov,
	Srivatsa S. Bhat, paulmck, Rusty Russell, rostedt, tglx,
	Andrew Morton, Andi Kleen

On Tue, Mar 5, 2013 at 7:19 AM, Lai Jiangshan <laijs@cn.fujitsu.com> wrote:
> I don't like the name lock_acquire_shared_recursive().
> (I mean the name is wrong, ......)

Names are hard :/ Do you have a better suggestion ?

> In the lockdep design, lock_acquire(l, s, t, 2, 2, n, i) is used for
> read-preference locks(rwlock) and all types of RCU. not for "recursive"
> read-preference implies "recursive".

I based my names on the following description from lockdep.h:

 * Values for "read":
 *
 *   0: exclusive (write) acquire
 *   1: read-acquire (no recursion allowed)
 *   2: read-acquire with same-instance recursion allowed

> But the name lock_acquire_shared_recursive() don't tell us it is
> read-preference.
>
> Example if we do have a lock which is write-preference but allow read_lock recursive,
> it will be still deadlock in this way, "recursive" does not help:
>
> cpu0: spin_lock(a);                             recursiveable_read_lock(b)
> cpu1: recursiveable_read_lock(b);               spin_lock(a);
> cpu2:                           write_lock(b);

I think this is a very theorical distinction as 1- we don't have such
locks in linux currently, and 2- lockdep does not currently support
this. That is, lockdep will either report both of these scenarios as
valid or invalid, but you can't tell it to allow the first scenario
while disallowing the second:

read_lock(a); read_lock(a);
(the recursive read lock scenario)

read_lock(a); lock(b); vs lock(b); read_lock(a);
(the lock ordering vs other locks scenario)

So, I would think that since lockdep doesn't make this distinction the
helper macros don't need to either ?

-- 
Michel "Walken" Lespinasse
A program is never fully debugged until the last user dies.

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

* Re: [PATCH 1/2] lockdep: introduce lock_acquire_exclusive/shared helper macros
  2013-03-05  2:17 ` [PATCH 1/2] lockdep: introduce lock_acquire_exclusive/shared helper macros Michel Lespinasse
  2013-03-05 15:19   ` Lai Jiangshan
@ 2013-03-05 17:06   ` Oleg Nesterov
  1 sibling, 0 replies; 8+ messages in thread
From: Oleg Nesterov @ 2013-03-05 17:06 UTC (permalink / raw)
  To: Michel Lespinasse
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Lai Jiangshan,
	Srivatsa S. Bhat, paulmck, Rusty Russell, rostedt, tglx,
	Andrew Morton, Andi Kleen

On 03/04, Michel Lespinasse wrote:
>
> In lockdep.h, the spinlock/mutex/rwsem/rwlock/lock_map acquire macros
> have different definitions based on the value of CONFIG_PROVE_LOCKING.
> We have separate ifdefs for each of these definitions, which seems
> redundant.

You know, I should not even try to comment this patch. I never really
understood this magic, and I forgot everything I knew.

But I like this patch because it makes lockdep.h more readable to me,
so I hope it is correct ;)

One question,

> +#ifdef CONFIG_PROVE_LOCKING
> + #define lock_acquire_exclusive(l, s, t, n, i)		lock_acquire(l, s, t, 0, 2, n, i)
> + #define lock_acquire_shared(l, s, t, n, i)		lock_acquire(l, s, t, 1, 2, n, i)
> + #define lock_acquire_shared_recursive(l, s, t, n, i)	lock_acquire(l, s, t, 2, 2, n, i)
>  #else
> -# define spin_acquire(l, s, t, i)		do { } while (0)
> -# define spin_release(l, n, i)			do { } while (0)
> + #define lock_acquire_exclusive(l, s, t, n, i)		lock_acquire(l, s, t, 0, 1, n, i)
> + #define lock_acquire_shared(l, s, t, n, i)		lock_acquire(l, s, t, 1, 1, n, i)
> + #define lock_acquire_shared_recursive(l, s, t, n, i)	lock_acquire(l, s, t, 2, 1, n, i)
>  #endif

Do we really need this ifdef? Can't we pass check == 2 unconditionally?

__lock_acquire() does:

	if (!prove_locking)
		check = 1;

anyway, and without CONFIG_PROVE_LOCKING prove_locking == 0.

And every time I need to look into lockdep.h these hardcoded constants
confuse me, and of course it is not possible to remember if this particular
"1" means "read" or "check". Imho it would be nice to add some symbolic
names. But this is offtopic.

Oleg.


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

* Re: [PATCH 2/2] lglock: update lockdep annotations to report recursive local locks
  2013-03-05  2:17 ` [PATCH 2/2] lglock: update lockdep annotations to report recursive local locks Michel Lespinasse
@ 2013-03-05 17:42   ` Oleg Nesterov
  2013-03-05 18:24     ` Michel Lespinasse
  0 siblings, 1 reply; 8+ messages in thread
From: Oleg Nesterov @ 2013-03-05 17:42 UTC (permalink / raw)
  To: Michel Lespinasse
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Lai Jiangshan,
	Srivatsa S. Bhat, paulmck, Rusty Russell, rostedt, tglx,
	Andrew Morton, Andi Kleen

On 03/04, Michel Lespinasse wrote:
>
> Both issues are easily fixed by indicating to lockdep that lglock's local
> locks are not recursive. We shouldn't use the rwlock acquire/release
> functions here, as lglock doesn't share the same semantics. Instead
> we can base our lockdep annotations on the lock_acquire_shared
> (for local lglock) and lock_acquire_exclusive (for global lglock)
> helpers.

IOW, with this patch lglock looks like rw_semaphore for lockdep...

Again, I can't ack this change, but afaics it is fine.

Oleg.


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

* Re: [PATCH 2/2] lglock: update lockdep annotations to report recursive local locks
  2013-03-05 17:42   ` Oleg Nesterov
@ 2013-03-05 18:24     ` Michel Lespinasse
  0 siblings, 0 replies; 8+ messages in thread
From: Michel Lespinasse @ 2013-03-05 18:24 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Lai Jiangshan,
	Srivatsa S. Bhat, paulmck, Rusty Russell, rostedt, tglx,
	Andrew Morton, Andi Kleen

On Tue, Mar 5, 2013 at 9:42 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> On 03/04, Michel Lespinasse wrote:
>>
>> Both issues are easily fixed by indicating to lockdep that lglock's local
>> locks are not recursive. We shouldn't use the rwlock acquire/release
>> functions here, as lglock doesn't share the same semantics. Instead
>> we can base our lockdep annotations on the lock_acquire_shared
>> (for local lglock) and lock_acquire_exclusive (for global lglock)
>> helpers.
>
> IOW, with this patch lglock looks like rw_semaphore for lockdep...

Yes.

I could have actually made lglock use the rwsem helpers, but I think
that would be quite confusing...

-- 
Michel "Walken" Lespinasse
A program is never fully debugged until the last user dies.

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

end of thread, other threads:[~2013-03-05 18:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-05  2:17 [PATCH 0/2] tighten lglock lockdep annotations Michel Lespinasse
2013-03-05  2:17 ` [PATCH 1/2] lockdep: introduce lock_acquire_exclusive/shared helper macros Michel Lespinasse
2013-03-05 15:19   ` Lai Jiangshan
2013-03-05 15:40     ` Michel Lespinasse
2013-03-05 17:06   ` Oleg Nesterov
2013-03-05  2:17 ` [PATCH 2/2] lglock: update lockdep annotations to report recursive local locks Michel Lespinasse
2013-03-05 17:42   ` Oleg Nesterov
2013-03-05 18:24     ` Michel Lespinasse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox