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 71385be..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);
 }
@@ -558,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;
@@ -851,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);
@@ -1081,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;
@@ -1444,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) {