aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dax.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2018-03-09 20:44:31 -0500
committerDan Williams <dan.j.williams@intel.com>2018-05-22 10:19:08 -0400
commit5fac7408d828719db6d3fdba63e3c3726a6d1ee5 (patch)
tree46d0b7891fa01a63292d9a2dd58012830160694d /fs/dax.c
parenta9b6de77b1a3ff729f7bfc54b2e17711776a416c (diff)
mm, fs, dax: handle layout changes to pinned dax mappings
Background: get_user_pages() in the filesystem pins file backed memory pages for access by devices performing dma. However, it only pins the memory pages not the page-to-file offset association. If a file is truncated the pages are mapped out of the file and dma may continue indefinitely into a page that is owned by a device driver. This breaks coherency of the file vs dma, but the assumption is that if userspace wants the file-space truncated it does not matter what data is inbound from the device, it is not relevant anymore. The only expectation is that dma can safely continue while the filesystem reallocates the block(s). Problem: This expectation that dma can safely continue while the filesystem changes the block map is broken by dax. With dax the target dma page *is* the filesystem block. The model of leaving the page pinned for dma, but truncating the file block out of the file, means that the filesytem is free to reallocate a block under active dma to another file and now the expected data-incoherency situation has turned into active data-corruption. Solution: Defer all filesystem operations (fallocate(), truncate()) on a dax mode file while any page/block in the file is under active dma. This solution assumes that dma is transient. Cases where dma operations are known to not be transient, like RDMA, have been explicitly disabled via commits like 5f1d43de5416 "IB/core: disable memory registration of filesystem-dax vmas". The dax_layout_busy_page() routine is called by filesystems with a lock held against mm faults (i_mmap_lock) to find pinned / busy dax pages. The process of looking up a busy page invalidates all mappings to trigger any subsequent get_user_pages() to block on i_mmap_lock. The filesystem continues to call dax_layout_busy_page() until it finally returns no more active pages. This approach assumes that the page pinning is transient, if that assumption is violated the system would have likely hung from the uncompleted I/O. Cc: Jeff Moyer <jmoyer@redhat.com> Cc: Dave Chinner <david@fromorbit.com> Cc: Matthew Wilcox <mawilcox@microsoft.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: "Darrick J. Wong" <darrick.wong@oracle.com> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Reported-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'fs/dax.c')
-rw-r--r--fs/dax.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/fs/dax.c b/fs/dax.c
index aaec72ded1b6..e8f61ea690f7 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -351,6 +351,19 @@ static void dax_disassociate_entry(void *entry, struct address_space *mapping,
351 } 351 }
352} 352}
353 353
354static struct page *dax_busy_page(void *entry)
355{
356 unsigned long pfn;
357
358 for_each_mapped_pfn(entry, pfn) {
359 struct page *page = pfn_to_page(pfn);
360
361 if (page_ref_count(page) > 1)
362 return page;
363 }
364 return NULL;
365}
366
354/* 367/*
355 * Find radix tree entry at given index. If it points to an exceptional entry, 368 * Find radix tree entry at given index. If it points to an exceptional entry,
356 * return it with the radix tree entry locked. If the radix tree doesn't 369 * return it with the radix tree entry locked. If the radix tree doesn't
@@ -492,6 +505,90 @@ restart:
492 return entry; 505 return entry;
493} 506}
494 507
508/**
509 * dax_layout_busy_page - find first pinned page in @mapping
510 * @mapping: address space to scan for a page with ref count > 1
511 *
512 * DAX requires ZONE_DEVICE mapped pages. These pages are never
513 * 'onlined' to the page allocator so they are considered idle when
514 * page->count == 1. A filesystem uses this interface to determine if
515 * any page in the mapping is busy, i.e. for DMA, or other
516 * get_user_pages() usages.
517 *
518 * It is expected that the filesystem is holding locks to block the
519 * establishment of new mappings in this address_space. I.e. it expects
520 * to be able to run unmap_mapping_range() and subsequently not race
521 * mapping_mapped() becoming true.
522 */
523struct page *dax_layout_busy_page(struct address_space *mapping)
524{
525 pgoff_t indices[PAGEVEC_SIZE];
526 struct page *page = NULL;
527 struct pagevec pvec;
528 pgoff_t index, end;
529 unsigned i;
530
531 /*
532 * In the 'limited' case get_user_pages() for dax is disabled.
533 */
534 if (IS_ENABLED(CONFIG_FS_DAX_LIMITED))
535 return NULL;
536
537 if (!dax_mapping(mapping) || !mapping_mapped(mapping))
538 return NULL;
539
540 pagevec_init(&pvec);
541 index = 0;
542 end = -1;
543
544 /*
545 * If we race get_user_pages_fast() here either we'll see the
546 * elevated page count in the pagevec_lookup and wait, or
547 * get_user_pages_fast() will see that the page it took a reference
548 * against is no longer mapped in the page tables and bail to the
549 * get_user_pages() slow path. The slow path is protected by
550 * pte_lock() and pmd_lock(). New references are not taken without
551 * holding those locks, and unmap_mapping_range() will not zero the
552 * pte or pmd without holding the respective lock, so we are
553 * guaranteed to either see new references or prevent new
554 * references from being established.
555 */
556 unmap_mapping_range(mapping, 0, 0, 1);
557
558 while (index < end && pagevec_lookup_entries(&pvec, mapping, index,
559 min(end - index, (pgoff_t)PAGEVEC_SIZE),
560 indices)) {
561 for (i = 0; i < pagevec_count(&pvec); i++) {
562 struct page *pvec_ent = pvec.pages[i];
563 void *entry;
564
565 index = indices[i];
566 if (index >= end)
567 break;
568
569 if (!radix_tree_exceptional_entry(pvec_ent))
570 continue;
571
572 xa_lock_irq(&mapping->i_pages);
573 entry = get_unlocked_mapping_entry(mapping, index, NULL);
574 if (entry)
575 page = dax_busy_page(entry);
576 put_unlocked_mapping_entry(mapping, index, entry);
577 xa_unlock_irq(&mapping->i_pages);
578 if (page)
579 break;
580 }
581 pagevec_remove_exceptionals(&pvec);
582 pagevec_release(&pvec);
583 index++;
584
585 if (page)
586 break;
587 }
588 return page;
589}
590EXPORT_SYMBOL_GPL(dax_layout_busy_page);
591
495static int __dax_invalidate_mapping_entry(struct address_space *mapping, 592static int __dax_invalidate_mapping_entry(struct address_space *mapping,
496 pgoff_t index, bool trunc) 593 pgoff_t index, bool trunc)
497{ 594{