dm: merge pushback and deferred bio lists

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Linux Kernel Mailing List
Date: Friday, April 3, 2009 - 11:09 am

Gitweb:     http://git.kernel.org/linus/022c261100e15652d720395b17ce76304fb2f97f
Commit:     022c261100e15652d720395b17ce76304fb2f97f
Parent:     401600dfd368305e641d79db16d514f55c084544
Author:     Mikulas Patocka <mpatocka@redhat.com>
AuthorDate: Thu Apr 2 19:55:39 2009 +0100
Committer:  Alasdair G Kergon <agk@redhat.com>
CommitDate: Thu Apr 2 19:55:39 2009 +0100

    dm: merge pushback and deferred bio lists
    
    Merge pushback and deferred lists into one list - use deferred list
    for both deferred and pushed-back bios.
    
    This will be needed for proper support of barrier bios: it is impossible to
    support ordering correctly with two lists because the requests on both lists
    will be mixed up.
    
    Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
    Signed-off-by: Alasdair G Kergon <agk@redhat.com>
---
 drivers/md/dm.c |   37 ++++++++++++++++---------------------
 1 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index ae21833..f570372 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -102,7 +102,6 @@ union map_info *dm_get_mapinfo(struct bio *bio)
 struct mapped_device {
 	struct rw_semaphore io_lock;
 	struct mutex suspend_lock;
-	spinlock_t pushback_lock;
 	rwlock_t map_lock;
 	atomic_t holders;
 	atomic_t open_count;
@@ -122,7 +121,7 @@ struct mapped_device {
 	wait_queue_head_t wait;
 	struct work_struct work;
 	struct bio_list deferred;
-	struct bio_list pushback;
+	spinlock_t deferred_lock;
 
 	/*
 	 * Processing queue (flush/barriers)
@@ -445,7 +444,9 @@ static int queue_io(struct mapped_device *md, struct bio *bio)
 		return 1;
 	}
 
+	spin_lock_irq(&md->deferred_lock);
 	bio_list_add(&md->deferred, bio);
+	spin_unlock_irq(&md->deferred_lock);
 
 	up_write(&md->io_lock);
 	return 0;		/* deferred successfully */
@@ -529,16 +530,14 @@ static void dec_pending(struct dm_io *io, int error)
 		if (io->error == DM_ENDIO_REQUEUE) {
 			/*
 			 * Target requested pushing back the I/O.
-			 * This must be handled before the sleeper on
-			 * suspend queue merges the pushback list.
 			 */
-			spin_lock_irqsave(&md->pushback_lock, flags);
+			spin_lock_irqsave(&md->deferred_lock, flags);
 			if (__noflush_suspending(md))
-				bio_list_add(&md->pushback, io->bio);
+				bio_list_add(&md->deferred, io->bio);
 			else
 				/* noflush suspend was interrupted. */
 				io->error = -EIO;
-			spin_unlock_irqrestore(&md->pushback_lock, flags);
+			spin_unlock_irqrestore(&md->deferred_lock, flags);
 		}
 
 		end_io_acct(io);
@@ -1096,7 +1095,7 @@ static struct mapped_device *alloc_dev(int minor)
 
 	init_rwsem(&md->io_lock);
 	mutex_init(&md->suspend_lock);
-	spin_lock_init(&md->pushback_lock);
+	spin_lock_init(&md->deferred_lock);
 	rwlock_init(&md->map_lock);
 	atomic_set(&md->holders, 1);
 	atomic_set(&md->open_count, 0);
@@ -1410,25 +1409,21 @@ static void dm_wq_work(struct work_struct *work)
 
 	down_write(&md->io_lock);
 
-	while ((c = bio_list_pop(&md->deferred)))
+next_bio:
+	spin_lock_irq(&md->deferred_lock);
+	c = bio_list_pop(&md->deferred);
+	spin_unlock_irq(&md->deferred_lock);
+
+	if (c) {
 		__split_and_process_bio(md, c);
+		goto next_bio;
+	}
 
 	clear_bit(DMF_BLOCK_IO, &md->flags);
 
 	up_write(&md->io_lock);
 }
 
-static void __merge_pushback_list(struct mapped_device *md)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&md->pushback_lock, flags);
-	clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
-	bio_list_merge_head(&md->deferred, &md->pushback);
-	bio_list_init(&md->pushback);
-	spin_unlock_irqrestore(&md->pushback_lock, flags);
-}
-
 static void dm_queue_flush(struct mapped_device *md)
 {
 	queue_work(md->wq, &md->work);
@@ -1572,7 +1567,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
 	remove_wait_queue(&md->wait, &wait);
 
 	if (noflush)
-		__merge_pushback_list(md);
+		clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
 	up_write(&md->io_lock);
 
 	/* were we interrupted ? */
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
dm: merge pushback and deferred bio lists, Linux Kernel Mailing ..., (Fri Apr 3, 11:09 am)