summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-04-12 00:15:51 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-04-12 00:15:51 -0700
commit6d27f67bf6ee2b9ad0c8814118264bc273d916a1 (patch)
tree061ebd5a38b7ba938bae27c66ff574d90764a7c3 /kernel
parent3749bf2c1fb31ffd3f95b9843890a7132fa06c06 (diff)
[PATCH] per-backing dev unplugging
From: Jens Axboe <axboe@suse.de>, Chris Mason, me, others. The global unplug list causes horrid spinlock contention on many-disk many-CPU setups - throughput is worse than halved. The other problem with the global unplugging is of course that it will cause the unplugging of queues which are unrelated to the I/O upon which the caller is about to wait. So what we do to solve these problems is to remove the global unplug and set up the infrastructure under which the VFS can tell the block layer to unplug only those queues which are relevant to the page or buffer_head whcih is about to be waited upon. We do this via the very appropriate address_space->backing_dev_info structure. Most of the complexity is in devicemapper, MD and swapper_space, because for these backing devices, multiple queues may need to be unplugged to complete a page/buffer I/O. In each case we ensure that data structures are in place to permit us to identify all the lower-level queues which contribute to the higher-level backing_dev_info. Each contributing queue is told to unplug in response to a higher-level unplug. To simplify things in various places we also introduce the concept of a "synchronous BIO": it is tagged with BIO_RW_SYNC. The block layer will perform an immediate unplug when it sees one of these go past.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/disk.c1
-rw-r--r--kernel/power/pmdisk.c3
-rw-r--r--kernel/power/swsusp.c5
3 files changed, 1 insertions, 8 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 7e035a9b42d1..6abcf99b7ada 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -84,7 +84,6 @@ static void free_some_memory(void)
while (shrink_all_memory(10000))
printk(".");
printk("|\n");
- blk_run_queues();
}
diff --git a/kernel/power/pmdisk.c b/kernel/power/pmdisk.c
index d54147214bea..22855abbdd6e 100644
--- a/kernel/power/pmdisk.c
+++ b/kernel/power/pmdisk.c
@@ -859,7 +859,6 @@ static int end_io(struct bio * bio, unsigned int num, int err)
static void wait_io(void)
{
- blk_run_queues();
while(atomic_read(&io_done))
io_schedule();
}
@@ -898,7 +897,7 @@ static int submit(int rw, pgoff_t page_off, void * page)
if (rw == WRITE)
bio_set_pages_dirty(bio);
start_io();
- submit_bio(rw,bio);
+ submit_bio(rw | (1 << BIO_RW_SYNC), bio);
wait_io();
Done:
bio_put(bio);
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 20134ab8e0b2..ae748a467af5 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -707,11 +707,6 @@ int software_suspend(void)
free_some_memory();
- /* No need to invalidate any vfsmnt list --
- * they will be valid after resume, anyway.
- */
- blk_run_queues();
-
/* Save state of all device drivers, and stop them. */
if ((res = device_suspend(4))==0)
/* If stopping device drivers worked, we proceed basically into