Skip to content

Commit 3c1c1af

Browse files
bgaffgregkh
authored andcommitted
PM: hibernate: Clean up sync_read handling in snapshot_write_next()
commit d08970d upstream. In snapshot_write_next(), sync_read is set and unset in three different spots unnecessiarly. As a result there is a subtle bug where the first page after the meta data has been loaded unconditionally sets sync_read to 0. If this first PFN was actually a highmem page, then the returned buffer will be the global "buffer," and the page needs to be loaded synchronously. That is, I'm not sure we can always assume the following to be safe: handle->buffer = get_buffer(&orig_bm, &ca); handle->sync_read = 0; Because get_buffer() can call get_highmem_page_buffer() which can return 'buffer'. The easiest way to address this is just set sync_read before snapshot_write_next() returns if handle->buffer == buffer. Signed-off-by: Brian Geffon <[email protected]> Fixes: 8357376 ("[PATCH] swsusp: Improve handling of highmem") Cc: All applicable <[email protected]> [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent df8363e commit 3c1c1af

File tree

1 file changed

+1
-5
lines changed

1 file changed

+1
-5
lines changed

kernel/power/snapshot.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,8 +2587,6 @@ int snapshot_write_next(struct snapshot_handle *handle)
25872587
if (handle->cur > 1 && handle->cur > nr_meta_pages + nr_copy_pages)
25882588
return 0;
25892589

2590-
handle->sync_read = 1;
2591-
25922590
if (!handle->cur) {
25932591
if (!buffer)
25942592
/* This makes the buffer be freed by swsusp_free() */
@@ -2624,7 +2622,6 @@ int snapshot_write_next(struct snapshot_handle *handle)
26242622
memory_bm_position_reset(&orig_bm);
26252623
restore_pblist = NULL;
26262624
handle->buffer = get_buffer(&orig_bm, &ca);
2627-
handle->sync_read = 0;
26282625
if (IS_ERR(handle->buffer))
26292626
return PTR_ERR(handle->buffer);
26302627
}
@@ -2634,9 +2631,8 @@ int snapshot_write_next(struct snapshot_handle *handle)
26342631
handle->buffer = get_buffer(&orig_bm, &ca);
26352632
if (IS_ERR(handle->buffer))
26362633
return PTR_ERR(handle->buffer);
2637-
if (handle->buffer != buffer)
2638-
handle->sync_read = 0;
26392634
}
2635+
handle->sync_read = (handle->buffer == buffer);
26402636
handle->cur++;
26412637
return PAGE_SIZE;
26422638
}

0 commit comments

Comments
 (0)