Merge tag 'powerpc-5.10-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[linux-2.6-microblaze.git] / kernel / power / swap.c
index 01e2858..c73f2e2 100644 (file)
@@ -226,6 +226,7 @@ struct hib_bio_batch {
        atomic_t                count;
        wait_queue_head_t       wait;
        blk_status_t            error;
+       struct blk_plug         plug;
 };
 
 static void hib_init_batch(struct hib_bio_batch *hb)
@@ -233,6 +234,12 @@ static void hib_init_batch(struct hib_bio_batch *hb)
        atomic_set(&hb->count, 0);
        init_waitqueue_head(&hb->wait);
        hb->error = BLK_STS_OK;
+       blk_start_plug(&hb->plug);
+}
+
+static void hib_finish_batch(struct hib_bio_batch *hb)
+{
+       blk_finish_plug(&hb->plug);
 }
 
 static void hib_end_io(struct bio *bio)
@@ -294,6 +301,10 @@ static int hib_submit_io(int op, int op_flags, pgoff_t page_off, void *addr,
 
 static blk_status_t hib_wait_io(struct hib_bio_batch *hb)
 {
+       /*
+        * We are relying on the behavior of blk_plug that a thread with
+        * a plug will flush the plug list before sleeping.
+        */
        wait_event(hb->wait, atomic_read(&hb->count) == 0);
        return blk_status_to_errno(hb->error);
 }
@@ -335,26 +346,23 @@ static int swsusp_swap_check(void)
 {
        int res;
 
-       res = swap_type_of(swsusp_resume_device, swsusp_resume_block,
-                       &hib_resume_bdev);
+       if (swsusp_resume_device)
+               res = swap_type_of(swsusp_resume_device, swsusp_resume_block);
+       else
+               res = find_first_swap(&swsusp_resume_device);
        if (res < 0)
                return res;
-
        root_swap = res;
-       res = blkdev_get(hib_resume_bdev, FMODE_WRITE, NULL);
-       if (res)
-               return res;
+
+       hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device, FMODE_WRITE,
+                       NULL);
+       if (IS_ERR(hib_resume_bdev))
+               return PTR_ERR(hib_resume_bdev);
 
        res = set_blocksize(hib_resume_bdev, PAGE_SIZE);
        if (res < 0)
                blkdev_put(hib_resume_bdev, FMODE_WRITE);
 
-       /*
-        * Update the resume device to the one actually used,
-        * so the test_resume mode can use it in case it is
-        * invoked from hibernate() to test the snapshot.
-        */
-       swsusp_resume_device = hib_resume_bdev->bd_dev;
        return res;
 }
 
@@ -561,6 +569,7 @@ static int save_image(struct swap_map_handle *handle,
                nr_pages++;
        }
        err2 = hib_wait_io(&hb);
+       hib_finish_batch(&hb);
        stop = ktime_get();
        if (!ret)
                ret = err2;
@@ -854,6 +863,7 @@ out_finish:
                pr_info("Image saving done\n");
        swsusp_show_speed(start, stop, nr_to_write, "Wrote");
 out_clean:
+       hib_finish_batch(&hb);
        if (crc) {
                if (crc->thr)
                        kthread_stop(crc->thr);
@@ -1084,6 +1094,7 @@ static int load_image(struct swap_map_handle *handle,
                nr_pages++;
        }
        err2 = hib_wait_io(&hb);
+       hib_finish_batch(&hb);
        stop = ktime_get();
        if (!ret)
                ret = err2;
@@ -1447,6 +1458,7 @@ out_finish:
        }
        swsusp_show_speed(start, stop, nr_to_read, "Read");
 out_clean:
+       hib_finish_batch(&hb);
        for (i = 0; i < ring_size; i++)
                free_page((unsigned long)page[i]);
        if (crc) {