Commit 872564c5 authored by Mike Snitzer's avatar Mike Snitzer

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: default avatarMike Snitzer <snitzer@kernel.org>
Signed-off-by: default avatarSusan LeGendre-McGhee <slegendr@redhat.com>
Signed-off-by: default avatarMatthew Sakai <msakai@redhat.com>
parent a6c05c98
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment