mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 21:54:11 +08:00
hugetlb: simplify prep_compound_gigantic_page ref count racing code
Code in prep_compound_gigantic_page waits for a rcu grace period if it notices a temporarily inflated ref count on a tail page. This was due to the identified potential race with speculative page cache references which could only last for a rcu grace period. This is overly complicated as this situation is VERY unlikely to ever happen. Instead, just quickly return an error. Also, only print a warning in prep_compound_gigantic_page instead of multiple callers. Link: https://lkml.kernel.org/r/20210809184832.18342-2-mike.kravetz@oracle.com Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Cc: David Hildenbrand <david@redhat.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Mina Almasry <almasrymina@google.com> Cc: Muchun Song <songmuchun@bytedance.com> Cc: Naoya Horiguchi <naoya.horiguchi@linux.dev> Cc: Oscar Salvador <osalvador@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
f87060d345
commit
416d85ed3e
17
mm/hugetlb.c
17
mm/hugetlb.c
@ -1657,16 +1657,14 @@ static bool prep_compound_gigantic_page(struct page *page, unsigned int order)
|
|||||||
* cache adding could take a ref on a 'to be' tail page.
|
* cache adding could take a ref on a 'to be' tail page.
|
||||||
* We need to respect any increased ref count, and only set
|
* We need to respect any increased ref count, and only set
|
||||||
* the ref count to zero if count is currently 1. If count
|
* the ref count to zero if count is currently 1. If count
|
||||||
* is not 1, we call synchronize_rcu in the hope that a rcu
|
* is not 1, we return an error. An error return indicates
|
||||||
* grace period will cause ref count to drop and then retry.
|
* the set of pages can not be converted to a gigantic page.
|
||||||
* If count is still inflated on retry we return an error and
|
* The caller who allocated the pages should then discard the
|
||||||
* must discard the pages.
|
* pages using the appropriate free interface.
|
||||||
*/
|
*/
|
||||||
if (!page_ref_freeze(p, 1)) {
|
if (!page_ref_freeze(p, 1)) {
|
||||||
pr_info("HugeTLB unexpected inflated ref count on freshly allocated page\n");
|
pr_warn("HugeTLB page can not be used due to unexpected inflated ref count\n");
|
||||||
synchronize_rcu();
|
goto out_error;
|
||||||
if (!page_ref_freeze(p, 1))
|
|
||||||
goto out_error;
|
|
||||||
}
|
}
|
||||||
set_page_count(p, 0);
|
set_page_count(p, 0);
|
||||||
set_compound_head(p, page);
|
set_compound_head(p, page);
|
||||||
@ -1830,7 +1828,6 @@ retry:
|
|||||||
retry = true;
|
retry = true;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
pr_warn("HugeTLB page can not be used due to unexpected inflated ref count\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2828,8 +2825,8 @@ static void __init gather_bootmem_prealloc(void)
|
|||||||
prep_new_huge_page(h, page, page_to_nid(page));
|
prep_new_huge_page(h, page, page_to_nid(page));
|
||||||
put_page(page); /* add to the hugepage allocator */
|
put_page(page); /* add to the hugepage allocator */
|
||||||
} else {
|
} else {
|
||||||
|
/* VERY unlikely inflated ref count on a tail page */
|
||||||
free_gigantic_page(page, huge_page_order(h));
|
free_gigantic_page(page, huge_page_order(h));
|
||||||
pr_warn("HugeTLB page can not be used due to unexpected inflated ref count\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user