Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: add unmap_mapping_pages()

Several users of unmap_mapping_range() would prefer to express their
range in pages rather than bytes. Unfortuately, on a 32-bit kernel, you
have to remember to cast your page number to a 64-bit type before
shifting it, and four places in the current tree didn't remember to do
that. That's a sign of a bad interface.

Conveniently, unmap_mapping_range() actually converts from bytes into
pages, so hoist the guts of unmap_mapping_range() into a new function
unmap_mapping_pages() and convert the callers which want to use pages.

Link: http://lkml.kernel.org/r/20171206142627.GD32044@bombadil.infradead.org
Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
Reported-by: "zhangyi (F)" <yi.zhang@huawei.com>
Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Matthew Wilcox and committed by
Linus Torvalds
977fbdcd a365ac09

+61 -60
+6 -13
fs/dax.c
··· 44 44 45 45 /* The 'colour' (ie low bits) within a PMD of a page offset. */ 46 46 #define PG_PMD_COLOUR ((PMD_SIZE >> PAGE_SHIFT) - 1) 47 + #define PG_PMD_NR (PMD_SIZE >> PAGE_SHIFT) 47 48 48 49 static wait_queue_head_t wait_table[DAX_WAIT_TABLE_ENTRIES]; 49 50 ··· 376 375 * unmapped. 377 376 */ 378 377 if (pmd_downgrade && dax_is_zero_entry(entry)) 379 - unmap_mapping_range(mapping, 380 - (index << PAGE_SHIFT) & PMD_MASK, PMD_SIZE, 0); 378 + unmap_mapping_pages(mapping, index & ~PG_PMD_COLOUR, 379 + PG_PMD_NR, false); 381 380 382 381 err = radix_tree_preload( 383 382 mapping_gfp_mask(mapping) & ~__GFP_HIGHMEM); ··· 539 538 if (dax_is_zero_entry(entry) && !(flags & RADIX_DAX_ZERO_PAGE)) { 540 539 /* we are replacing a zero page with block mapping */ 541 540 if (dax_is_pmd_entry(entry)) 542 - unmap_mapping_range(mapping, 543 - (vmf->pgoff << PAGE_SHIFT) & PMD_MASK, 544 - PMD_SIZE, 0); 541 + unmap_mapping_pages(mapping, index & ~PG_PMD_COLOUR, 542 + PG_PMD_NR, false); 545 543 else /* pte entry */ 546 - unmap_mapping_range(mapping, vmf->pgoff << PAGE_SHIFT, 547 - PAGE_SIZE, 0); 544 + unmap_mapping_pages(mapping, vmf->pgoff, 1, false); 548 545 } 549 546 550 547 spin_lock_irq(&mapping->tree_lock); ··· 1268 1269 } 1269 1270 1270 1271 #ifdef CONFIG_FS_DAX_PMD 1271 - /* 1272 - * The 'colour' (ie low bits) within a PMD of a page offset. This comes up 1273 - * more often than one might expect in the below functions. 1274 - */ 1275 - #define PG_PMD_COLOUR ((PMD_SIZE >> PAGE_SHIFT) - 1) 1276 - 1277 1272 static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap, 1278 1273 void *entry) 1279 1274 {
+16 -10
include/linux/mm.h
··· 1312 1312 unsigned long end, unsigned long floor, unsigned long ceiling); 1313 1313 int copy_page_range(struct mm_struct *dst, struct mm_struct *src, 1314 1314 struct vm_area_struct *vma); 1315 - void unmap_mapping_range(struct address_space *mapping, 1316 - loff_t const holebegin, loff_t const holelen, int even_cows); 1317 1315 int follow_pte_pmd(struct mm_struct *mm, unsigned long address, 1318 1316 unsigned long *start, unsigned long *end, 1319 1317 pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp); ··· 1321 1323 unsigned int flags, unsigned long *prot, resource_size_t *phys); 1322 1324 int generic_access_phys(struct vm_area_struct *vma, unsigned long addr, 1323 1325 void *buf, int len, int write); 1324 - 1325 - static inline void unmap_shared_mapping_range(struct address_space *mapping, 1326 - loff_t const holebegin, loff_t const holelen) 1327 - { 1328 - unmap_mapping_range(mapping, holebegin, holelen, 0); 1329 - } 1330 1326 1331 1327 extern void truncate_pagecache(struct inode *inode, loff_t new); 1332 1328 extern void truncate_setsize(struct inode *inode, loff_t newsize); ··· 1336 1344 extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, 1337 1345 unsigned long address, unsigned int fault_flags, 1338 1346 bool *unlocked); 1347 + void unmap_mapping_pages(struct address_space *mapping, 1348 + pgoff_t start, pgoff_t nr, bool even_cows); 1349 + void unmap_mapping_range(struct address_space *mapping, 1350 + loff_t const holebegin, loff_t const holelen, int even_cows); 1339 1351 #else 1340 1352 static inline int handle_mm_fault(struct vm_area_struct *vma, 1341 1353 unsigned long address, unsigned int flags) ··· 1356 1360 BUG(); 1357 1361 return -EFAULT; 1358 1362 } 1363 + static inline void unmap_mapping_pages(struct address_space *mapping, 1364 + pgoff_t start, pgoff_t nr, bool even_cows) { } 1365 + static inline void unmap_mapping_range(struct address_space *mapping, 1366 + loff_t const holebegin, loff_t const holelen, int even_cows) { } 1359 1367 #endif 1360 1368 1361 - extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, 1362 - unsigned int gup_flags); 1369 + static inline void unmap_shared_mapping_range(struct address_space *mapping, 1370 + loff_t const holebegin, loff_t const holelen) 1371 + { 1372 + unmap_mapping_range(mapping, holebegin, holelen, 0); 1373 + } 1374 + 1375 + extern int access_process_vm(struct task_struct *tsk, unsigned long addr, 1376 + void *buf, int len, unsigned int gup_flags); 1363 1377 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, 1364 1378 void *buf, int len, unsigned int gup_flags); 1365 1379 extern int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+1 -2
mm/khugepaged.c
··· 1399 1399 } 1400 1400 1401 1401 if (page_mapped(page)) 1402 - unmap_mapping_range(mapping, index << PAGE_SHIFT, 1403 - PAGE_SIZE, 0); 1402 + unmap_mapping_pages(mapping, index, 1, false); 1404 1403 1405 1404 spin_lock_irq(&mapping->tree_lock); 1406 1405
+31 -12
mm/memory.c
··· 2799 2799 } 2800 2800 2801 2801 /** 2802 + * unmap_mapping_pages() - Unmap pages from processes. 2803 + * @mapping: The address space containing pages to be unmapped. 2804 + * @start: Index of first page to be unmapped. 2805 + * @nr: Number of pages to be unmapped. 0 to unmap to end of file. 2806 + * @even_cows: Whether to unmap even private COWed pages. 2807 + * 2808 + * Unmap the pages in this address space from any userspace process which 2809 + * has them mmaped. Generally, you want to remove COWed pages as well when 2810 + * a file is being truncated, but not when invalidating pages from the page 2811 + * cache. 2812 + */ 2813 + void unmap_mapping_pages(struct address_space *mapping, pgoff_t start, 2814 + pgoff_t nr, bool even_cows) 2815 + { 2816 + struct zap_details details = { }; 2817 + 2818 + details.check_mapping = even_cows ? NULL : mapping; 2819 + details.first_index = start; 2820 + details.last_index = start + nr - 1; 2821 + if (details.last_index < details.first_index) 2822 + details.last_index = ULONG_MAX; 2823 + 2824 + i_mmap_lock_write(mapping); 2825 + if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root))) 2826 + unmap_mapping_range_tree(&mapping->i_mmap, &details); 2827 + i_mmap_unlock_write(mapping); 2828 + } 2829 + 2830 + /** 2802 2831 * unmap_mapping_range - unmap the portion of all mmaps in the specified 2803 - * address_space corresponding to the specified page range in the underlying 2832 + * address_space corresponding to the specified byte range in the underlying 2804 2833 * file. 2805 2834 * 2806 2835 * @mapping: the address space containing mmaps to be unmapped. ··· 2847 2818 void unmap_mapping_range(struct address_space *mapping, 2848 2819 loff_t const holebegin, loff_t const holelen, int even_cows) 2849 2820 { 2850 - struct zap_details details = { }; 2851 2821 pgoff_t hba = holebegin >> PAGE_SHIFT; 2852 2822 pgoff_t hlen = (holelen + PAGE_SIZE - 1) >> PAGE_SHIFT; 2853 2823 ··· 2858 2830 hlen = ULONG_MAX - hba + 1; 2859 2831 } 2860 2832 2861 - details.check_mapping = even_cows ? NULL : mapping; 2862 - details.first_index = hba; 2863 - details.last_index = hba + hlen - 1; 2864 - if (details.last_index < details.first_index) 2865 - details.last_index = ULONG_MAX; 2866 - 2867 - i_mmap_lock_write(mapping); 2868 - if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root))) 2869 - unmap_mapping_range_tree(&mapping->i_mmap, &details); 2870 - i_mmap_unlock_write(mapping); 2833 + unmap_mapping_pages(mapping, hba, hlen, even_cows); 2871 2834 } 2872 2835 EXPORT_SYMBOL(unmap_mapping_range); 2873 2836
-7
mm/nommu.c
··· 1788 1788 return -ENOMEM; 1789 1789 } 1790 1790 1791 - void unmap_mapping_range(struct address_space *mapping, 1792 - loff_t const holebegin, loff_t const holelen, 1793 - int even_cows) 1794 - { 1795 - } 1796 - EXPORT_SYMBOL(unmap_mapping_range); 1797 - 1798 1791 int filemap_fault(struct vm_fault *vmf) 1799 1792 { 1800 1793 BUG();
+7 -16
mm/truncate.c
··· 179 179 truncate_cleanup_page(struct address_space *mapping, struct page *page) 180 180 { 181 181 if (page_mapped(page)) { 182 - loff_t holelen; 183 - 184 - holelen = PageTransHuge(page) ? HPAGE_PMD_SIZE : PAGE_SIZE; 185 - unmap_mapping_range(mapping, 186 - (loff_t)page->index << PAGE_SHIFT, 187 - holelen, 0); 182 + pgoff_t nr = PageTransHuge(page) ? HPAGE_PMD_NR : 1; 183 + unmap_mapping_pages(mapping, page->index, nr, false); 188 184 } 189 185 190 186 if (page_has_private(page)) ··· 711 715 /* 712 716 * Zap the rest of the file in one hit. 713 717 */ 714 - unmap_mapping_range(mapping, 715 - (loff_t)index << PAGE_SHIFT, 716 - (loff_t)(1 + end - index) 717 - << PAGE_SHIFT, 718 - 0); 718 + unmap_mapping_pages(mapping, index, 719 + (1 + end - index), false); 719 720 did_range_unmap = 1; 720 721 } else { 721 722 /* 722 723 * Just zap this page 723 724 */ 724 - unmap_mapping_range(mapping, 725 - (loff_t)index << PAGE_SHIFT, 726 - PAGE_SIZE, 0); 725 + unmap_mapping_pages(mapping, index, 726 + 1, false); 727 727 } 728 728 } 729 729 BUG_ON(page_mapped(page)); ··· 745 753 * get remapped later. 746 754 */ 747 755 if (dax_mapping(mapping)) { 748 - unmap_mapping_range(mapping, (loff_t)start << PAGE_SHIFT, 749 - (loff_t)(end - start + 1) << PAGE_SHIFT, 0); 756 + unmap_mapping_pages(mapping, start, end - start + 1, false); 750 757 } 751 758 out: 752 759 cleancache_invalidate_inode(mapping);