Re: Memory corruption during hibernation since 2.6.31

From: KAMEZAWA Hiroyuki
Date: Thu Jul 29 2010 - 01:29:25 EST


On Thu, 29 Jul 2010 14:23:33 +0900 (JST)
KOSAKI Motohiro <kosaki.motohiro@xxxxxxxxxxxxxx> wrote:

> Can you please add explicit commenting in the code?
>
How about this ?
==
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx>

At hibernation, all pages-should-be-saved are written into a image (here, swap).
Then, swap_map[], memmap etcs are also saved into disks.

But, swap allocation happens one by one. So, the final image of swap_map[] is
different from saved one and the commit c9e444103b5e7a5a3519f9913f59767f92e33baf
changes page's state while assiging swap. Because memory can be modified in
hibernation is only not-to-be-save memory. it's a breakage.

This patch fixes it by disabling swap entry reuse at hibernation.



Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx>
---
mm/swapfile.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-2.6.34.org/mm/swapfile.c
===================================================================
--- linux-2.6.34.org.orig/mm/swapfile.c
+++ linux-2.6.34.org/mm/swapfile.c
@@ -315,8 +315,15 @@ checks:
if (offset > si->highest_bit)
scan_base = offset = si->lowest_bit;

- /* reuse swap entry of cache-only swap if not busy. */
- if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
+ /*
+ * reuse swap entry of cache-only swap if not busy &&
+ * when we're called via pageout(). At hibernation, swap-reuse
+ * is harmful because it changes memory status...which may
+ * be saved already.
+ */
+ if (vm_swap_full()
+ && usage == SWAP_HAS_CACHE
+ && si->swap_map[offset] == SWAP_HAS_CACHE) {
int swap_was_freed;
spin_unlock(&swap_lock);
swap_was_freed = __try_to_reclaim_swap(si, offset);

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/