lkml.org 
[lkml]   [2020]   [Sep]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH 18/24] mm/hugetlb: Clear PageHWPoison on the non-error memory page
    Date
    Because we reuse the first tail page, if we set PageHWPosion on a
    tail page. It indicates that we may set PageHWPoison on a series
    of pages. So we need to clear PageHWPoison on the non-error pages.
    We use the head[3].mapping to record the real error page index and
    clear non-error page PageHWPoison later.

    Signed-off-by: Muchun Song <songmuchun@bytedance.com>
    ---
    mm/hugetlb.c | 33 +++++++++++++++++++++++++++++++++
    1 file changed, 33 insertions(+)

    diff --git a/mm/hugetlb.c b/mm/hugetlb.c
    index 34706cec21ec..8666cedf9a7b 100644
    --- a/mm/hugetlb.c
    +++ b/mm/hugetlb.c
    @@ -1847,6 +1847,21 @@ static inline void free_gigantic_page_comm(struct hstate *h, struct page *page)
    {
    free_gigantic_page(page, huge_page_order(h));
    }
    +
    +static inline bool subpage_hwpoison(struct page *head, struct page *page)
    +{
    + return page_private(head + 4) == page - head;
    +}
    +
    +static inline void set_subpage_hwpoison(struct page *head, struct page *page)
    +{
    + set_page_private(head + 4, page - head);
    +}
    +
    +static inline void clear_subpage_hwpoison(struct page *head)
    +{
    + set_page_private(head + 4, 0);
    +}
    #else
    static inline void hugetlb_vmemmap_init(struct hstate *h)
    {
    @@ -1894,6 +1909,19 @@ static inline void free_gigantic_page_comm(struct hstate *h, struct page *page)
    free_gigantic_page(page, huge_page_order(h));
    spin_lock(&hugetlb_lock);
    }
    +
    +static inline bool subpage_hwpoison(struct page *head, struct page *page)
    +{
    + return true;
    +}
    +
    +static inline void set_subpage_hwpoison(struct page *head, struct page *page)
    +{
    +}
    +
    +static inline void clear_subpage_hwpoison(struct page *head)
    +{
    +}
    #endif

    static void update_and_free_page(struct hstate *h, struct page *page)
    @@ -1918,6 +1946,9 @@ static void __free_hugepage(struct hstate *h, struct page *page)
    1 << PG_referenced | 1 << PG_dirty |
    1 << PG_active | 1 << PG_private |
    1 << PG_writeback);
    +
    + if (PageHWPoison(page + i) && !subpage_hwpoison(page, page + i))
    + ClearPageHWPoison(page + i);
    }
    VM_BUG_ON_PAGE(hugetlb_cgroup_from_page(page), page);
    VM_BUG_ON_PAGE(hugetlb_cgroup_from_page_rsvd(page), page);
    @@ -2107,6 +2138,7 @@ static void prep_new_huge_page(struct hstate *h, struct page *page, int nid)
    free_huge_page_vmemmap(h, page);
    /* Must be called before the initialization of @page->lru */
    vmemmap_pgtable_free(h, page);
    + clear_subpage_hwpoison(page);

    INIT_LIST_HEAD(&page->lru);
    set_compound_page_dtor(page, HUGETLB_PAGE_DTOR);
    @@ -2477,6 +2509,7 @@ int dissolve_free_huge_page(struct page *page)
    SetPageHWPoison(page);
    ClearPageHWPoison(head);
    }
    + set_subpage_hwpoison(head, page);
    list_del(&head->lru);
    h->free_huge_pages--;
    h->free_huge_pages_node[nid]--;
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-09-16 02:42    [W:4.048 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site