|
@@ -696,8 +696,22 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order)
|
|
|
/* we rely on prep_new_huge_page to set the destructor */
|
|
|
set_compound_order(page, order);
|
|
|
__SetPageHead(page);
|
|
|
+ __ClearPageReserved(page);
|
|
|
for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
|
|
|
__SetPageTail(p);
|
|
|
+ /*
|
|
|
+ * For gigantic hugepages allocated through bootmem at
|
|
|
+ * boot, it's safer to be consistent with the not-gigantic
|
|
|
+ * hugepages and clear the PG_reserved bit from all tail pages
|
|
|
+ * too. Otherwse drivers using get_user_pages() to access tail
|
|
|
+ * pages may get the reference counting wrong if they see
|
|
|
+ * PG_reserved set on a tail page (despite the head page not
|
|
|
+ * having PG_reserved set). Enforcing this consistency between
|
|
|
+ * head and tail pages allows drivers to optimize away a check
|
|
|
+ * on the head page when they need know if put_page() is needed
|
|
|
+ * after get_user_pages().
|
|
|
+ */
|
|
|
+ __ClearPageReserved(p);
|
|
|
set_page_count(p, 0);
|
|
|
p->first_page = page;
|
|
|
}
|
|
@@ -1330,9 +1344,9 @@ static void __init gather_bootmem_prealloc(void)
|
|
|
#else
|
|
|
page = virt_to_page(m);
|
|
|
#endif
|
|
|
- __ClearPageReserved(page);
|
|
|
WARN_ON(page_count(page) != 1);
|
|
|
prep_compound_huge_page(page, h->order);
|
|
|
+ WARN_ON(PageReserved(page));
|
|
|
prep_new_huge_page(h, page, page_to_nid(page));
|
|
|
/*
|
|
|
* If we had gigantic hugepages allocated at boot time, we need
|