This is a note to let you know that I've just added the patch titled
dax: Avoid page invalidation races and unnecessary radix tree traversals
to the 4.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: dax-avoid-page-invalidation-races-and-unnecessary-radix-tree-traversals.patch and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
From foo@baz Wed Dec 6 17:39:55 CET 2017
From: Jan Kara jack@suse.cz Date: Wed, 10 Aug 2016 17:10:28 +0200 Subject: dax: Avoid page invalidation races and unnecessary radix tree traversals
From: Jan Kara jack@suse.cz
[ Upstream commit e3fce68cdbed297d927e993b3ea7b8b1cee545da ]
Currently dax_iomap_rw() takes care of invalidating page tables and evicting hole pages from the radix tree when write(2) to the file happens. This invalidation is only necessary when there is some block allocation resulting from write(2). Furthermore in current place the invalidation is racy wrt page fault instantiating a hole page just after we have invalidated it.
So perform the page invalidation inside dax_iomap_actor() where we can do it only when really necessary and after blocks have been allocated so nobody will be instantiating new hole pages anymore.
Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Ross Zwisler ross.zwisler@linux.intel.com Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin alexander.levin@verizon.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/dax.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-)
--- a/fs/dax.c +++ b/fs/dax.c @@ -1265,6 +1265,17 @@ iomap_dax_actor(struct inode *inode, lof if (WARN_ON_ONCE(iomap->type != IOMAP_MAPPED)) return -EIO;
+ /* + * Write can allocate block for an area which has a hole page mapped + * into page tables. We have to tear down these mappings so that data + * written by write(2) is visible in mmap. + */ + if ((iomap->flags & IOMAP_F_NEW) && inode->i_mapping->nrpages) { + invalidate_inode_pages2_range(inode->i_mapping, + pos >> PAGE_SHIFT, + (end - 1) >> PAGE_SHIFT); + } + while (pos < end) { unsigned offset = pos & (PAGE_SIZE - 1); struct blk_dax_ctl dax = { 0 }; @@ -1329,23 +1340,6 @@ iomap_dax_rw(struct kiocb *iocb, struct if (iov_iter_rw(iter) == WRITE) flags |= IOMAP_WRITE;
- /* - * Yes, even DAX files can have page cache attached to them: A zeroed - * page is inserted into the pagecache when we have to serve a write - * fault on a hole. It should never be dirtied and can simply be - * dropped from the pagecache once we get real data for the page. - * - * XXX: This is racy against mmap, and there's nothing we can do about - * it. We'll eventually need to shift this down even further so that - * we can check if we allocated blocks over a hole first. - */ - if (mapping->nrpages) { - ret = invalidate_inode_pages2_range(mapping, - pos >> PAGE_SHIFT, - (pos + iov_iter_count(iter) - 1) >> PAGE_SHIFT); - WARN_ON_ONCE(ret); - } - while (iov_iter_count(iter)) { ret = iomap_apply(inode, pos, iov_iter_count(iter), flags, ops, iter, iomap_dax_actor);
Patches currently in stable-queue which might be from jack@suse.cz are
queue-4.9/mm-avoid-returning-vm_fault_retry-from-page_mkwrite-handlers.patch queue-4.9/dax-avoid-page-invalidation-races-and-unnecessary-radix-tree-traversals.patch