mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking.
@ 2024-08-12 10:39 Sebastian Andrzej Siewior
  2024-08-12 10:39 ` [PATCH 1/4] locking/rt: Add sparse annotation PREEMPT_RT's sleeping locks Sebastian Andrzej Siewior
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2024-08-12 10:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: tglx, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, Boqun Feng

Hi,

the series adds sparse annotation to PREEMPT_RT's locking which
substitutes spinlock_t and rwlock_t.
The way local_lock_t is implemented, sparse annotation works for
PREEMPT_RT due its spinlock_t usage but not for !PREEMPT_RT because it
is just preempt_disable().

Sebastian


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

* [PATCH 1/4] locking/rt: Add sparse annotation PREEMPT_RT's sleeping locks.
  2024-08-12 10:39 [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking Sebastian Andrzej Siewior
@ 2024-08-12 10:39 ` Sebastian Andrzej Siewior
  2024-10-24  9:37   ` [tip: locking/core] " tip-bot2 for Sebastian Andrzej Siewior
  2024-08-12 10:39 ` [PATCH 2/4] locking/rt: Remove one __cond_lock() in RT's spin_trylock_irqsave() Sebastian Andrzej Siewior
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2024-08-12 10:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: tglx, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long,
	Boqun Feng, Sebastian Andrzej Siewior

The sleeping locks on PREEMPT_RT (rt_spin_lock() and friends) lack
sparse annotation. Therefore a missing spin_unlock() won't be spotted by
sparse in a PREEMPT_RT build while it is noticed on a !PREEMPT_RT build.

