diff options
Diffstat (limited to 'mm/memory-failure.c')
-rw-r--r-- | mm/memory-failure.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 1a9242c53315..f4c9fa1149e2 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1421,12 +1421,13 @@ static int soft_offline_huge_page(struct page *page, int flags) if (PageHWPoison(hpage)) { pr_info("soft offline: %#lx hugepage already poisoned\n", pfn); - return -EBUSY; + ret = -EBUSY; + goto out; } ret = get_any_page(page, pfn, flags); if (ret < 0) - return ret; + goto out; if (ret == 0) goto done; @@ -1437,14 +1438,14 @@ static int soft_offline_huge_page(struct page *page, int flags) if (ret) { pr_info("soft offline: %#lx: migration failed %d, type %lx\n", pfn, ret, page->flags); - return ret; + goto out; } done: /* keep elevated page count for bad page */ atomic_long_add(1 << compound_trans_order(hpage), &mce_bad_pages); set_page_hwpoison_huge_page(hpage); dequeue_hwpoisoned_huge_page(hpage); - +out: return ret; } @@ -1476,24 +1477,28 @@ int soft_offline_page(struct page *page, int flags) unsigned long pfn = page_to_pfn(page); struct page *hpage = compound_trans_head(page); - if (PageHuge(page)) - return soft_offline_huge_page(page, flags); + if (PageHuge(page)) { + ret = soft_offline_huge_page(page, flags); + goto out; + } if (PageTransHuge(hpage)) { if (PageAnon(hpage) && unlikely(split_huge_page(hpage))) { pr_info("soft offline: %#lx: failed to split THP\n", pfn); - return -EBUSY; + ret = -EBUSY; + goto out; } } if (PageHWPoison(page)) { pr_info("soft offline: %#lx page already poisoned\n", pfn); - return -EBUSY; + ret = -EBUSY; + goto out; } ret = get_any_page(page, pfn, flags); if (ret < 0) - return ret; + goto out; if (ret == 0) goto done; @@ -1512,14 +1517,15 @@ int soft_offline_page(struct page *page, int flags) */ ret = get_any_page(page, pfn, 0); if (ret < 0) - return ret; + goto out; if (ret == 0) goto done; } if (!PageLRU(page)) { pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n", pfn, page->flags); - return -EIO; + ret = -EIO; + goto out; } /* @@ -1575,12 +1581,12 @@ int soft_offline_page(struct page *page, int flags) pfn, ret, page_count(page), page->flags); } if (ret) - return ret; + goto out; done: /* keep elevated page count for bad page */ - atomic_long_add(1, &mce_bad_pages); + atomic_long_inc(&mce_bad_pages); SetPageHWPoison(page); - +out: return ret; } |