http://bugzilla.opensuse.org/show_bug.cgi?id=913885 --- Comment #12 from Joey Lee <jlee@suse.com> --- Hi Björn, Thanks for your dmesg on comment#5 and comment#6, it's VERY useful to check the logic bug of e820 to nosave region. (In reply to Björn Voigt from comment #6)
Created attachment 620573 [details] Dmesg output after suspend (Kernel 3.18.3-1.gc3e148f-desktop)
Looks there have bug in e820_mark_nosave_regions() make an misjudgment when the e820 region doesn't align to PAGE_SIZE: void __init e820_mark_nosave_regions(unsigned long limit_pfn) { int i; unsigned long pfn = 0; for (i = 0; i < e820.nr_map; i++) { struct e820entry *ei = &e820.map[i]; if (pfn < PFN_UP(ei->addr)) register_nosave_region(pfn, PFN_UP(ei->addr)); /* register to nosave region if there have hole between 2 e820 entries */ pfn = PFN_DOWN(ei->addr + ei->size); [...] The purpose of the above block in e820_mark_nosave_regions() is to compare the end PFN of last region with the current region's start PFN. It used to find out the hole between 2 e820 entries and register it to nosave regions list. The above codes so far works when all e820 entries aligned to PAGE_SIZE, but have bug on non-aligned e820 entries. For example from dmesg: Aligned case: [ 0.000000] reserve setup_data: [mem 0x000000000270b658-0x00000000cbc4efff] usable [ 0.000000] reserve setup_data: [mem 0x00000000cbc4f000-0x00000000cbc93fff] ACPI NVS PFN_DOWN (0xcbc4efff+1) = ((0xCBC4F000) >> PAGE_SHIFT) = 0xCBC4F PFN_UP (0xcbc4f000) = (((0xcbc4f000) + PAGE_SIZE-1) >> PAGE_SHIFT) = (0xcbc4f000 + 0x1000 - 1 >> PAGE_SHIFT) = 0xCBC4FFFF >> PAGE_SHIFT = 0xCBC4F if (0xCBC4F < 0xCBC4F) /* NOT TRUE! */ register_nosave_region(...); Non-aligned case: [ 0.000000] reserve setup_data: [mem 0x0000000000100000-0x0000000002576017] usable [ 0.000000] reserve setup_data: [mem 0x0000000002576018-0x0000000002585857] usable PFN_DOWN (0x2576017+1) = ((0x2576018) >> PAGE_SHIFT) = 0x2576 PFN_UP (0x2576018) = (((0x2576018) + PAGE_SIZE-1) >> PAGE_SHIFT) = (0x2576018 + 0x1000 - 1 >> PAGE_SHIFT) = 0x2577017 >> PAGE_SHIFT = 0x2577 if (0x2576 < 0x2577) /* TRUE! Misjudgment! */ register_nosave_region(0x2576, 0x2577); /* register to nosave region */ Then why this issue happened randomly because the non-aligned e820 entries generated by e820_reserve_setup_data(), setup data are allocated by kernel when early boot stage. So the allocated address are random in usable region. I think this is a old issue in code until I add patch to check the persistent of e820 region between hibernate and resume. I am trying to make a patch to fix this issue. -- You are receiving this mail because: You are on the CC list for the bug.