All of lore.kernel.org
 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 related	[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 related	[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 related	[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 related	[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 related	[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 related	[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 related	[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 related	[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 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.