On 05/04/2024 15:38, Christoph Hellwig wrote:
On Fri, Apr 05, 2024 at 01:31:10PM +0100, John Garry wrote:
Anyway, changing the code, below, for sparse when it seems somewhat
broken/unreliable may not be the best approach.
Ok, let's skip this and I'll report a bug to the sparse maintainers
(unless you want to do that, in which case I'll happily leave it to
you).
This actually looks like a kernel issue - that being that the mutex API
is not annotated for lock checking.
For a reference, see this:
https://lore.kernel.org/lkml/cover.1579893447.git.jbi.octave@xxxxxxxxx/T/#mbb8bda6c0a7ca7ce19f46df976a8e3b489745488
As a quick hack to prove, you can try this for building blk-setting.c:
---->8----
diff --git a/block/blk-settings.c b/block/blk-settings.c
index cdbaef159c4b..c9da5549f3c2 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -277,6 +277,7 @@ EXPORT_SYMBOL_GPL(queue_limits_commit_update);
* Returns 0 if successful, else a negative error code.
*/
int queue_limits_set(struct request_queue *q, struct queue_limits *lim)
+__acquires(q->limits_lock)
{
mutex_lock(&q->limits_lock);
return queue_limits_commit_update(q, lim);
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 67edc4ca2bee..af5d3e20553b 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -143,7 +143,7 @@ do { \
} while (0)
#else
-extern void mutex_lock(struct mutex *lock);
+extern __lockfunc void mutex_lock(struct mutex *lock) __acquires(lock);
extern int __must_check mutex_lock_interruptible(struct mutex *lock);
extern int __must_check mutex_lock_killable(struct mutex *lock);
extern void mutex_lock_io(struct mutex *lock);
@@ -162,7 +162,7 @@ extern void mutex_lock_io(struct mutex *lock);
* Returns 1 if the mutex has been acquired successfully, and 0 on
contention.
*/
extern int mutex_trylock(struct mutex *lock);
-extern void mutex_unlock(struct mutex *lock);
+extern __lockfunc void mutex_unlock(struct mutex *lock) __releases(lock);
extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);
----8<----
I would need to investigate further for any progress in adding that lock
checking to the mutex API, but it did not look promising from that
patchset. For now I suppose you can either:
a. remove current annotation.
b. change to a spinlock - I don't think that anything requiring
scheduling is happening when updating the limits, but would need to
audit to be sure.
BTW, as for lock checking for inline functions in the header, I think
that there is no checking there.