|
@@ -12,6 +12,17 @@
|
|
|
#include <linux/rwsem.h>
|
|
|
#include <asm/pgtable.h>
|
|
|
|
|
|
+static inline void get_huge_page_tail(struct page *page)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * __split_huge_page_refcount() cannot run
|
|
|
+ * from under us.
|
|
|
+ */
|
|
|
+ VM_BUG_ON(page_mapcount(page) < 0);
|
|
|
+ VM_BUG_ON(atomic_read(&page->_count) != 0);
|
|
|
+ atomic_inc(&page->_mapcount);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* The performance critical leaf functions are made noinline otherwise gcc
|
|
|
* inlines everything into a single function which results in too much
|
|
@@ -56,6 +67,8 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
|
|
|
put_page(head);
|
|
|
return 0;
|
|
|
}
|
|
|
+ if (head != page)
|
|
|
+ get_huge_page_tail(page);
|
|
|
|
|
|
pages[*nr] = page;
|
|
|
(*nr)++;
|