Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 210471
b: refs/heads/master
c: b73d7fc
h: refs/heads/master
i:
  210469: bd3dc5b
  210467: 730c476
  210463: e9c0840
v: v3
  • Loading branch information
Hugh Dickins authored and Linus Torvalds committed Sep 10, 2010
1 parent 81d766d commit 36e07b9
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 910321ea817a202ff70fac666e37e2c8e2f88823
refs/heads/master: b73d7fcecd93dc15eaa3c45c8c587b613f6673c4
24 changes: 20 additions & 4 deletions trunk/mm/swapfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,8 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si,
if (offset > si->highest_bit)
scan_base = offset = si->lowest_bit;

/* reuse swap entry of cache-only swap if not hibernation. */
if (vm_swap_full()
&& usage == SWAP_HAS_CACHE
&& si->swap_map[offset] == SWAP_HAS_CACHE) {
/* reuse swap entry of cache-only swap if not busy. */
if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
int swap_was_freed;
spin_unlock(&swap_lock);
swap_was_freed = __try_to_reclaim_swap(si, offset);
Expand Down Expand Up @@ -688,6 +686,24 @@ int try_to_free_swap(struct page *page)
if (page_swapcount(page))
return 0;

/*
* Once hibernation has begun to create its image of memory,
* there's a danger that one of the calls to try_to_free_swap()
* - most probably a call from __try_to_reclaim_swap() while
* hibernation is allocating its own swap pages for the image,
* but conceivably even a call from memory reclaim - will free
* the swap from a page which has already been recorded in the
* image as a clean swapcache page, and then reuse its swap for
* another page of the image. On waking from hibernation, the
* original page might be freed under memory pressure, then
* later read back in from swap, now with the wrong data.
*
* Hibernation clears bits from gfp_allowed_mask to prevent
* memory reclaim from writing to disk, so check that here.
*/
if (!(gfp_allowed_mask & __GFP_IO))
return 0;

delete_from_swap_cache(page);
SetPageDirty(page);
return 1;
Expand Down

0 comments on commit 36e07b9

Please sign in to comment.