From: William Kucharski <william.kucharski@xxxxxxxxxx> When we have the opportunity to use transparent huge pages to map a file, we want to follow the same rules as DAX. Signed-off-by: William Kucharski <william.kucharski@xxxxxxxxxx> [Inline __thp_get_unmapped_area() into thp_get_unmapped_area()] Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- mm/huge_memory.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 15a86b06befc..e78686b628ae 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -535,30 +535,30 @@ bool is_transparent_hugepage(struct page *page) } EXPORT_SYMBOL_GPL(is_transparent_hugepage); -static unsigned long __thp_get_unmapped_area(struct file *filp, - unsigned long addr, unsigned long len, - loff_t off, unsigned long flags, unsigned long size) +unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) { + loff_t off = (loff_t)pgoff << PAGE_SHIFT; loff_t off_end = off + len; - loff_t off_align = round_up(off, size); + loff_t off_align = round_up(off, PMD_SIZE); unsigned long len_pad, ret; - if (off_end <= off_align || (off_end - off_align) < size) - return 0; + if (off_end <= off_align || (off_end - off_align) < PMD_SIZE) + goto regular; - len_pad = len + size; + len_pad = len + PMD_SIZE; if (len_pad < len || (off + len_pad) < off) - return 0; + goto regular; ret = current->mm->get_unmapped_area(filp, addr, len_pad, off >> PAGE_SHIFT, flags); /* - * The failure might be due to length padding. The caller will retry - * without the padding. + * The failure might be due to length padding. Retry without + * the padding. */ if (IS_ERR_VALUE(ret)) - return 0; + goto regular; /* * Do not try to align to THP boundary if allocation at the address @@ -567,23 +567,9 @@ static unsigned long __thp_get_unmapped_area(struct file *filp, if (ret == addr) return addr; - ret += (off - ret) & (size - 1); + ret += (off - ret) & (PMD_SIZE - 1); return ret; -} - -unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) -{ - unsigned long ret; - loff_t off = (loff_t)pgoff << PAGE_SHIFT; - - if (!IS_DAX(filp->f_mapping->host) || !IS_ENABLED(CONFIG_FS_DAX_PMD)) - goto out; - - ret = __thp_get_unmapped_area(filp, addr, len, off, flags, PMD_SIZE); - if (ret) - return ret; -out: +regular: return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags); } EXPORT_SYMBOL_GPL(thp_get_unmapped_area); -- 2.26.2