aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory-failure.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory-failure.c')
-rw-r--r--mm/memory-failure.c49
1 files changed, 24 insertions, 25 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 729d4b15b645..e17ec3f1c637 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -370,9 +370,6 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
370 int ret = FAILED; 370 int ret = FAILED;
371 struct address_space *mapping; 371 struct address_space *mapping;
372 372
373 if (!isolate_lru_page(p))
374 page_cache_release(p);
375
376 /* 373 /*
377 * For anonymous pages we're done the only reference left 374 * For anonymous pages we're done the only reference left
378 * should be the one m_f() holds. 375 * should be the one m_f() holds.
@@ -498,30 +495,18 @@ static int me_pagecache_dirty(struct page *p, unsigned long pfn)
498 */ 495 */
499static int me_swapcache_dirty(struct page *p, unsigned long pfn) 496static int me_swapcache_dirty(struct page *p, unsigned long pfn)
500{ 497{
501 int ret = FAILED;
502
503 ClearPageDirty(p); 498 ClearPageDirty(p);
504 /* Trigger EIO in shmem: */ 499 /* Trigger EIO in shmem: */
505 ClearPageUptodate(p); 500 ClearPageUptodate(p);
506 501
507 if (!isolate_lru_page(p)) { 502 return DELAYED;
508 page_cache_release(p);
509 ret = DELAYED;
510 }
511
512 return ret;
513} 503}
514 504
515static int me_swapcache_clean(struct page *p, unsigned long pfn) 505static int me_swapcache_clean(struct page *p, unsigned long pfn)
516{ 506{
517 int ret = FAILED;
518
519 if (!isolate_lru_page(p)) {
520 page_cache_release(p);
521 ret = RECOVERED;
522 }
523 delete_from_swap_cache(p); 507 delete_from_swap_cache(p);
524 return ret; 508
509 return RECOVERED;
525} 510}
526 511
527/* 512/*
@@ -611,8 +596,6 @@ static struct page_state {
611 { 0, 0, "unknown page state", me_unknown }, 596 { 0, 0, "unknown page state", me_unknown },
612}; 597};
613 598
614#undef lru
615
616static void action_result(unsigned long pfn, char *msg, int result) 599static void action_result(unsigned long pfn, char *msg, int result)
617{ 600{
618 struct page *page = NULL; 601 struct page *page = NULL;
@@ -664,9 +647,6 @@ static void hwpoison_user_mappings(struct page *p, unsigned long pfn,
664 if (PageReserved(p) || PageCompound(p) || PageSlab(p)) 647 if (PageReserved(p) || PageCompound(p) || PageSlab(p))
665 return; 648 return;
666 649
667 if (!PageLRU(p))
668 lru_add_drain_all();
669
670 /* 650 /*
671 * This check implies we don't kill processes if their pages 651 * This check implies we don't kill processes if their pages
672 * are in the swap cache early. Those are always late kills. 652 * are in the swap cache early. Those are always late kills.
@@ -738,6 +718,7 @@ static void hwpoison_user_mappings(struct page *p, unsigned long pfn,
738 718
739int __memory_failure(unsigned long pfn, int trapno, int ref) 719int __memory_failure(unsigned long pfn, int trapno, int ref)
740{ 720{
721 unsigned long lru_flag;
741 struct page_state *ps; 722 struct page_state *ps;
742 struct page *p; 723 struct page *p;
743 int res; 724 int res;
@@ -775,6 +756,24 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
775 } 756 }
776 757
777 /* 758 /*
759 * We ignore non-LRU pages for good reasons.
760 * - PG_locked is only well defined for LRU pages and a few others
761 * - to avoid races with __set_page_locked()
762 * - to avoid races with __SetPageSlab*() (and more non-atomic ops)
763 * The check (unnecessarily) ignores LRU pages being isolated and
764 * walked by the page reclaim code, however that's not a big loss.
765 */
766 if (!PageLRU(p))
767 lru_add_drain_all();
768 lru_flag = p->flags & lru;
769 if (isolate_lru_page(p)) {
770 action_result(pfn, "non LRU", IGNORED);
771 put_page(p);
772 return -EBUSY;
773 }
774 page_cache_release(p);
775
776 /*
778 * Lock the page and wait for writeback to finish. 777 * Lock the page and wait for writeback to finish.
779 * It's very difficult to mess with pages currently under IO 778 * It's very difficult to mess with pages currently under IO
780 * and in many cases impossible, so we just avoid it here. 779 * and in many cases impossible, so we just avoid it here.
@@ -790,7 +789,7 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
790 /* 789 /*
791 * Torn down by someone else? 790 * Torn down by someone else?
792 */ 791 */
793 if (PageLRU(p) && !PageSwapCache(p) && p->mapping == NULL) { 792 if ((lru_flag & lru) && !PageSwapCache(p) && p->mapping == NULL) {
794 action_result(pfn, "already truncated LRU", IGNORED); 793 action_result(pfn, "already truncated LRU", IGNORED);
795 res = 0; 794 res = 0;
796 goto out; 795 goto out;
@@ -798,7 +797,7 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
798 797
799 res = -EBUSY; 798 res = -EBUSY;
800 for (ps = error_states;; ps++) { 799 for (ps = error_states;; ps++) {
801 if ((p->flags & ps->mask) == ps->res) { 800 if (((p->flags | lru_flag)& ps->mask) == ps->res) {
802 res = page_action(ps, p, pfn, ref); 801 res = page_action(ps, p, pfn, ref);
803 break; 802 break;
804 } 803 }