OpenWrt – Blame information for rev 3
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 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 |
||
3 | office | 74 | @@ -5932,7 +5932,7 @@ static void __ref alloc_node_mem_map(str |
1 | office | 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 |