diff options
Diffstat (limited to 'mm/memory-failure.c')
-rw-r--r-- | mm/memory-failure.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index cd8989c1027e..7211a73ba14d 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -435,7 +435,7 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill, | |||
435 | if (av == NULL) /* Not actually mapped anymore */ | 435 | if (av == NULL) /* Not actually mapped anymore */ |
436 | return; | 436 | return; |
437 | 437 | ||
438 | pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); | 438 | pgoff = page_to_pgoff(page); |
439 | read_lock(&tasklist_lock); | 439 | read_lock(&tasklist_lock); |
440 | for_each_process (tsk) { | 440 | for_each_process (tsk) { |
441 | struct anon_vma_chain *vmac; | 441 | struct anon_vma_chain *vmac; |
@@ -469,7 +469,7 @@ static void collect_procs_file(struct page *page, struct list_head *to_kill, | |||
469 | mutex_lock(&mapping->i_mmap_mutex); | 469 | mutex_lock(&mapping->i_mmap_mutex); |
470 | read_lock(&tasklist_lock); | 470 | read_lock(&tasklist_lock); |
471 | for_each_process(tsk) { | 471 | for_each_process(tsk) { |
472 | pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); | 472 | pgoff_t pgoff = page_to_pgoff(page); |
473 | struct task_struct *t = task_early_kill(tsk, force_early); | 473 | struct task_struct *t = task_early_kill(tsk, force_early); |
474 | 474 | ||
475 | if (!t) | 475 | if (!t) |
@@ -895,7 +895,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
895 | struct page *hpage = *hpagep; | 895 | struct page *hpage = *hpagep; |
896 | struct page *ppage; | 896 | struct page *ppage; |
897 | 897 | ||
898 | if (PageReserved(p) || PageSlab(p)) | 898 | if (PageReserved(p) || PageSlab(p) || !PageLRU(p)) |
899 | return SWAP_SUCCESS; | 899 | return SWAP_SUCCESS; |
900 | 900 | ||
901 | /* | 901 | /* |
@@ -1159,9 +1159,6 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1159 | action_result(pfn, "free buddy, 2nd try", DELAYED); | 1159 | action_result(pfn, "free buddy, 2nd try", DELAYED); |
1160 | return 0; | 1160 | return 0; |
1161 | } | 1161 | } |
1162 | action_result(pfn, "non LRU", IGNORED); | ||
1163 | put_page(p); | ||
1164 | return -EBUSY; | ||
1165 | } | 1162 | } |
1166 | } | 1163 | } |
1167 | 1164 | ||
@@ -1194,6 +1191,9 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1194 | return 0; | 1191 | return 0; |
1195 | } | 1192 | } |
1196 | 1193 | ||
1194 | if (!PageHuge(p) && !PageTransTail(p) && !PageLRU(p)) | ||
1195 | goto identify_page_state; | ||
1196 | |||
1197 | /* | 1197 | /* |
1198 | * For error on the tail page, we should set PG_hwpoison | 1198 | * For error on the tail page, we should set PG_hwpoison |
1199 | * on the head page to show that the hugepage is hwpoisoned | 1199 | * on the head page to show that the hugepage is hwpoisoned |
@@ -1243,6 +1243,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1243 | goto out; | 1243 | goto out; |
1244 | } | 1244 | } |
1245 | 1245 | ||
1246 | identify_page_state: | ||
1246 | res = -EBUSY; | 1247 | res = -EBUSY; |
1247 | /* | 1248 | /* |
1248 | * The first check uses the current page flags which may not have any | 1249 | * The first check uses the current page flags which may not have any |