diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index e4dae98ba7f8..2457ea2c6dca 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -35,8 +35,8 @@
/*
* Flags for vmemmap_populate_range and friends.
*/
-/* Get a ref on the head page struct page, for ZONE_DEVICE compound pages */
-#define VMEMMAP_POPULATE_PAGEREF 0x0001
+/* Vmemmap population for ZONE_DEVICE compound pages */
+#define VMEMMAP_POPULATE_DAX 0x0001
#include "internal.h"
#include "mm_init.h"
@@ -243,13 +243,17 @@ static inline struct page *vmemmap_shared_tail_page(unsigned int order,
#endif
static __meminit void *vmemmap_alloc_pte(unsigned long pfn, int node,
- struct vmem_altmap *altmap)
+ struct vmem_altmap *altmap, unsigned long flags)
{
struct zone *zone;
struct page *page;
const unsigned int order = pfn_to_section_compound_order(pfn);
- if (!vmemmap_optimizable_pfn(pfn))
+ /*
+ * Device DAX still relies on vmemmap_populate_compound_pages() for
+ * head/first-tail allocation and tail-page reuse.
+ */
+ if (!vmemmap_optimizable_pfn(pfn) || flags & VMEMMAP_POPULATE_DAX)
return vmemmap_alloc_block_buf(PAGE_SIZE, node, altmap);
zone = pfn_to_zone(pfn, node);@@ -271,7 +275,7 @@ static pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, in
pte_t entry;
if (ptpfn == (unsigned long)-1) {
- void *p = vmemmap_alloc_pte(pfn, node, altmap);
+ void *p = vmemmap_alloc_pte(pfn, node, altmap, flags);
if (!p)
return NULL;@@ -286,7 +290,7 @@ static pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, in
* and through vmemmap_populate_compound_pages() when
* slab is available.
*/
- if (flags & VMEMMAP_POPULATE_PAGEREF)
+ if (flags & VMEMMAP_POPULATE_DAX)
get_page(pfn_to_page(ptpfn));
}
entry = pfn_pte(ptpfn, PAGE_KERNEL);
@@ -546,6 +550,7 @@ static int __meminit vmemmap_populate_compound_pages(unsigned long start_pfn,
unsigned long size, addr;
pte_t *pte;
int rc;
+ unsigned long flags = VMEMMAP_POPULATE_DAX;
if (reuse_compound_section(start_pfn, pgmap)) {
pte = compound_section_tail_page(start);@@ -557,8 +562,7 @@ static int __meminit vmemmap_populate_compound_pages(unsigned long start_pfn,
* with just tail struct pages.
*/
return vmemmap_populate_range(start, end, node, NULL,
- pte_pfn(ptep_get(pte)),
- VMEMMAP_POPULATE_PAGEREF);
+ pte_pfn(ptep_get(pte)), flags);
}
size = min(end - start, pgmap_vmemmap_nr(pgmap) * sizeof(struct page));
@@ -566,13 +570,13 @@ static int __meminit vmemmap_populate_compound_pages(unsigned long start_pfn,
unsigned long next, last = addr + size;
/* Populate the head page vmemmap page */
- pte = vmemmap_populate_address(addr, node, NULL, -1, 0);
+ pte = vmemmap_populate_address(addr, node, NULL, -1, flags);
if (!pte)
return -ENOMEM;
/* Populate the tail pages vmemmap page */
next = addr + PAGE_SIZE;
- pte = vmemmap_populate_address(next, node, NULL, -1, 0);
+ pte = vmemmap_populate_address(next, node, NULL, -1, flags);
if (!pte)
return -ENOMEM;
@@ -582,8 +586,7 @@ static int __meminit vmemmap_populate_compound_pages(unsigned long start_pfn,
*/
next += PAGE_SIZE;
rc = vmemmap_populate_range(next, last, node, NULL,
- pte_pfn(ptep_get(pte)),
- VMEMMAP_POPULATE_PAGEREF);
+ pte_pfn(ptep_get(pte)), flags);
if (rc)
return -ENOMEM;
}
--
2.54.0