]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - mm/memory-failure.c
Merge tag 'renesas-fixes-for-v4.13' of https://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-bionic-kernel.git] / mm / memory-failure.c
index 2aec57c07652e966968e0cdf1bd36ec65f11ec94..1cd3b3569af8a79285b75bfdb2485b7de7a69aa8 100644 (file)
@@ -1022,9 +1022,31 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
        return unmap_success;
 }
 
-static int memory_failure_hugetlb(unsigned long pfn, int trapno, int flags)
+static int identify_page_state(unsigned long pfn, struct page *p,
+                               unsigned long page_flags)
 {
        struct page_state *ps;
+
+       /*
+        * The first check uses the current page flags which may not have any
+        * relevant information. The second check with the saved page flags is
+        * carried out only if the first check can't determine the page status.
+        */
+       for (ps = error_states;; ps++)
+               if ((p->flags & ps->mask) == ps->res)
+                       break;
+
+       page_flags |= (p->flags & (1UL << PG_dirty));
+
+       if (!ps->mask)
+               for (ps = error_states;; ps++)
+                       if ((page_flags & ps->mask) == ps->res)
+                               break;
+       return page_action(ps, p, pfn);
+}
+
+static int memory_failure_hugetlb(unsigned long pfn, int trapno, int flags)
+{
        struct page *p = pfn_to_page(pfn);
        struct page *head = compound_head(p);
        int res;
@@ -1074,19 +1096,7 @@ static int memory_failure_hugetlb(unsigned long pfn, int trapno, int flags)
                goto out;
        }
 
-       res = -EBUSY;
-
-       for (ps = error_states;; ps++)
-               if ((p->flags & ps->mask) == ps->res)
-                       break;
-
-       page_flags |= (p->flags & (1UL << PG_dirty));
-
-       if (!ps->mask)
-               for (ps = error_states;; ps++)
-                       if ((page_flags & ps->mask) == ps->res)
-                               break;
-       res = page_action(ps, p, pfn);
+       res = identify_page_state(pfn, p, page_flags);
 out:
        unlock_page(head);
        return res;
@@ -1112,7 +1122,6 @@ out:
  */
 int memory_failure(unsigned long pfn, int trapno, int flags)
 {
-       struct page_state *ps;
        struct page *p;
        struct page *hpage;
        struct page *orig_head;
@@ -1273,23 +1282,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
        }
 
 identify_page_state:
-       res = -EBUSY;
-       /*
-        * The first check uses the current page flags which may not have any
-        * relevant information. The second check with the saved page flagss is
-        * carried out only if the first check can't determine the page status.
-        */
-       for (ps = error_states;; ps++)
-               if ((p->flags & ps->mask) == ps->res)
-                       break;
-
-       page_flags |= (p->flags & (1UL << PG_dirty));
-
-       if (!ps->mask)
-               for (ps = error_states;; ps++)
-                       if ((page_flags & ps->mask) == ps->res)
-                               break;
-       res = page_action(ps, p, pfn);
+       res = identify_page_state(pfn, p, page_flags);
 out:
        unlock_page(p);
        return res;
@@ -1491,16 +1484,8 @@ EXPORT_SYMBOL(unpoison_memory);
 static struct page *new_page(struct page *p, unsigned long private, int **x)
 {
        int nid = page_to_nid(p);
-       if (PageHuge(p)) {
-               struct hstate *hstate = page_hstate(compound_head(p));
 
-               if (hstate_is_gigantic(hstate))
-                       return alloc_huge_page_node(hstate, NUMA_NO_NODE);
-
-               return alloc_huge_page_node(hstate, nid);
-       } else {
-               return __alloc_pages_node(nid, GFP_HIGHUSER_MOVABLE, 0);
-       }
+       return new_page_nodemask(p, nid, &node_states[N_MEMORY]);
 }
 
 /*