Skip to content

Commit d150294

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 <bgeffon@google.com> Fixes: 8357376 ("[PATCH] swsusp: Improve handling of highmem") Cc: All applicable <stable@vger.kernel.org> [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 567c6f6 commit d150294

File tree

1 file changed

+1
-5
lines changed

1 file changed

+1
-5
lines changed

kernel/power/snapshot.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -2633,8 +2633,6 @@ int snapshot_write_next(struct snapshot_handle *handle)
26332633
if (handle->cur > 1 && handle->cur > nr_meta_pages + nr_copy_pages)
26342634
return 0;
26352635

2636-
handle->sync_read = 1;
2637-
26382636
if (!handle->cur) {
26392637
if (!buffer)
26402638
/* This makes the buffer be freed by swsusp_free() */
@@ -2670,7 +2668,6 @@ int snapshot_write_next(struct snapshot_handle *handle)
26702668
memory_bm_position_reset(&orig_bm);
26712669
restore_pblist = NULL;
26722670
handle->buffer = get_buffer(&orig_bm, &ca);
2673-
handle->sync_read = 0;
26742671
if (IS_ERR(handle->buffer))
26752672
return PTR_ERR(handle->buffer);
26762673
}
@@ -2680,9 +2677,8 @@ int snapshot_write_next(struct snapshot_handle *handle)
26802677
handle->buffer = get_buffer(&orig_bm, &ca);
26812678
if (IS_ERR(handle->buffer))
26822679
return PTR_ERR(handle->buffer);
2683-
if (handle->buffer != buffer)
2684-
handle->sync_read = 0;
26852680
}
2681+
handle->sync_read = (handle->buffer == buffer);
26862682
handle->cur++;
26872683
return PAGE_SIZE;
26882684
}

0 commit comments

Comments
 (0)