Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c791ace1 authored by Dave Jiang's avatar Dave Jiang Committed by Linus Torvalds
Browse files

mm: replace FAULT_FLAG_SIZE with parameter to huge_fault

Since the introduction of FAULT_FLAG_SIZE to the vm_fault flag, it has
been somewhat painful with getting the flags set and removed at the
correct locations.  More than one kernel oops was introduced due to
difficulties of getting the placement correctly.

Remove the flag values and introduce an input parameter to huge_fault
that indicates the size of the page entry.  This makes the code easier
to trace and should avoid the issues we see with the fault flags where
removal of the flag was necessary in the fallback paths.

Link: http://lkml.kernel.org/r/148615748258.43180.1690152053774975329.stgit@djiang5-desk3.ch.intel.com


Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
Tested-by: default avatarDan Williams <dan.j.williams@intel.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Cc: Matthew Wilcox <mawilcox@microsoft.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Nilesh Choudhury <nilesh.choudhury@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9557feee
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -538,7 +538,8 @@ static int __dax_dev_pud_fault(struct dax_dev *dax_dev, struct vm_fault *vmf)
}
#endif /* !CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */

static int dax_dev_fault(struct vm_fault *vmf)
static int dax_dev_huge_fault(struct vm_fault *vmf,
		enum page_entry_size pe_size)
{
	int rc;
	struct file *filp = vmf->vma->vm_file;
@@ -550,14 +551,14 @@ static int dax_dev_fault(struct vm_fault *vmf)
			vmf->vma->vm_start, vmf->vma->vm_end);

	rcu_read_lock();
	switch (vmf->flags & FAULT_FLAG_SIZE_MASK) {
	case FAULT_FLAG_SIZE_PTE:
	switch (pe_size) {
	case PE_SIZE_PTE:
		rc = __dax_dev_pte_fault(dax_dev, vmf);
		break;
	case FAULT_FLAG_SIZE_PMD:
	case PE_SIZE_PMD:
		rc = __dax_dev_pmd_fault(dax_dev, vmf);
		break;
	case FAULT_FLAG_SIZE_PUD:
	case PE_SIZE_PUD:
		rc = __dax_dev_pud_fault(dax_dev, vmf);
		break;
	default:
@@ -568,9 +569,14 @@ static int dax_dev_fault(struct vm_fault *vmf)
	return rc;
}

static int dax_dev_fault(struct vm_fault *vmf)
{
	return dax_dev_huge_fault(vmf, PE_SIZE_PTE);
}

static const struct vm_operations_struct dax_dev_vm_ops = {
	.fault = dax_dev_fault,
	.huge_fault = dax_dev_fault,
	.huge_fault = dax_dev_huge_fault,
};

static int dax_mmap(struct file *filp, struct vm_area_struct *vma)
+5 −4
Original line number Diff line number Diff line
@@ -1452,12 +1452,13 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, struct iomap_ops *ops)
 * has done all the necessary locking for page fault to proceed
 * successfully.
 */
int dax_iomap_fault(struct vm_fault *vmf, const struct iomap_ops *ops)
int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size,
		    const struct iomap_ops *ops)
{
	switch (vmf->flags & FAULT_FLAG_SIZE_MASK) {
	case FAULT_FLAG_SIZE_PTE:
	switch (pe_size) {
	case PE_SIZE_PTE:
		return dax_iomap_pte_fault(vmf, ops);
	case FAULT_FLAG_SIZE_PMD:
	case PE_SIZE_PMD:
		return dax_iomap_pmd_fault(vmf, ops);
	default:
		return VM_FAULT_FALLBACK;
+1 −1
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ static int ext2_dax_fault(struct vm_fault *vmf)
	}
	down_read(&ei->dax_sem);

	ret = dax_iomap_fault(vmf, &ext2_iomap_ops);
	ret = dax_iomap_fault(vmf, PE_SIZE_PTE, &ext2_iomap_ops);

	up_read(&ei->dax_sem);
	if (vmf->flags & FAULT_FLAG_WRITE)
+9 −3
Original line number Diff line number Diff line
@@ -253,7 +253,8 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
}

#ifdef CONFIG_FS_DAX
static int ext4_dax_fault(struct vm_fault *vmf)
static int ext4_dax_huge_fault(struct vm_fault *vmf,
		enum page_entry_size pe_size)
{
	int result;
	struct inode *inode = file_inode(vmf->vma->vm_file);
@@ -265,7 +266,7 @@ static int ext4_dax_fault(struct vm_fault *vmf)
		file_update_time(vmf->vma->vm_file);
	}
	down_read(&EXT4_I(inode)->i_mmap_sem);
	result = dax_iomap_fault(vmf, &ext4_iomap_ops);
	result = dax_iomap_fault(vmf, pe_size, &ext4_iomap_ops);
	up_read(&EXT4_I(inode)->i_mmap_sem);
	if (write)
		sb_end_pagefault(sb);
@@ -273,6 +274,11 @@ static int ext4_dax_fault(struct vm_fault *vmf)
	return result;
}

static int ext4_dax_fault(struct vm_fault *vmf)
{
	return ext4_dax_huge_fault(vmf, PE_SIZE_PTE);
}

/*
 * Handle write fault for VM_MIXEDMAP mappings. Similarly to ext4_dax_fault()
 * handler we check for races agaist truncate. Note that since we cycle through
@@ -305,7 +311,7 @@ static int ext4_dax_pfn_mkwrite(struct vm_fault *vmf)

static const struct vm_operations_struct ext4_dax_vm_ops = {
	.fault		= ext4_dax_fault,
	.huge_fault	= ext4_dax_fault,
	.huge_fault	= ext4_dax_huge_fault,
	.page_mkwrite	= ext4_dax_fault,
	.pfn_mkwrite	= ext4_dax_pfn_mkwrite,
};
+5 −4
Original line number Diff line number Diff line
@@ -1391,7 +1391,7 @@ xfs_filemap_page_mkwrite(
	xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);

	if (IS_DAX(inode)) {
		ret = dax_iomap_fault(vmf, &xfs_iomap_ops);
		ret = dax_iomap_fault(vmf, PE_SIZE_PTE, &xfs_iomap_ops);
	} else {
		ret = iomap_page_mkwrite(vmf, &xfs_iomap_ops);
		ret = block_page_mkwrite_return(ret);
@@ -1418,7 +1418,7 @@ xfs_filemap_fault(

	xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
	if (IS_DAX(inode))
		ret = dax_iomap_fault(vmf, &xfs_iomap_ops);
		ret = dax_iomap_fault(vmf, PE_SIZE_PTE, &xfs_iomap_ops);
	else
		ret = filemap_fault(vmf);
	xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
@@ -1435,7 +1435,8 @@ xfs_filemap_fault(
 */
STATIC int
xfs_filemap_huge_fault(
	struct vm_fault		*vmf)
	struct vm_fault		*vmf,
	enum page_entry_size	pe_size)
{
	struct inode		*inode = file_inode(vmf->vma->vm_file);
	struct xfs_inode	*ip = XFS_I(inode);
@@ -1452,7 +1453,7 @@ xfs_filemap_huge_fault(
	}

	xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
	ret = dax_iomap_fault(vmf, &xfs_iomap_ops);
	ret = dax_iomap_fault(vmf, pe_size, &xfs_iomap_ops);
	xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED);

	if (vmf->flags & FAULT_FLAG_WRITE)
Loading