diff options
author | Mike Snitzer <snitzer@kernel.org> | 2024-02-05 21:04:19 -0500 |
---|---|---|
committer | Mike Snitzer <snitzer@kernel.org> | 2024-02-20 13:43:18 -0500 |
commit | 872564c501b72ae0c84af51084753e8652e4a84b (patch) | |
tree | cbd175a50bc33d9602e2e250f59e397930d0b7a4 /drivers/md | |
parent | a6c05c981ecc841a3e95af666c2a1a6a265e7adc (diff) | |
download | linux-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.c | 35 |
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); |