kernel: bump 4.14 to 4.14.77
[openwrt/openwrt.git] / target / linux / generic / pending-4.14 / 120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
1 From: Tobias Wolf <dev-NTEO@vplace.de>
2 Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation
3
4 An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any
5 kernel beyond version 4.3 resulting in:
6
7 BUG: Bad page state in process swapper pfn:086ac
8
9 bisect resulted in:
10
11 a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit
12 commit a1c34a3bf00af2cede839879502e12dc68491ad5
13 Author: Laura Abbott <laura@labbott.name>
14 Date: Thu Nov 5 18:48:46 2015 -0800
15
16 mm: Don't offset memmap for flatmem
17
18 Srinivas Kandagatla reported bad page messages when trying to remove the
19 bottom 2MB on an ARM based IFC6410 board
20
21 BUG: Bad page state in process swapper pfn:fffa8
22 page:ef7fb500 count:0 mapcount:0 mapping: (null) index:0x0
23 flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked)
24 page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set
25 bad because of flags:
26 flags: 0x200041(locked|active|mlocked)
27 Modules linked in:
28 CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty
29 #816
30 Hardware name: Qualcomm (Flattened Device Tree)
31 unwind_backtrace
32 show_stack
33 dump_stack
34 bad_page
35 free_pages_prepare
36 free_hot_cold_page
37 __free_pages
38 free_highmem_page
39 mem_init
40 start_kernel
41 Disabling lock debugging due to kernel taint
42 [...]
43 :040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4
44 0a8156f848733dfa21e16c196dfb6c0a76290709 M mm
45
46 This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by
47 page_to_pfn anymore.
48
49 The following output was generated with two hacked in printk statements:
50
51 printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map -
52 (pgdat->node_start_pfn - ARCH_PFN_OFFSET));
53 if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
54 mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
55 printk("after %p\n", mem_map);
56
57 Output:
58
59 [ 0.000000] before 8861b280 vs. 8861b280 or 8851b280
60 [ 0.000000] after 8851b280
61
62 As seen in the first line mem_map with subtraction of offset does not equal the
63 mem_map after subtraction of ARCH_PFN_OFFSET.
64
65 After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the
66 previously calculated offset is zero for the named platform it is able to boot
67 4.4 and 4.9-rc7 again.
68
69 Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
70 ---
71
72 --- a/mm/page_alloc.c
73 +++ b/mm/page_alloc.c
74 @@ -6153,7 +6153,7 @@ static void __ref alloc_node_mem_map(str
75 mem_map = NODE_DATA(0)->node_mem_map;
76 #if defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) || defined(CONFIG_FLATMEM)
77 if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
78 - mem_map -= offset;
79 + mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
80 #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
81 }
82 #endif