From: Andrew Morton Kill off the polled-mode read completion code, clean a few little things up. Cc: Pavel Machek Cc: "Rafael J. Wysocki" Signed-off-by: Andrew Morton --- kernel/power/swap.c | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff -puN kernel/power/swap.c~swsusp-read-speedup-cleanup kernel/power/swap.c --- a/kernel/power/swap.c~swsusp-read-speedup-cleanup +++ a/kernel/power/swap.c @@ -386,27 +386,6 @@ int swsusp_write(void) return error; } -/* - * Using bio to read from swap. - * This code requires a bit more work than just using buffer heads - * but, it is the recommended way for 2.5/2.6. - * The following are to signal the beginning and end of I/O. Bios - * finish asynchronously, while we want them to happen synchronously. - * A simple atomic_t, and a wait loop take care of this problem. - */ - -static atomic_t io_done = ATOMIC_INIT(0); - -static int end_io(struct bio *bio, unsigned int num, int err) -{ - if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { - printk(KERN_ERR "I/O error reading swsusp image.\n"); - return -EIO; - } - atomic_set(&io_done, 0); - return 0; -} - static struct block_device *resume_bdev; /** @@ -414,12 +393,12 @@ static struct block_device *resume_bdev; * @rw: READ or WRITE. * @off physical offset of page. * @page: page we're reading or writing. + * @bio_chain: list of pending biod (for async reading) * * Straight from the textbook - allocate and initialize the bio. - * If we're writing, make sure the page is marked as dirty. - * Then submit it and wait. + * If we're reading, make sure the page is marked as dirty. + * Then submit it and, if @bio_chain == NULL, wait. */ - static int submit(int rw, pgoff_t page_off, struct page *page, struct bio **bio_chain) { @@ -430,7 +409,7 @@ static int submit(int rw, pgoff_t page_o return -ENOMEM; bio->bi_sector = page_off * (PAGE_SIZE >> 9); bio->bi_bdev = resume_bdev; - bio->bi_end_io = end_io; + bio->bi_end_io = end_swap_bio_read; if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { printk("swsusp: ERROR: adding page to bio at %ld\n", page_off); @@ -438,19 +417,17 @@ static int submit(int rw, pgoff_t page_o return -EFAULT; } + lock_page(page); + bio_get(bio); + if (bio_chain == NULL) { - atomic_set(&io_done, 1); submit_bio(rw | (1 << BIO_RW_SYNC), bio); - while (atomic_read(&io_done)) - yield(); + wait_on_page_locked(page); if (rw == READ) bio_set_pages_dirty(bio); bio_put(bio); } else { - lock_page(page); get_page(page); - bio_get(bio); - bio->bi_end_io = end_swap_bio_read; bio->bi_private = *bio_chain; *bio_chain = bio; submit_bio(rw, bio); _