Add the __acquires/__releases macros to the lock/ unlock functions. The
trylock functions already use the __cond_lock() wrapper.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 include/linux/rwlock_rt.h   | 10 +++++-----
 include/linux/spinlock_rt.h |  8 ++++----
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/linux/rwlock_rt.h b/include/linux/rwlock_rt.h
index 8544ff05e594d..7d81fc6918ee8 100644
--- a/include/linux/rwlock_rt.h
+++ b/include/linux/rwlock_rt.h
@@ -24,13 +24,13 @@ do {							\
 	__rt_rwlock_init(rwl, #rwl, &__key);		\
 } while (0)
 
-extern void rt_read_lock(rwlock_t *rwlock);
+extern void rt_read_lock(rwlock_t *rwlock)	__acquires(rwlock);
 extern int rt_read_trylock(rwlock_t *rwlock);
-extern void rt_read_unlock(rwlock_t *rwlock);
-extern void rt_write_lock(rwlock_t *rwlock);
-extern void rt_write_lock_nested(rwlock_t *rwlock, int subclass);
+extern void rt_read_unlock(rwlock_t *rwlock)	__releases(rwlock);
+extern void rt_write_lock(rwlock_t *rwlock)	__acquires(rwlock);
+extern void rt_write_lock_nested(rwlock_t *rwlock, int subclass)	__acquires(rwlock);
 extern int rt_write_trylock(rwlock_t *rwlock);
-extern void rt_write_unlock(rwlock_t *rwlock);
+extern void rt_write_unlock(rwlock_t *rwlock)	__releases(rwlock);
 
 static __always_inline void read_lock(rwlock_t *rwlock)
 {
diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h
index 61c49b16f69ab..babc3e0287791 100644
--- a/include/linux/spinlock_rt.h
+++ b/include/linux/spinlock_rt.h
@@ -32,10 +32,10 @@ do {								\
 	__rt_spin_lock_init(slock, #slock, &__key, true);	\
 } while (0)
 
-extern void rt_spin_lock(spinlock_t *lock);
-extern void rt_spin_lock_nested(spinlock_t *lock, int subclass);
-extern void rt_spin_lock_nest_lock(spinlock_t *lock, struct lockdep_map *nest_lock);
-extern void rt_spin_unlock(spinlock_t *lock);
+extern void rt_spin_lock(spinlock_t *lock) __acquires(lock);
+extern void rt_spin_lock_nested(spinlock_t *lock, int subclass)	__acquires(lock);
+extern void rt_spin_lock_nest_lock(spinlock_t *lock, struct lockdep_map *nest_lock) __acquires(lock);
+extern void rt_spin_unlock(spinlock_t *lock)	__releases(lock);
 extern void rt_spin_lock_unlock(spinlock_t *lock);
 extern int rt_spin_trylock_bh(spinlock_t *lock);
 extern int rt_spin_trylock(spinlock_t *lock);
-- 
2.45.2


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

* [PATCH 2/4] locking/rt: Remove one __cond_lock() in RT's spin_trylock_irqsave()
  2024-08-12 10:39 [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking Sebastian Andrzej Siewior
  2024-08-12 10:39 ` [PATCH 1/4] locking/rt: Add sparse annotation PREEMPT_RT's sleeping locks Sebastian Andrzej Siewior
@ 2024-08-12 10:39 ` Sebastian Andrzej Siewior
  2024-10-24  9:37   ` [tip: locking/core] " tip-bot2 for Sebastian Andrzej Siewior
  2024-08-12 10:39 ` [PATCH 3/4] locking/rt: Add sparse annotation for RCU Sebastian Andrzej Siewior
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2024-08-12 10:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: tglx, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long,
	Boqun Feng, Sebastian Andrzej Siewior

spin_trylock_irqsave() has a __cond_lock() wrapper which points to
__spin_trylock_irqsave(). The function then invokes spin_trylock() which
has another __cond_lock() finally pointing to rt_spin_trylock().

The compiler has no problem to parse this but sparse does not recognise
that users of spin_trylock_irqsave() acquire a conditional lock and
complains.

Remove one layer of __cond_lock() so that sparse recognises conditional
locking.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 include/linux/spinlock_rt.h | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h
index babc3e0287791..f9f14e135be7b 100644
--- a/include/linux/spinlock_rt.h
+++ b/include/linux/spinlock_rt.h
@@ -132,7 +132,7 @@ static __always_inline void spin_unlock_irqrestore(spinlock_t *lock,
 #define spin_trylock_irq(lock)				\
 	__cond_lock(lock, rt_spin_trylock(lock))
 
-#define __spin_trylock_irqsave(lock, flags)		\
+#define spin_trylock_irqsave(lock, flags)		\
 ({							\
 	int __locked;					\
 							\
@@ -142,9 +142,6 @@ static __always_inline void spin_unlock_irqrestore(spinlock_t *lock,
 	__locked;					\
 })
 
-#define spin_trylock_irqsave(lock, flags)		\
-	__cond_lock(lock, __spin_trylock_irqsave(lock, flags))
-
 #define spin_is_contended(lock)		(((void)(lock), 0))
 
 static inline int spin_is_locked(spinlock_t *lock)
-- 
2.45.2


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

* [PATCH 3/4] locking/rt: Add sparse annotation for RCU.
  2024-08-12 10:39 [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking Sebastian Andrzej Siewior
  2024-08-12 10:39 ` [PATCH 1/4] locking/rt: Add sparse annotation PREEMPT_RT's sleeping locks Sebastian Andrzej Siewior
  2024-08-12 10:39 ` [PATCH 2/4] locking/rt: Remove one __cond_lock() in RT's spin_trylock_irqsave() Sebastian Andrzej Siewior
@ 2024-08-12 10:39 ` Sebastian Andrzej Siewior
  2024-10-24  9:37   ` [tip: locking/core] " tip-bot2 for Sebastian Andrzej Siewior
  2024-08-12 10:39 ` [PATCH 4/4] locking/rt: Annotate unlock followed by lock for sparse Sebastian Andrzej Siewior
  2024-10-01  7:17 ` [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking Sebastian Andrzej Siewior
  4 siblings, 1 reply; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2024-08-12 10:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: tglx, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long,
	Boqun Feng, Sebastian Andrzej Siewior

Every lock, that becomes a sleeping on PREEMPT_RT, starts a RCU read
section. There is no sparse annotation for this and sparse complains
about unbalanced locking.

Add __acquires/ __releases for the RCU lock. This covers all but the
trylock functions. I tried the __cond_acquires() annotation but it
didn't work.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 kernel/locking/spinlock_rt.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/kernel/locking/spinlock_rt.c b/kernel/locking/spinlock_rt.c
index 38e292454fccb..d1cf8b2b6dcac 100644
--- a/kernel/locking/spinlock_rt.c
+++ b/kernel/locking/spinlock_rt.c
@@ -51,7 +51,7 @@ static __always_inline void __rt_spin_lock(spinlock_t *lock)
 	migrate_disable();
 }
 
-void __sched rt_spin_lock(spinlock_t *lock)
+void __sched rt_spin_lock(spinlock_t *lock) __acquires(RCU)
 {
 	spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
 	__rt_spin_lock(lock);
@@ -75,7 +75,7 @@ void __sched rt_spin_lock_nest_lock(spinlock_t *lock,
 EXPORT_SYMBOL(rt_spin_lock_nest_lock);
 #endif
 
-void __sched rt_spin_unlock(spinlock_t *lock)
+void __sched rt_spin_unlock(spinlock_t *lock) __releases(RCU)
 {
 	spin_release(&lock->dep_map, _RET_IP_);
 	migrate_enable();
@@ -225,7 +225,7 @@ int __sched rt_write_trylock(rwlock_t *rwlock)
 }
 EXPORT_SYMBOL(rt_write_trylock);
 
-void __sched rt_read_lock(rwlock_t *rwlock)
+void __sched rt_read_lock(rwlock_t *rwlock) __acquires(RCU)
 {
 	rtlock_might_resched();
 	rwlock_acquire_read(&rwlock->dep_map, 0, 0, _RET_IP_);
@@ -235,7 +235,7 @@ void __sched rt_read_lock(rwlock_t *rwlock)
 }
 EXPORT_SYMBOL(rt_read_lock);
 
-void __sched rt_write_lock(rwlock_t *rwlock)
+void __sched rt_write_lock(rwlock_t *rwlock) __acquires(RCU)
 {
 	rtlock_might_resched();
 	rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_);
@@ -246,7 +246,7 @@ void __sched rt_write_lock(rwlock_t *rwlock)
 EXPORT_SYMBOL(rt_write_lock);
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
-void __sched rt_write_lock_nested(rwlock_t *rwlock, int subclass)
+void __sched rt_write_lock_nested(rwlock_t *rwlock, int subclass) __acquires(RCU)
 {
 	rtlock_might_resched();
 	rwlock_acquire(&rwlock->dep_map, subclass, 0, _RET_IP_);
@@ -257,7 +257,7 @@ void __sched rt_write_lock_nested(rwlock_t *rwlock, int subclass)
 EXPORT_SYMBOL(rt_write_lock_nested);
 #endif
 
-void __sched rt_read_unlock(rwlock_t *rwlock)
+void __sched rt_read_unlock(rwlock_t *rwlock) __releases(RCU)
 {
 	rwlock_release(&rwlock->dep_map, _RET_IP_);
 	migrate_enable();
@@ -266,7 +266,7 @@ void __sched rt_read_unlock(rwlock_t *rwlock)
 }
 EXPORT_SYMBOL(rt_read_unlock);
 
-void __sched rt_write_unlock(rwlock_t *rwlock)
+void __sched rt_write_unlock(rwlock_t *rwlock) __releases(RCU)
 {
 	rwlock_release(&rwlock->dep_map, _RET_IP_);
 	rcu_read_unlock();
-- 
2.45.2


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

* [PATCH 4/4] locking/rt: Annotate unlock followed by lock for sparse.
  2024-08-12 10:39 [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking Sebastian Andrzej Siewior
                   ` (2 preceding siblings ...)
  2024-08-12 10:39 ` [PATCH 3/4] locking/rt: Add sparse annotation for RCU Sebastian Andrzej Siewior
@ 2024-08-12 10:39 ` Sebastian Andrzej Siewior
  2024-10-24  9:37   ` [tip: locking/core] " tip-bot2 for Sebastian Andrzej Siewior
  2024-10-01  7:17 ` [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking Sebastian Andrzej Siewior
  4 siblings, 1 reply; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2024-08-12 10:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: tglx, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long,
	Boqun Feng, Sebastian Andrzej Siewior

rt_mutex_slowlock_block() and rtlock_slowlock_locked() both unlock
lock::wait_lock and then lock it later. This is unusual and sparse
complains about it.

Add __releases() + __acquires() annotation to mark that it is expected.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 kernel/locking/rtmutex.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index 88d08eeb8bc03..e389078bddecb 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -1601,6 +1601,7 @@ static int __sched rt_mutex_slowlock_block(struct rt_mutex_base *lock,
 					   unsigned int state,
 					   struct hrtimer_sleeper *timeout,
 					   struct rt_mutex_waiter *waiter)
+	__releases(&lock->wait_lock) __acquires(&lock->wait_lock)
 {
 	struct rt_mutex *rtm = container_of(lock, struct rt_mutex, rtmutex);
 	struct task_struct *owner;
@@ -1804,6 +1805,7 @@ static __always_inline int __rt_mutex_lock(struct rt_mutex_base *lock,
  * @lock:	The underlying RT mutex
  */
 static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock)
+	__releases(&lock->wait_lock) __acquires(&lock->wait_lock)
 {
 	struct rt_mutex_waiter waiter;
 	struct task_struct *owner;
-- 
2.45.2


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

* Re: [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking.
  2024-08-12 10:39 [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking Sebastian Andrzej Siewior
                   ` (3 preceding siblings ...)
  2024-08-12 10:39 ` [PATCH 4/4] locking/rt: Annotate unlock followed by lock for sparse Sebastian Andrzej Siewior
@ 2024-10-01  7:17 ` Sebastian Andrzej Siewior
  4 siblings, 0 replies; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2024-10-01  7:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: tglx, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, Boqun Feng

On 2024-08-12 12:39:01 [+0200], To linux-kernel@vger.kernel.org wrote:
Hi,
> 
> the series adds sparse annotation to PREEMPT_RT's locking which
> substitutes spinlock_t and rwlock_t.
> The way local_lock_t is implemented, sparse annotation works for
> PREEMPT_RT due its spinlock_t usage but not for !PREEMPT_RT because it
> is just preempt_disable().

A friendly ping.

Sebastian

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

* [tip: locking/core] locking/rt: Annotate unlock followed by lock for sparse.
  2024-08-12 10:39 ` [PATCH 4/4] locking/rt: Annotate unlock followed by lock for sparse Sebastian Andrzej Siewior
@ 2024-10-24  9:37   ` tip-bot2 for Sebastian Andrzej Siewior
  0 siblings, 0 replies; 10+ messages in thread
From: tip-bot2 for Sebastian Andrzej Siewior @ 2024-10-24  9:37 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Sebastian Andrzej Siewior, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the locking/core branch of tip:

Commit-ID:     77abd3b7d9bf384306872b6201b1dfeb1e899892
Gitweb:        https://git.kernel.org/tip/77abd3b7d9bf384306872b6201b1dfeb1e899892
Author:        Sebastian Andrzej Siewior <bigeasy@linutronix.de>
AuthorDate:    Mon, 12 Aug 2024 12:39:05 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 24 Oct 2024 11:27:02 +02:00

locking/rt: Annotate unlock followed by lock for sparse.

rt_mutex_slowlock_block() and rtlock_slowlock_locked() both unlock
lock::wait_lock and then lock it later. This is unusual and sparse
complains about it.

Add __releases() + __acquires() annotation to mark that it is expected.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20240812104200.2239232-5-bigeasy@linutronix.de

---
 kernel/locking/rtmutex.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index ebebd0e..d3b72c2 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -1601,6 +1601,7 @@ static int __sched rt_mutex_slowlock_block(struct rt_mutex_base *lock,
 					   unsigned int state,
 					   struct hrtimer_sleeper *timeout,
 					   struct rt_mutex_waiter *waiter)
+	__releases(&lock->wait_lock) __acquires(&lock->wait_lock)
 {
 	struct rt_mutex *rtm = container_of(lock, struct rt_mutex, rtmutex);
 	struct task_struct *owner;
@@ -1805,6 +1806,7 @@ static __always_inline int __rt_mutex_lock(struct rt_mutex_base *lock,
  * @lock:	The underlying RT mutex
  */
 static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock)
+	__releases(&lock->wait_lock) __acquires(&lock->wait_lock)
 {
 	struct rt_mutex_waiter waiter;
 	struct task_struct *owner;

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

* [tip: locking/core] locking/rt: Add sparse annotation for RCU.
  2024-08-12 10:39 ` [PATCH 3/4] locking/rt: Add sparse annotation for RCU Sebastian Andrzej Siewior
@ 2024-10-24  9:37   ` tip-bot2 for Sebastian Andrzej Siewior
  0 siblings, 0 replies; 10+ messages in thread
From: tip-bot2 for Sebastian Andrzej Siewior @ 2024-10-24  9:37 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Sebastian Andrzej Siewior, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the locking/core branch of tip:

Commit-ID:     168660b826a77fda28235e0b0b3027041d6a5240
Gitweb:        https://git.kernel.org/tip/168660b826a77fda28235e0b0b3027041d6a5240
Author:        Sebastian Andrzej Siewior <bigeasy@linutronix.de>
AuthorDate:    Mon, 12 Aug 2024 12:39:04 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 24 Oct 2024 11:27:02 +02:00

locking/rt: Add sparse annotation for RCU.

Every lock, that becomes a sleeping lock on PREEMPT_RT, starts a RCU read
side critical section. There is no sparse annotation for this and sparse
complains about unbalanced locking.

Add __acquires/ __releases for the RCU lock. This covers all but the
trylock functions. A __cond_acquires() annotation didn't work.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20240812104200.2239232-4-bigeasy@linutronix.de

---
 kernel/locking/spinlock_rt.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/kernel/locking/spinlock_rt.c b/kernel/locking/spinlock_rt.c
index 38e2924..d1cf8b2 100644
--- a/kernel/locking/spinlock_rt.c
+++ b/kernel/locking/spinlock_rt.c
@@ -51,7 +51,7 @@ static __always_inline void __rt_spin_lock(spinlock_t *lock)
 	migrate_disable();
 }
 
-void __sched rt_spin_lock(spinlock_t *lock)
+void __sched rt_spin_lock(spinlock_t *lock) __acquires(RCU)
 {
 	spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
 	__rt_spin_lock(lock);
@@ -75,7 +75,7 @@ void __sched rt_spin_lock_nest_lock(spinlock_t *lock,
 EXPORT_SYMBOL(rt_spin_lock_nest_lock);
 #endif
 
-void __sched rt_spin_unlock(spinlock_t *lock)
+void __sched rt_spin_unlock(spinlock_t *lock) __releases(RCU)
 {
 	spin_release(&lock->dep_map, _RET_IP_);
 	migrate_enable();
@@ -225,7 +225,7 @@ int __sched rt_write_trylock(rwlock_t *rwlock)
 }
 EXPORT_SYMBOL(rt_write_trylock);
 
-void __sched rt_read_lock(rwlock_t *rwlock)
+void __sched rt_read_lock(rwlock_t *rwlock) __acquires(RCU)
 {
 	rtlock_might_resched();
 	rwlock_acquire_read(&rwlock->dep_map, 0, 0, _RET_IP_);
@@ -235,7 +235,7 @@ void __sched rt_read_lock(rwlock_t *rwlock)
 }
 EXPORT_SYMBOL(rt_read_lock);
 
-void __sched rt_write_lock(rwlock_t *rwlock)
+void __sched rt_write_lock(rwlock_t *rwlock) __acquires(RCU)
 {
 	rtlock_might_resched();
 	rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_);
@@ -246,7 +246,7 @@ void __sched rt_write_lock(rwlock_t *rwlock)
 EXPORT_SYMBOL(rt_write_lock);
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
-void __sched rt_write_lock_nested(rwlock_t *rwlock, int subclass)
+void __sched rt_write_lock_nested(rwlock_t *rwlock, int subclass) __acquires(RCU)
 {
 	rtlock_might_resched();
 	rwlock_acquire(&rwlock->dep_map, subclass, 0, _RET_IP_);
@@ -257,7 +257,7 @@ void __sched rt_write_lock_nested(rwlock_t *rwlock, int subclass)
 EXPORT_SYMBOL(rt_write_lock_nested);
 #endif
 
-void __sched rt_read_unlock(rwlock_t *rwlock)
+void __sched rt_read_unlock(rwlock_t *rwlock) __releases(RCU)
 {
 	rwlock_release(&rwlock->dep_map, _RET_IP_);
 	migrate_enable();
@@ -266,7 +266,7 @@ void __sched rt_read_unlock(rwlock_t *rwlock)
 }
 EXPORT_SYMBOL(rt_read_unlock);
 
-void __sched rt_write_unlock(rwlock_t *rwlock)
+void __sched rt_write_unlock(rwlock_t *rwlock) __releases(RCU)
 {
 	rwlock_release(&rwlock->dep_map, _RET_IP_);
 	rcu_read_unlock();

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

* [tip: locking/core] locking/rt: Add sparse annotation PREEMPT_RT's sleeping locks.
  2024-08-12 10:39 ` [PATCH 1/4] locking/rt: Add sparse annotation PREEMPT_RT's sleeping locks Sebastian Andrzej Siewior
@ 2024-10-24  9:37   ` tip-bot2 for Sebastian Andrzej Siewior
  0 siblings, 0 replies; 10+ messages in thread
From: tip-bot2 for Sebastian Andrzej Siewior @ 2024-10-24  9:37 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Sebastian Andrzej Siewior, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the locking/core branch of tip:

Commit-ID:     52e0874fc16bd26e9ea1871e30ffb2c6dff187cf
Gitweb:        https://git.kernel.org/tip/52e0874fc16bd26e9ea1871e30ffb2c6dff187cf
Author:        Sebastian Andrzej Siewior <bigeasy@linutronix.de>
AuthorDate:    Mon, 12 Aug 2024 12:39:02 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 24 Oct 2024 11:27:01 +02:00

locking/rt: Add sparse annotation PREEMPT_RT's sleeping locks.

The sleeping locks on PREEMPT_RT (rt_spin_lock() and friends) lack
sparse annotation. Therefore a missing spin_unlock() won't be spotted by
sparse in a PREEMPT_RT build while it is noticed on a !PREEMPT_RT build.

Add the __acquires/__releases macros to the lock/ unlock functions. The
trylock functions already use the __cond_lock() wrapper.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20240812104200.2239232-2-bigeasy@linutronix.de

---
 include/linux/rwlock_rt.h   | 10 +++++-----
 include/linux/spinlock_rt.h |  8 ++++----
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/linux/rwlock_rt.h b/include/linux/rwlock_rt.h
index 8544ff0..7d81fc6 100644
--- a/include/linux/rwlock_rt.h
+++ b/include/linux/rwlock_rt.h
@@ -24,13 +24,13 @@ do {							\
 	__rt_rwlock_init(rwl, #rwl, &__key);		\
 } while (0)
 
-extern void rt_read_lock(rwlock_t *rwlock);
+extern void rt_read_lock(rwlock_t *rwlock)	__acquires(rwlock);
 extern int rt_read_trylock(rwlock_t *rwlock);
-extern void rt_read_unlock(rwlock_t *rwlock);
-extern void rt_write_lock(rwlock_t *rwlock);
-extern void rt_write_lock_nested(rwlock_t *rwlock, int subclass);
+extern void rt_read_unlock(rwlock_t *rwlock)	__releases(rwlock);
+extern void rt_write_lock(rwlock_t *rwlock)	__acquires(rwlock);
+extern void rt_write_lock_nested(rwlock_t *rwlock, int subclass)	__acquires(rwlock);
 extern int rt_write_trylock(rwlock_t *rwlock);
-extern void rt_write_unlock(rwlock_t *rwlock);
+extern void rt_write_unlock(rwlock_t *rwlock)	__releases(rwlock);
 
 static __always_inline void read_lock(rwlock_t *rwlock)
 {
diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h
index 61c49b1..babc3e0 100644
--- a/include/linux/spinlock_rt.h
+++ b/include/linux/spinlock_rt.h
@@ -32,10 +32,10 @@ do {								\
 	__rt_spin_lock_init(slock, #slock, &__key, true);	\
 } while (0)
 
-extern void rt_spin_lock(spinlock_t *lock);
-extern void rt_spin_lock_nested(spinlock_t *lock, int subclass);
-extern void rt_spin_lock_nest_lock(spinlock_t *lock, struct lockdep_map *nest_lock);
-extern void rt_spin_unlock(spinlock_t *lock);
+extern void rt_spin_lock(spinlock_t *lock) __acquires(lock);
+extern void rt_spin_lock_nested(spinlock_t *lock, int subclass)	__acquires(lock);
+extern void rt_spin_lock_nest_lock(spinlock_t *lock, struct lockdep_map *nest_lock) __acquires(lock);
+extern void rt_spin_unlock(spinlock_t *lock)	__releases(lock);
 extern void rt_spin_lock_unlock(spinlock_t *lock);
 extern int rt_spin_trylock_bh(spinlock_t *lock);
 extern int rt_spin_trylock(spinlock_t *lock);

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

* [tip: locking/core] locking/rt: Remove one __cond_lock() in RT's spin_trylock_irqsave()
  2024-08-12 10:39 ` [PATCH 2/4] locking/rt: Remove one __cond_lock() in RT's spin_trylock_irqsave() Sebastian Andrzej Siewior
@ 2024-10-24  9:37   ` tip-bot2 for Sebastian Andrzej Siewior
  0 siblings, 0 replies; 10+ messages in thread
From: tip-bot2 for Sebastian Andrzej Siewior @ 2024-10-24  9:37 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Sebastian Andrzej Siewior, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the locking/core branch of tip:

Commit-ID:     b1f01f9e54b1aaadb6740f86017e8fabdee77fe2
Gitweb:        https://git.kernel.org/tip/b1f01f9e54b1aaadb6740f86017e8fabdee77fe2
Author:        Sebastian Andrzej Siewior <bigeasy@linutronix.de>
AuthorDate:    Mon, 12 Aug 2024 12:39:03 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 24 Oct 2024 11:27:01 +02:00

locking/rt: Remove one __cond_lock() in RT's spin_trylock_irqsave()

spin_trylock_irqsave() has a __cond_lock() wrapper which points to
__spin_trylock_irqsave(). The function then invokes spin_trylock() which
has another __cond_lock() finally pointing to rt_spin_trylock().

The compiler has no problem to parse this but sparse does not recognise
that users of spin_trylock_irqsave() acquire a conditional lock and
complains.

Remove one layer of __cond_lock() so that sparse recognises conditional
locking.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20240812104200.2239232-3-bigeasy@linutronix.de

---
 include/linux/spinlock_rt.h | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h
index babc3e0..f9f14e1 100644
--- a/include/linux/spinlock_rt.h
+++ b/include/linux/spinlock_rt.h
@@ -132,7 +132,7 @@ static __always_inline void spin_unlock_irqrestore(spinlock_t *lock,
 #define spin_trylock_irq(lock)				\
 	__cond_lock(lock, rt_spin_trylock(lock))
 
-#define __spin_trylock_irqsave(lock, flags)		\
+#define spin_trylock_irqsave(lock, flags)		\
 ({							\
 	int __locked;					\
 							\
@@ -142,9 +142,6 @@ static __always_inline void spin_unlock_irqrestore(spinlock_t *lock,
 	__locked;					\
 })
 
-#define spin_trylock_irqsave(lock, flags)		\
-	__cond_lock(lock, __spin_trylock_irqsave(lock, flags))
-
 #define spin_is_contended(lock)		(((void)(lock), 0))
 
 static inline int spin_is_locked(spinlock_t *lock)

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

end of thread, other threads:[~2024-10-24  9:37 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-12 10:39 [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking Sebastian Andrzej Siewior
2024-08-12 10:39 ` [PATCH 1/4] locking/rt: Add sparse annotation PREEMPT_RT's sleeping locks Sebastian Andrzej Siewior
2024-10-24  9:37   ` [tip: locking/core] " tip-bot2 for Sebastian Andrzej Siewior
2024-08-12 10:39 ` [PATCH 2/4] locking/rt: Remove one __cond_lock() in RT's spin_trylock_irqsave() Sebastian Andrzej Siewior
2024-10-24  9:37   ` [tip: locking/core] " tip-bot2 for Sebastian Andrzej Siewior
2024-08-12 10:39 ` [PATCH 3/4] locking/rt: Add sparse annotation for RCU Sebastian Andrzej Siewior
2024-10-24  9:37   ` [tip: locking/core] " tip-bot2 for Sebastian Andrzej Siewior
2024-08-12 10:39 ` [PATCH 4/4] locking/rt: Annotate unlock followed by lock for sparse Sebastian Andrzej Siewior
2024-10-24  9:37   ` [tip: locking/core] " tip-bot2 for Sebastian Andrzej Siewior
2024-10-01  7:17 ` [PATCH 0/4] locking/rt: Add sparse annotation PREEMPT_RT's locking Sebastian Andrzej Siewior

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

all inboxes | Powered by JetHome®