diff options
author | yalin wang <yalin.wang2010@gmail.com> | 2016-01-21 19:40:30 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-21 20:20:51 -0500 |
commit | 16fd0fe4aa92d0d621ecfe21de86f7fdcfa41947 (patch) | |
tree | d94d862bb32b160dcacb5467c099f52748f5f1dd | |
parent | 7162a1e87b3e380133dadc7909081bb70d0a7041 (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.h | 12 | ||||
-rw-r--r-- | mm/huge_memory.c | 6 |
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 | ||
47 | TRACE_EVENT(mm_khugepaged_scan_pmd, | 47 | TRACE_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 | ||
105 | TRACE_EVENT(mm_collapse_huge_page_isolate, | 105 | TRACE_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 | ||
2083 | out: | 2083 | out: |
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 | } |
2582 | out: | 2582 | out: |
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 | } |