]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blobdiff - mm/memory-failure.c
Merge branch 'akpm' (patches from Andrew)
[mirror_ubuntu-kernels.git] / mm / memory-failure.c
index 224bd0be223c59925a2a43b9d5f46056206c5214..54879c3390243603ecdcb39686def20d66c6facb 100644 (file)
@@ -68,7 +68,7 @@ atomic_long_t num_poisoned_pages __read_mostly = ATOMIC_LONG_INIT(0);
 
 static bool __page_handle_poison(struct page *page)
 {
-       bool ret;
+       int ret;
 
        zone_pcp_disable(page_zone(page));
        ret = dissolve_free_huge_page(page);
@@ -76,7 +76,7 @@ static bool __page_handle_poison(struct page *page)
                ret = take_page_off_buddy(page);
        zone_pcp_enable(page_zone(page));
 
-       return ret;
+       return ret > 0;
 }
 
 static bool page_handle_poison(struct page *page, bool hugepage_or_freepage, bool release)
@@ -282,9 +282,9 @@ static int kill_proc(struct to_kill *tk, unsigned long pfn, int flags)
 
 /*
  * Unknown page type encountered. Try to check whether it can turn PageLRU by
- * lru_add_drain_all, or a free page by reclaiming slabs when possible.
+ * lru_add_drain_all.
  */
-void shake_page(struct page *p, int access)
+void shake_page(struct page *p)
 {
        if (PageHuge(p))
                return;
@@ -296,11 +296,9 @@ void shake_page(struct page *p, int access)
        }
 
        /*
-        * Only call shrink_node_slabs here (which would also shrink
-        * other caches) if access is not potentially fatal.
+        * TODO: Could shrink slab caches here if a lightweight range-based
+        * shrinker will be available.
         */
-       if (access)
-               drop_slab_node(page_to_nid(p));
 }
 EXPORT_SYMBOL_GPL(shake_page);
 
@@ -391,8 +389,8 @@ static void add_to_kill(struct task_struct *tsk, struct page *p,
 /*
  * Kill the processes that have been collected earlier.
  *
- * Only do anything when DOIT is set, otherwise just free the list
- * (this is used for clean pages which do not need killing)
+ * Only do anything when FORCEKILL is set, otherwise just free the
+ * list (this is used for clean pages which do not need killing)
  * Also when FAIL is set do a force kill because something went
  * wrong earlier.
  */
@@ -867,7 +865,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
        /*
         * Truncation is a bit tricky. Enable it per file system for now.
         *
-        * Open: to take i_mutex or not for this? Right now we don't.
+        * Open: to take i_rwsem or not for this? Right now we don't.
         */
        ret = truncate_error_page(p, pfn, mapping);
 out:
@@ -1205,7 +1203,7 @@ try_again:
                         * page, retry.
                         */
                        if (pass++ < 3) {
-                               shake_page(p, 1);
+                               shake_page(p);
                                goto try_again;
                        }
                        ret = -EIO;
@@ -1222,7 +1220,7 @@ try_again:
                 */
                if (pass++ < 3) {
                        put_page(p);
-                       shake_page(p, 1);
+                       shake_page(p);
                        count_increased = false;
                        goto try_again;
                }
@@ -1230,6 +1228,9 @@ try_again:
                ret = -EIO;
        }
 out:
+       if (ret == -EIO)
+               dump_page(p, "hwpoison: unhandlable page");
+
        return ret;
 }
 
@@ -1271,14 +1272,13 @@ static int get_hwpoison_page(struct page *p, unsigned long flags)
  * the pages and send SIGBUS to the processes if the data was dirty.
  */
 static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
-                                 int flags, struct page **hpagep)
+                                 int flags, struct page *hpage)
 {
        enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_SYNC;
        struct address_space *mapping;
        LIST_HEAD(tokill);
        bool unmap_success;
        int kill = 1, forcekill;
-       struct page *hpage = *hpagep;
        bool mlocked = PageMlocked(hpage);
 
        /*
@@ -1370,7 +1370,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
         * shake_page() again to ensure that it's flushed.
         */
        if (mlocked)
-               shake_page(hpage, 0);
+               shake_page(hpage);
 
        /*
         * Now that the dirty bit has been propagated to the
@@ -1503,7 +1503,7 @@ static int memory_failure_hugetlb(unsigned long pfn, int flags)
                goto out;
        }
 
-       if (!hwpoison_user_mappings(p, pfn, flags, &head)) {
+       if (!hwpoison_user_mappings(p, pfn, flags, head)) {
                action_result(pfn, MF_MSG_UNMAP_FAILED, MF_IGNORED);
                res = -EBUSY;
                goto out;
@@ -1724,7 +1724,7 @@ try_again:
         * The check (unnecessarily) ignores LRU pages being isolated and
         * walked by the page reclaim code, however that's not a big loss.
         */
-       shake_page(p, 0);
+       shake_page(p);
 
        lock_page(p);
 
@@ -1783,7 +1783,7 @@ try_again:
         * Now take care of user space mappings.
         * Abort on fail: __delete_from_page_cache() assumes unmapped page.
         */
-       if (!hwpoison_user_mappings(p, pfn, flags, &p)) {
+       if (!hwpoison_user_mappings(p, pfn, flags, p)) {
                action_result(pfn, MF_MSG_UNMAP_FAILED, MF_IGNORED);
                res = -EBUSY;
                goto unlock_page;
@@ -2099,7 +2099,7 @@ static int __soft_offline_page(struct page *page)
 
        if (isolate_page(hpage, &pagelist)) {
                ret = migrate_pages(&pagelist, alloc_migration_target, NULL,
-                       (unsigned long)&mtc, MIGRATE_SYNC, MR_MEMORY_FAILURE);
+                       (unsigned long)&mtc, MIGRATE_SYNC, MR_MEMORY_FAILURE, NULL);
                if (!ret) {
                        bool release = !huge;
 
@@ -2208,9 +2208,6 @@ retry:
                        try_again = false;
                        goto retry;
                }
-       } else if (ret == -EIO) {
-               pr_info("%s: %#lx: unknown page type: %lx (%pGp)\n",
-                        __func__, pfn, page->flags, &page->flags);
        }
 
        return ret;