[PATCH 4/7] dm vdo data-vio: silence sparse warnings about locking context imbalances

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Mike Snitzer <snitzer@xxxxxxxxxx>

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@xxxxxxxxxx>
Signed-off-by: Susan LeGendre-McGhee <slegendr@xxxxxxxxxx>
Signed-off-by: Matthew Sakai <msakai@xxxxxxxxxx>
---
 drivers/md/dm-vdo/data-vio.c | 35 +++++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/md/dm-vdo/data-vio.c b/drivers/md/dm-vdo/data-vio.c
index e0f1574ae112..d77adeb5006e 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);
-- 
2.42.0





[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux