@@ -41,7 +41,6 @@ u32 swsusp_hardware_signature;
* in which case some architectures need these pages cleaning before they
* can be executed. We don't know which pages these may be, so clean the lot.
*/
-static bool clean_pages_on_read;
static bool clean_pages_on_decompress;
/*
@@ -256,9 +255,6 @@ static void hib_end_io(struct bio *bio)
if (bio_data_dir(bio) == WRITE)
put_page(page);
- else if (clean_pages_on_read)
- flush_icache_range((unsigned long)page_address(page),
- (unsigned long)page_address(page) + PAGE_SIZE);
if (bio->bi_status && !hb->error)
hb->error = bio->bi_status;
@@ -1084,6 +1080,50 @@ static int swap_reader_finish(struct swap_map_handle *handle)
return 0;
}
+struct swsusp_readpages {
+ unsigned long size;
+ unsigned long cursor;
+ struct page **pages;
+};
+
+static int swsusp_init_readpages(struct swsusp_readpages *read_pages, unsigned int nr_to_read)
+{
+ read_pages->pages = (struct page **)vzalloc(sizeof(struct page *) * nr_to_read);
+ if (!read_pages->pages) {
+ return -ENOMEM;
+ }
+
+ read_pages->size = nr_to_read;
+ read_pages->cursor = 0;
+
+ return 0;
+}
+
+
+static int swsusp_add_readpage(struct swsusp_readpages *read_pages, void *page_addr)
+{
+ if (read_pages->cursor >= read_pages->size) {
+ return -ENOMEM;
+ }
+
+ read_pages->pages[read_pages->cursor++] = virt_to_page(page_addr);
+ return 0;
+}
+
+static void swsusp_clean_readedpages(struct swsusp_readpages *read_pages, bool flush)
+{
+ unsigned long idx;
+
+ for (idx = 0; idx < read_pages->cursor; idx++) {
+ if (flush && read_pages->pages[idx])
+ flush_icache_range((unsigned long)page_address(read_pages->pages[idx]),
+ (unsigned long)page_address(read_pages->pages[idx] + PAGE_SIZE));
+ }
+
+ vfree(read_pages->pages);
+ return;
+}
+
/**
* load_image - load the image using the swap map handle
* @handle and the snapshot handle @snapshot
@@ -1101,10 +1141,14 @@ static int load_image(struct swap_map_handle *handle,
struct hib_bio_batch hb;
int err2;
unsigned nr_pages;
+ struct swsusp_readpages pages_to_clean;
hib_init_batch(&hb);
+ ret = swsusp_init_readpages(&pages_to_clean, nr_to_read);
+ if (!ret) {
+ return ret;
+ }
- clean_pages_on_read = true;
pr_info("Loading image data pages (%u pages)...\n", nr_to_read);
m = nr_to_read / 10;
if (!m)
@@ -1122,6 +1166,10 @@ static int load_image(struct swap_map_handle *handle,
ret = hib_wait_io(&hb);
if (ret)
break;
+ ret = swsusp_add_readpage(&pages_to_clean, data_of(*snapshot));
+ if (ret)
+ break;
+
if (!(nr_pages % m))
pr_info("Image loading progress: %3d%%\n",
nr_pages / m * 10);
@@ -1132,6 +1180,7 @@ static int load_image(struct swap_map_handle *handle,
stop = ktime_get();
if (!ret)
ret = err2;
+ swsusp_clean_readedpages(&pages_to_clean, !ret);
if (!ret) {
pr_info("Image loading done\n");
ret = snapshot_write_finalize(snapshot);