aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dax.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2019-05-15 22:51:48 -0700
committerOlof Johansson <olof@lixom.net>2019-05-15 22:51:48 -0700
commit7a0c4c17089a8aff52f516f0f52002be52950aae (patch)
tree474dc451d62a1ba788ed52c4cecf93f9e50cc39a /fs/dax.c
parentMerge tag 'v5.2-rockchip-soc32-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into arm/soc (diff)
parentMerge tag 'davinci-fixes-for-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci into fixes (diff)
downloadlinux-stable-7a0c4c17089a8aff52f516f0f52002be52950aae.tar.xz
linux-stable-7a0c4c17089a8aff52f516f0f52002be52950aae.zip
Merge branch 'fixes' into arm/soc
Merge in a few pending fixes from pre-5.1 that didn't get sent in: MAINTAINERS: update arch/arm/mach-davinci ARM: dts: ls1021: Fix SGMII PCS link remaining down after PHY disconnect ARM: dts: imx6q-logicpd: Reduce inrush current on USBH1 ARM: dts: imx6q-logicpd: Reduce inrush current on start ARM: dts: imx: Fix the AR803X phy-mode ARM: dts: sun8i: a33: Reintroduce default pinctrl muxing arm64: dts: allwinner: a64: Rename hpvcc-supply to cpvdd-supply ARM: sunxi: fix a leaked reference by adding missing of_node_put ARM: sunxi: fix a leaked reference by adding missing of_node_put Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'fs/dax.c')
-rw-r--r--fs/dax.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/dax.c b/fs/dax.c
index ca0671d55aa6..e5e54da1715f 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -33,6 +33,7 @@
#include <linux/sizes.h>
#include <linux/mmu_notifier.h>
#include <linux/iomap.h>
+#include <asm/pgalloc.h>
#include "internal.h"
#define CREATE_TRACE_POINTS
@@ -1407,7 +1408,9 @@ static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf,
{
struct address_space *mapping = vmf->vma->vm_file->f_mapping;
unsigned long pmd_addr = vmf->address & PMD_MASK;
+ struct vm_area_struct *vma = vmf->vma;
struct inode *inode = mapping->host;
+ pgtable_t pgtable = NULL;
struct page *zero_page;
spinlock_t *ptl;
pmd_t pmd_entry;
@@ -1422,12 +1425,22 @@ static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf,
*entry = dax_insert_entry(xas, mapping, vmf, *entry, pfn,
DAX_PMD | DAX_ZERO_PAGE, false);
+ if (arch_needs_pgtable_deposit()) {
+ pgtable = pte_alloc_one(vma->vm_mm);
+ if (!pgtable)
+ return VM_FAULT_OOM;
+ }
+
ptl = pmd_lock(vmf->vma->vm_mm, vmf->pmd);
if (!pmd_none(*(vmf->pmd))) {
spin_unlock(ptl);
goto fallback;
}
+ if (pgtable) {
+ pgtable_trans_huge_deposit(vma->vm_mm, vmf->pmd, pgtable);
+ mm_inc_nr_ptes(vma->vm_mm);
+ }
pmd_entry = mk_pmd(zero_page, vmf->vma->vm_page_prot);
pmd_entry = pmd_mkhuge(pmd_entry);
set_pmd_at(vmf->vma->vm_mm, pmd_addr, vmf->pmd, pmd_entry);
@@ -1436,6 +1449,8 @@ static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf,
return VM_FAULT_NOPAGE;
fallback:
+ if (pgtable)
+ pte_free(vma->vm_mm, pgtable);
trace_dax_pmd_load_hole_fallback(inode, vmf, zero_page, *entry);
return VM_FAULT_FALLBACK;
}