aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@kernel.org>2024-02-05 21:04:19 -0500
committerMike Snitzer <snitzer@kernel.org>2024-02-20 13:43:18 -0500
commit872564c501b72ae0c84af51084753e8652e4a84b (patch)
treecbd175a50bc33d9602e2e250f59e397930d0b7a4 /drivers/md
parenta6c05c981ecc841a3e95af666c2a1a6a265e7adc (diff)
downloadlinux-872564c501b72ae0c84af51084753e8652e4a84b.tar.gz
dm vdo data-vio: silence sparse warnings about locking context imbalances
Factor wait_permit() out from acquire_permit() so that the latter always holds the spinlock and the former always releases it. Otherwise sparse complains about locking context imbalances due to conditional spin_unlock in acquire_permit: warning: context imbalance in 'acquire_permit' - different lock contexts for basic block warning: context imbalance in 'vdo_launch_bio' - unexpected unlock Signed-off-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Susan LeGendre-McGhee <slegendr@redhat.com> Signed-off-by: Matthew Sakai <msakai@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-vdo/data-vio.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/md/dm-vdo/data-vio.c b/drivers/md/dm-vdo/data-vio.c
index e0f1574ae1129..d77adeb5006ef 100644
--- a/drivers/md/dm-vdo/data-vio.c
+++ b/drivers/md/dm-vdo/data-vio.c
@@ -929,27 +929,30 @@ void free_data_vio_pool(struct data_vio_pool *pool)
uds_free(pool);
}
-static bool acquire_permit(struct limiter *limiter, struct bio *bio)
+static bool acquire_permit(struct limiter *limiter)
{
- if (limiter->busy >= limiter->limit) {
- DEFINE_WAIT(wait);
-
- bio_list_add(&limiter->new_waiters, bio);
- prepare_to_wait_exclusive(&limiter->blocked_threads, &wait,
- TASK_UNINTERRUPTIBLE);
- spin_unlock(&limiter->pool->lock);
- io_schedule();
- finish_wait(&limiter->blocked_threads, &wait);
+ if (limiter->busy >= limiter->limit)
return false;
- }
WRITE_ONCE(limiter->busy, limiter->busy + 1);
if (limiter->max_busy < limiter->busy)
WRITE_ONCE(limiter->max_busy, limiter->busy);
-
return true;
}
+static void wait_permit(struct limiter *limiter, struct bio *bio)
+ __releases(&limiter->pool->lock)
+{
+ DEFINE_WAIT(wait);
+
+ bio_list_add(&limiter->new_waiters, bio);
+ prepare_to_wait_exclusive(&limiter->blocked_threads, &wait,
+ TASK_UNINTERRUPTIBLE);
+ spin_unlock(&limiter->pool->lock);
+ io_schedule();
+ finish_wait(&limiter->blocked_threads, &wait);
+}
+
/**
* vdo_launch_bio() - Acquire a data_vio from the pool, assign the bio to it, and launch it.
*
@@ -965,11 +968,15 @@ void vdo_launch_bio(struct data_vio_pool *pool, struct bio *bio)
bio->bi_private = (void *) jiffies;
spin_lock(&pool->lock);
if ((bio_op(bio) == REQ_OP_DISCARD) &&
- !acquire_permit(&pool->discard_limiter, bio))
+ !acquire_permit(&pool->discard_limiter)) {
+ wait_permit(&pool->discard_limiter, bio);
return;
+ }
- if (!acquire_permit(&pool->limiter, bio))
+ if (!acquire_permit(&pool->limiter)) {
+ wait_permit(&pool->limiter, bio);
return;
+ }
data_vio = get_available_data_vio(pool);
spin_unlock(&pool->lock);