103-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch 2.8 KB

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