mm: hwpoison: introduce idenfity_page_state

Factoring duplicate code into a function.

Link: http://lkml.kernel.org/r/1496305019-5493-10-git-send-email-n-horiguchi@ah.jp.nec.com
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Naoya Horiguchi 2017-07-10 15:47:56 -07:00 committed by Linus Torvalds
parent ddd40d8a2c
commit 0348d2ebec
1 changed files with 25 additions and 32 deletions

View File

@ -1022,9 +1022,31 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
return unmap_success; 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; 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 *p = pfn_to_page(pfn);
struct page *head = compound_head(p); struct page *head = compound_head(p);
int res; int res;
@ -1074,19 +1096,7 @@ static int memory_failure_hugetlb(unsigned long pfn, int trapno, int flags)
goto out; goto out;
} }
res = -EBUSY; res = identify_page_state(pfn, p, page_flags);
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);
out: out:
unlock_page(head); unlock_page(head);
return res; return res;
@ -1112,7 +1122,6 @@ out:
*/ */
int memory_failure(unsigned long pfn, int trapno, int flags) int memory_failure(unsigned long pfn, int trapno, int flags)
{ {
struct page_state *ps;
struct page *p; struct page *p;
struct page *hpage; struct page *hpage;
struct page *orig_head; struct page *orig_head;
@ -1273,23 +1282,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
} }
identify_page_state: identify_page_state:
res = -EBUSY; res = identify_page_state(pfn, p, page_flags);
/*
* 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);
out: out:
unlock_page(p); unlock_page(p);
return res; return res;