aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryalin wang <yalin.wang2010@gmail.com>2016-01-21 19:40:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-21 20:20:51 -0500
commit16fd0fe4aa92d0d621ecfe21de86f7fdcfa41947 (patch)
treed94d862bb32b160dcacb5467c099f52748f5f1dd
parent7162a1e87b3e380133dadc7909081bb70d0a7041 (diff)
mm: fix kernel crash in khugepaged thread
This crash is caused by NULL pointer deference, in page_to_pfn() marco, when page == NULL : Unable to handle kernel NULL pointer dereference at virtual address 00000000 Internal error: Oops: 94000006 [#1] SMP Modules linked in: CPU: 1 PID: 26 Comm: khugepaged Tainted: G W 4.3.0-rc6-next-20151022ajb-00001-g32f3386-dirty #3 PC is at khugepaged+0x378/0x1af8 LR is at khugepaged+0x418/0x1af8 Process khugepaged (pid: 26, stack limit = 0xffffffc079638020) Call trace: khugepaged+0x378/0x1af8 kthread+0xdc/0xf4 ret_from_fork+0xc/0x40 Code: 35001700 f0002c60 aa0703e3 f9009fa0 (f94000e0) ---[ end trace 637503d8e28ae69e ]--- Kernel panic - not syncing: Fatal exception CPU2: stopping CPU: 2 PID: 0 Comm: swapper/2 Tainted: G D W 4.3.0-rc6-next-20151022ajb-00001-g32f3386-dirty #3 Hardware name: linux,dummy-virt (DT) [akpm@linux-foundation.org: fix fat-fingered merge resolution] Signed-off-by: yalin wang <yalin.wang2010@gmail.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Acked-by: David Rientjes <rientjes@google.com> Cc: Cyrill Gorcunov <gorcunov@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/trace/events/huge_memory.h12
-rw-r--r--mm/huge_memory.c6
2 files changed, 9 insertions, 9 deletions
diff --git a/include/trace/events/huge_memory.h b/include/trace/events/huge_memory.h
index 0f803d2783e3..47c6212d8f3c 100644
--- a/include/trace/events/huge_memory.h
+++ b/include/trace/events/huge_memory.h
@@ -46,10 +46,10 @@ SCAN_STATUS
46 46
47TRACE_EVENT(mm_khugepaged_scan_pmd, 47TRACE_EVENT(mm_khugepaged_scan_pmd,
48 48
49 TP_PROTO(struct mm_struct *mm, unsigned long pfn, bool writable, 49 TP_PROTO(struct mm_struct *mm, struct page *page, bool writable,
50 bool referenced, int none_or_zero, int status), 50 bool referenced, int none_or_zero, int status),
51 51
52 TP_ARGS(mm, pfn, writable, referenced, none_or_zero, status), 52 TP_ARGS(mm, page, writable, referenced, none_or_zero, status),
53 53
54 TP_STRUCT__entry( 54 TP_STRUCT__entry(
55 __field(struct mm_struct *, mm) 55 __field(struct mm_struct *, mm)
@@ -62,7 +62,7 @@ TRACE_EVENT(mm_khugepaged_scan_pmd,
62 62
63 TP_fast_assign( 63 TP_fast_assign(
64 __entry->mm = mm; 64 __entry->mm = mm;
65 __entry->pfn = pfn; 65 __entry->pfn = page ? page_to_pfn(page) : -1;
66 __entry->writable = writable; 66 __entry->writable = writable;
67 __entry->referenced = referenced; 67 __entry->referenced = referenced;
68 __entry->none_or_zero = none_or_zero; 68 __entry->none_or_zero = none_or_zero;
@@ -104,10 +104,10 @@ TRACE_EVENT(mm_collapse_huge_page,
104 104
105TRACE_EVENT(mm_collapse_huge_page_isolate, 105TRACE_EVENT(mm_collapse_huge_page_isolate,
106 106
107 TP_PROTO(unsigned long pfn, int none_or_zero, 107 TP_PROTO(struct page *page, int none_or_zero,
108 bool referenced, bool writable, int status), 108 bool referenced, bool writable, int status),
109 109
110 TP_ARGS(pfn, none_or_zero, referenced, writable, status), 110 TP_ARGS(page, none_or_zero, referenced, writable, status),
111 111
112 TP_STRUCT__entry( 112 TP_STRUCT__entry(
113 __field(unsigned long, pfn) 113 __field(unsigned long, pfn)
@@ -118,7 +118,7 @@ TRACE_EVENT(mm_collapse_huge_page_isolate,
118 ), 118 ),
119 119
120 TP_fast_assign( 120 TP_fast_assign(
121 __entry->pfn = pfn; 121 __entry->pfn = page ? page_to_pfn(page) : -1;
122 __entry->none_or_zero = none_or_zero; 122 __entry->none_or_zero = none_or_zero;
123 __entry->referenced = referenced; 123 __entry->referenced = referenced;
124 __entry->writable = writable; 124 __entry->writable = writable;
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 2d1ffe9d0e26..fd3a07b3e6f4 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2072,7 +2072,7 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
2072 if (likely(writable)) { 2072 if (likely(writable)) {
2073 if (likely(referenced)) { 2073 if (likely(referenced)) {
2074 result = SCAN_SUCCEED; 2074 result = SCAN_SUCCEED;
2075 trace_mm_collapse_huge_page_isolate(page_to_pfn(page), none_or_zero, 2075 trace_mm_collapse_huge_page_isolate(page, none_or_zero,
2076 referenced, writable, result); 2076 referenced, writable, result);
2077 return 1; 2077 return 1;
2078 } 2078 }
@@ -2082,7 +2082,7 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
2082 2082
2083out: 2083out:
2084 release_pte_pages(pte, _pte); 2084 release_pte_pages(pte, _pte);
2085 trace_mm_collapse_huge_page_isolate(page_to_pfn(page), none_or_zero, 2085 trace_mm_collapse_huge_page_isolate(page, none_or_zero,
2086 referenced, writable, result); 2086 referenced, writable, result);
2087 return 0; 2087 return 0;
2088} 2088}
@@ -2580,7 +2580,7 @@ out_unmap:
2580 collapse_huge_page(mm, address, hpage, vma, node); 2580 collapse_huge_page(mm, address, hpage, vma, node);
2581 } 2581 }
2582out: 2582out:
2583 trace_mm_khugepaged_scan_pmd(mm, page_to_pfn(page), writable, referenced, 2583 trace_mm_khugepaged_scan_pmd(mm, page, writable, referenced,
2584 none_or_zero, result); 2584 none_or_zero, result);
2585 return ret; 2585 return ret;
2586} 2586}