diff for duplicates of <20140725194450.GJ6754@linux.intel.com> diff --git a/a/2.txt b/N1/2.txt index 496abdc..8b13789 100644 --- a/a/2.txt +++ b/N1/2.txt @@ -1,27 +1 @@ ->From 9f68c0a856b86dbd109be3b95427cd69bec8330d Mon Sep 17 00:00:00 2001 -From: Matthew Wilcox <willy@linux.intel.com> -Date: Fri, 25 Jul 2014 09:43:15 -0400 -Subject: [PATCH 1/4] dax: Only unlock the i_mmap_mutex if we locked it -The second time we faulted on a hole, we would try to unlock the -i_mmap_mutex, even though we weren't holding it. Oops. ---- - fs/dax.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/fs/dax.c b/fs/dax.c -index 39b95b1..a65a0f9 100644 ---- a/fs/dax.c -+++ b/fs/dax.c -@@ -341,7 +341,8 @@ static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, - if (error || bh.b_size < PAGE_SIZE) - goto sigbus; - } else { -- mutex_unlock(&mapping->i_mmap_mutex); -+ if (!page) -+ mutex_unlock(&mapping->i_mmap_mutex); - return dax_load_hole(mapping, page, vmf); - } - } --- -2.0.1 diff --git a/a/3.hdr b/a/3.hdr deleted file mode 100644 index a72eab5..0000000 --- a/a/3.hdr +++ /dev/null @@ -1,2 +0,0 @@ -Content-Type: text/x-diff; charset=us-ascii -Content-Disposition: attachment; filename="0002-dax-Call-delete_from_page_cache-after-unmap_mapping_.patch" diff --git a/a/3.txt b/a/3.txt deleted file mode 100644 index 0cca522..0000000 --- a/a/3.txt +++ /dev/null @@ -1,30 +0,0 @@ ->From 4c68125c7557a2a61ba83167ee6a9ff44fdeee89 Mon Sep 17 00:00:00 2001 -From: Matthew Wilcox <willy@linux.intel.com> -Date: Fri, 25 Jul 2014 09:44:32 -0400 -Subject: [PATCH 2/4] dax: Call delete_from_page_cache() after - unmap_mapping_range() - -delete_from_page_cache() checks that the page is already unmapped -from everywhere, so we should unmap it from everywhere before we -delete it. This matches the call sequence in mm/truncate.c. ---- - fs/dax.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/fs/dax.c b/fs/dax.c -index a65a0f9..b4fdfd9 100644 ---- a/fs/dax.c -+++ b/fs/dax.c -@@ -383,9 +383,9 @@ static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, - } - - if (page) { -- delete_from_page_cache(page); - unmap_mapping_range(mapping, vmf->pgoff << PAGE_SHIFT, - PAGE_CACHE_SIZE, 0); -+ delete_from_page_cache(page); - unlock_page(page); - page_cache_release(page); - } --- -2.0.1 diff --git a/a/4.hdr b/a/4.hdr deleted file mode 100644 index eb110de..0000000 --- a/a/4.hdr +++ /dev/null @@ -1,2 +0,0 @@ -Content-Type: text/x-diff; charset=us-ascii -Content-Disposition: attachment; filename="0003-Factor-zap_pte-out-of-zap_pte_range.patch" diff --git a/a/4.txt b/a/4.txt deleted file mode 100644 index 2b3a174..0000000 --- a/a/4.txt +++ /dev/null @@ -1,223 +0,0 @@ ->From 60a90d68474bca2afc7e93517169769f4e028962 Mon Sep 17 00:00:00 2001 -From: Matthew Wilcox <willy@linux.intel.com> -Date: Fri, 25 Jul 2014 09:46:01 -0400 -Subject: [PATCH 3/4] Factor zap_pte() out of zap_pte_range() - -zap_pte() can be called while holding the PTE lock, which is important for -a follow-on patch. This patch should *only* move code into a separate -function; other changes to make zap_pte() usable are in subsequent -patches. ---- - mm/memory.c | 190 ++++++++++++++++++++++++++++++++---------------------------- - 1 file changed, 101 insertions(+), 89 deletions(-) - -diff --git a/mm/memory.c b/mm/memory.c -index cf06c97..6a35f98 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -1071,6 +1071,105 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, - return ret; - } - -+/* Returns true to break out of the loop */ -+static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma, -+ pte_t *pte, unsigned long addr, -+ struct zap_details *details, int *rss, -+ int *force_flush) -+{ -+ struct mm_struct *mm = tlb->mm; -+ pte_t ptent = *pte; -+ -+ if (pte_none(ptent)) -+ return false; -+ -+ if (pte_present(ptent)) { -+ struct page *page; -+ -+ page = vm_normal_page(vma, addr, ptent); -+ if (unlikely(details) && page) { -+ /* -+ * unmap_shared_mapping_pages() wants to -+ * invalidate cache without truncating: -+ * unmap shared but keep private pages. -+ */ -+ if (details->check_mapping && -+ details->check_mapping != page->mapping) -+ return false; -+ /* -+ * Each page->index must be checked when -+ * invalidating or truncating nonlinear. -+ */ -+ if (details->nonlinear_vma && -+ (page->index < details->first_index || -+ page->index > details->last_index)) -+ return false; -+ } -+ ptent = ptep_get_and_clear_full(mm, addr, pte, -+ tlb->fullmm); -+ tlb_remove_tlb_entry(tlb, pte, addr); -+ if (unlikely(!page)) -+ return false; -+ if (unlikely(details) && details->nonlinear_vma -+ && linear_page_index(details->nonlinear_vma, -+ addr) != page->index) { -+ pte_t ptfile = pgoff_to_pte(page->index); -+ if (pte_soft_dirty(ptent)) -+ pte_file_mksoft_dirty(ptfile); -+ set_pte_at(mm, addr, pte, ptfile); -+ } -+ if (PageAnon(page)) -+ rss[MM_ANONPAGES]--; -+ else { -+ if (pte_dirty(ptent)) { -+ *force_flush = 1; -+ set_page_dirty(page); -+ } -+ if (pte_young(ptent) && -+ likely(!(vma->vm_flags & VM_SEQ_READ))) -+ mark_page_accessed(page); -+ rss[MM_FILEPAGES]--; -+ } -+ page_remove_rmap(page); -+ if (unlikely(page_mapcount(page) < 0)) -+ print_bad_pte(vma, addr, ptent, page); -+ if (unlikely(!__tlb_remove_page(tlb, page))) { -+ *force_flush = 1; -+ return true; -+ } -+ return false; -+ } -+ /* -+ * If details->check_mapping, we leave swap entries; -+ * if details->nonlinear_vma, we leave file entries. -+ */ -+ if (unlikely(details)) -+ return false; -+ if (pte_file(ptent)) { -+ if (unlikely(!(vma->vm_flags & VM_NONLINEAR))) -+ print_bad_pte(vma, addr, ptent, NULL); -+ } else { -+ swp_entry_t entry = pte_to_swp_entry(ptent); -+ -+ if (!non_swap_entry(entry)) -+ rss[MM_SWAPENTS]--; -+ else if (is_migration_entry(entry)) { -+ struct page *page; -+ -+ page = migration_entry_to_page(entry); -+ -+ if (PageAnon(page)) -+ rss[MM_ANONPAGES]--; -+ else -+ rss[MM_FILEPAGES]--; -+ } -+ if (unlikely(!free_swap_and_cache(entry))) -+ print_bad_pte(vma, addr, ptent, NULL); -+ } -+ pte_clear_not_present_full(mm, addr, pte, tlb->fullmm); -+ return false; -+} -+ - static unsigned long zap_pte_range(struct mmu_gather *tlb, - struct vm_area_struct *vma, pmd_t *pmd, - unsigned long addr, unsigned long end, -@@ -1089,95 +1188,8 @@ again: - pte = start_pte; - arch_enter_lazy_mmu_mode(); - do { -- pte_t ptent = *pte; -- if (pte_none(ptent)) { -- continue; -- } -- -- if (pte_present(ptent)) { -- struct page *page; -- -- page = vm_normal_page(vma, addr, ptent); -- if (unlikely(details) && page) { -- /* -- * unmap_shared_mapping_pages() wants to -- * invalidate cache without truncating: -- * unmap shared but keep private pages. -- */ -- if (details->check_mapping && -- details->check_mapping != page->mapping) -- continue; -- /* -- * Each page->index must be checked when -- * invalidating or truncating nonlinear. -- */ -- if (details->nonlinear_vma && -- (page->index < details->first_index || -- page->index > details->last_index)) -- continue; -- } -- ptent = ptep_get_and_clear_full(mm, addr, pte, -- tlb->fullmm); -- tlb_remove_tlb_entry(tlb, pte, addr); -- if (unlikely(!page)) -- continue; -- if (unlikely(details) && details->nonlinear_vma -- && linear_page_index(details->nonlinear_vma, -- addr) != page->index) { -- pte_t ptfile = pgoff_to_pte(page->index); -- if (pte_soft_dirty(ptent)) -- pte_file_mksoft_dirty(ptfile); -- set_pte_at(mm, addr, pte, ptfile); -- } -- if (PageAnon(page)) -- rss[MM_ANONPAGES]--; -- else { -- if (pte_dirty(ptent)) { -- force_flush = 1; -- set_page_dirty(page); -- } -- if (pte_young(ptent) && -- likely(!(vma->vm_flags & VM_SEQ_READ))) -- mark_page_accessed(page); -- rss[MM_FILEPAGES]--; -- } -- page_remove_rmap(page); -- if (unlikely(page_mapcount(page) < 0)) -- print_bad_pte(vma, addr, ptent, page); -- if (unlikely(!__tlb_remove_page(tlb, page))) { -- force_flush = 1; -- break; -- } -- continue; -- } -- /* -- * If details->check_mapping, we leave swap entries; -- * if details->nonlinear_vma, we leave file entries. -- */ -- if (unlikely(details)) -- continue; -- if (pte_file(ptent)) { -- if (unlikely(!(vma->vm_flags & VM_NONLINEAR))) -- print_bad_pte(vma, addr, ptent, NULL); -- } else { -- swp_entry_t entry = pte_to_swp_entry(ptent); -- -- if (!non_swap_entry(entry)) -- rss[MM_SWAPENTS]--; -- else if (is_migration_entry(entry)) { -- struct page *page; -- -- page = migration_entry_to_page(entry); -- -- if (PageAnon(page)) -- rss[MM_ANONPAGES]--; -- else -- rss[MM_FILEPAGES]--; -- } -- if (unlikely(!free_swap_and_cache(entry))) -- print_bad_pte(vma, addr, ptent, NULL); -- } -- pte_clear_not_present_full(mm, addr, pte, tlb->fullmm); -+ if (zap_pte(tlb, vma, pte, addr, details, rss, &force_flush)) -+ break; - } while (pte++, addr += PAGE_SIZE, addr != end); - - add_mm_rss_vec(mm, rss); --- -2.0.1 diff --git a/a/5.hdr b/a/5.hdr deleted file mode 100644 index 6731b47..0000000 --- a/a/5.hdr +++ /dev/null @@ -1,2 +0,0 @@ -Content-Type: text/x-diff; charset=us-ascii -Content-Disposition: attachment; filename="0004-mm-Introduce-zap_pte_single.patch" diff --git a/a/5.txt b/a/5.txt deleted file mode 100644 index 901ee29..0000000 --- a/a/5.txt +++ /dev/null @@ -1,134 +0,0 @@ ->From 50c81e697f68aba7362dbf77b9017f8bba666e17 Mon Sep 17 00:00:00 2001 -From: Matthew Wilcox <willy@linux.intel.com> -Date: Fri, 25 Jul 2014 15:10:12 -0400 -Subject: [PATCH 4/4] mm: Introduce zap_pte_single() - -zap_pte_single() is a new wrapper around zap_pte() that does all the -necessary setup for insert_pte() and insert_page(). ---- - mm/memory.c | 44 ++++++++++++++++++++++++++++++++++---------- - 1 file changed, 34 insertions(+), 10 deletions(-) - -diff --git a/mm/memory.c b/mm/memory.c -index 6a35f98..a8e17ce 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -1077,7 +1077,8 @@ static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma, - struct zap_details *details, int *rss, - int *force_flush) - { -- struct mm_struct *mm = tlb->mm; -+ struct mm_struct *mm = tlb ? tlb->mm : vma->vm_mm; -+ bool fullmm = tlb ? tlb->fullmm : false; - pte_t ptent = *pte; - - if (pte_none(ptent)) -@@ -1105,9 +1106,9 @@ static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma, - page->index > details->last_index)) - return false; - } -- ptent = ptep_get_and_clear_full(mm, addr, pte, -- tlb->fullmm); -- tlb_remove_tlb_entry(tlb, pte, addr); -+ ptent = ptep_get_and_clear_full(mm, addr, pte, fullmm); -+ if (tlb) -+ tlb_remove_tlb_entry(tlb, pte, addr); - if (unlikely(!page)) - return false; - if (unlikely(details) && details->nonlinear_vma -@@ -1133,7 +1134,7 @@ static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma, - page_remove_rmap(page); - if (unlikely(page_mapcount(page) < 0)) - print_bad_pte(vma, addr, ptent, page); -- if (unlikely(!__tlb_remove_page(tlb, page))) { -+ if (unlikely(tlb && !__tlb_remove_page(tlb, page))) { - *force_flush = 1; - return true; - } -@@ -1166,10 +1167,27 @@ static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma, - if (unlikely(!free_swap_and_cache(entry))) - print_bad_pte(vma, addr, ptent, NULL); - } -- pte_clear_not_present_full(mm, addr, pte, tlb->fullmm); -+ pte_clear_not_present_full(mm, addr, pte, fullmm); - return false; - } - -+static void zap_pte_single(struct vm_area_struct *vma, pte_t *pte, -+ unsigned long addr) -+{ -+ struct mm_struct *mm = vma->vm_mm; -+ int force_flush = 0; -+ int rss[NR_MM_COUNTERS]; -+ -+ VM_BUG_ON(!mutex_is_locked(&vma->vm_file->f_mapping->i_mmap_mutex)); -+ -+ init_rss_vec(rss); -+ update_hiwater_rss(mm); -+ flush_cache_page(vma, addr, pte_pfn(*pte)); -+ zap_pte(NULL, vma, pte, addr, NULL, rss, &force_flush); -+ flush_tlb_page(vma, addr); -+ add_mm_rss_vec(mm, rss); -+} -+ - static unsigned long zap_pte_range(struct mmu_gather *tlb, - struct vm_area_struct *vma, pmd_t *pmd, - unsigned long addr, unsigned long end, -@@ -1494,6 +1512,7 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr, - int retval; - pte_t *pte; - spinlock_t *ptl; -+ bool replaced = false; - - retval = -EINVAL; - if (PageAnon(page)) -@@ -1507,8 +1526,8 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr, - if (!pte_none(*pte)) { - if (!replace) - goto out_unlock; -- VM_BUG_ON(!mutex_is_locked(&vma->vm_file->f_mapping->i_mmap_mutex)); -- zap_page_range_single(vma, addr, PAGE_SIZE, NULL); -+ zap_pte_single(vma, pte, addr); -+ replaced = true; - } - - /* Ok, finally just insert the thing.. */ -@@ -1519,6 +1538,8 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr, - - retval = 0; - pte_unmap_unlock(pte, ptl); -+ if (replaced) -+ mmu_notifier_invalidate_page(mm, addr); - return retval; - out_unlock: - pte_unmap_unlock(pte, ptl); -@@ -1576,6 +1597,7 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr, - int retval; - pte_t *pte, entry; - spinlock_t *ptl; -+ bool replaced = false; - - retval = -ENOMEM; - pte = get_locked_pte(mm, addr, &ptl); -@@ -1585,8 +1607,8 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr, - if (!pte_none(*pte)) { - if (!replace) - goto out_unlock; -- VM_BUG_ON(!mutex_is_locked(&vma->vm_file->f_mapping->i_mmap_mutex)); -- zap_page_range_single(vma, addr, PAGE_SIZE, NULL); -+ zap_pte_single(vma, pte, addr); -+ replaced = true; - } - - /* Ok, finally just insert the thing.. */ -@@ -1597,6 +1619,8 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr, - retval = 0; - out_unlock: - pte_unmap_unlock(pte, ptl); -+ if (replaced) -+ mmu_notifier_invalidate_page(mm, addr); - out: - return retval; - } --- -2.0.1 diff --git a/a/6.hdr b/a/6.hdr deleted file mode 100644 index c0a4e27..0000000 --- a/a/6.hdr +++ /dev/null @@ -1,2 +0,0 @@ -Content-Type: text/x-csrc; charset=us-ascii -Content-Disposition: attachment; filename="double-map.c" diff --git a/a/6.txt b/a/6.txt deleted file mode 100644 index 2bdfab1..0000000 --- a/a/6.txt +++ /dev/null @@ -1,63 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> - -int -main(int argc, char *argv[]) -{ - int fd; - void *addr, *addr2; - char buf[4096]; - - if (argc != 2) { - fprintf(stderr, "usage: %s filename\n", argv[0]); - exit(1); - } - - if ((fd = open(argv[1], O_CREAT|O_RDWR, 0666)) < 0) { - perror(argv[1]); - exit(1); - } - - if (ftruncate(fd, 4096) < 0) { - perror("ftruncate"); - exit(1); - } - - if ((addr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, - fd, 0)) == MAP_FAILED) { - perror("mmap"); - exit(1); - } - - if ((addr2 = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, - fd, 0)) == MAP_FAILED) { - perror("mmap"); - exit(1); - } - -printf("addr = %p addr2 = %p\n", addr, addr2); - - close(fd); - - /* first read */ - memcpy(buf, addr, 2048); - -getc(stdin); - - /* second read */ - memcpy(buf + 2048, addr2, 2048); - -getc(stdin); - - /* now write a bit */ - memcpy(addr, buf, 8); - - printf("%s: test passed.\n", argv[0]); - exit(0); -} diff --git a/a/content_digest b/N1/content_digest index adaa655..492dd51 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -134,494 +134,5 @@ "\01:2\0" "fn\00001-dax-Only-unlock-the-i_mmap_mutex-if-we-locked-it.patch\0" "b\0" - ">From 9f68c0a856b86dbd109be3b95427cd69bec8330d Mon Sep 17 00:00:00 2001\n" - "From: Matthew Wilcox <willy@linux.intel.com>\n" - "Date: Fri, 25 Jul 2014 09:43:15 -0400\n" - "Subject: [PATCH 1/4] dax: Only unlock the i_mmap_mutex if we locked it\n" - "\n" - "The second time we faulted on a hole, we would try to unlock the\n" - "i_mmap_mutex, even though we weren't holding it. Oops.\n" - "---\n" - " fs/dax.c | 3 ++-\n" - " 1 file changed, 2 insertions(+), 1 deletion(-)\n" - "\n" - "diff --git a/fs/dax.c b/fs/dax.c\n" - "index 39b95b1..a65a0f9 100644\n" - "--- a/fs/dax.c\n" - "+++ b/fs/dax.c\n" - "@@ -341,7 +341,8 @@ static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,\n" - " \t\t\tif (error || bh.b_size < PAGE_SIZE)\n" - " \t\t\t\tgoto sigbus;\n" - " \t\t} else {\n" - "-\t\t\tmutex_unlock(&mapping->i_mmap_mutex);\n" - "+\t\t\tif (!page)\n" - "+\t\t\t\tmutex_unlock(&mapping->i_mmap_mutex);\n" - " \t\t\treturn dax_load_hole(mapping, page, vmf);\n" - " \t\t}\n" - " \t}\n" - "-- \n" - 2.0.1 - "\01:3\0" - "fn\00002-dax-Call-delete_from_page_cache-after-unmap_mapping_.patch\0" - "b\0" - ">From 4c68125c7557a2a61ba83167ee6a9ff44fdeee89 Mon Sep 17 00:00:00 2001\n" - "From: Matthew Wilcox <willy@linux.intel.com>\n" - "Date: Fri, 25 Jul 2014 09:44:32 -0400\n" - "Subject: [PATCH 2/4] dax: Call delete_from_page_cache() after\n" - " unmap_mapping_range()\n" - "\n" - "delete_from_page_cache() checks that the page is already unmapped\n" - "from everywhere, so we should unmap it from everywhere before we\n" - "delete it. This matches the call sequence in mm/truncate.c.\n" - "---\n" - " fs/dax.c | 2 +-\n" - " 1 file changed, 1 insertion(+), 1 deletion(-)\n" - "\n" - "diff --git a/fs/dax.c b/fs/dax.c\n" - "index a65a0f9..b4fdfd9 100644\n" - "--- a/fs/dax.c\n" - "+++ b/fs/dax.c\n" - "@@ -383,9 +383,9 @@ static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,\n" - " \t}\n" - " \n" - " \tif (page) {\n" - "-\t\tdelete_from_page_cache(page);\n" - " \t\tunmap_mapping_range(mapping, vmf->pgoff << PAGE_SHIFT,\n" - " \t\t\t\t\t\t\tPAGE_CACHE_SIZE, 0);\n" - "+\t\tdelete_from_page_cache(page);\n" - " \t\tunlock_page(page);\n" - " \t\tpage_cache_release(page);\n" - " \t}\n" - "-- \n" - 2.0.1 - "\01:4\0" - "fn\00003-Factor-zap_pte-out-of-zap_pte_range.patch\0" - "b\0" - ">From 60a90d68474bca2afc7e93517169769f4e028962 Mon Sep 17 00:00:00 2001\n" - "From: Matthew Wilcox <willy@linux.intel.com>\n" - "Date: Fri, 25 Jul 2014 09:46:01 -0400\n" - "Subject: [PATCH 3/4] Factor zap_pte() out of zap_pte_range()\n" - "\n" - "zap_pte() can be called while holding the PTE lock, which is important for\n" - "a follow-on patch. This patch should *only* move code into a separate\n" - "function; other changes to make zap_pte() usable are in subsequent\n" - "patches.\n" - "---\n" - " mm/memory.c | 190 ++++++++++++++++++++++++++++++++----------------------------\n" - " 1 file changed, 101 insertions(+), 89 deletions(-)\n" - "\n" - "diff --git a/mm/memory.c b/mm/memory.c\n" - "index cf06c97..6a35f98 100644\n" - "--- a/mm/memory.c\n" - "+++ b/mm/memory.c\n" - "@@ -1071,6 +1071,105 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,\n" - " \treturn ret;\n" - " }\n" - " \n" - "+/* Returns true to break out of the loop */\n" - "+static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma,\n" - "+\t\t\t\tpte_t *pte, unsigned long addr,\n" - "+\t\t\t\tstruct zap_details *details, int *rss,\n" - "+\t\t\t\tint *force_flush)\n" - "+{\n" - "+\tstruct mm_struct *mm = tlb->mm;\n" - "+\tpte_t ptent = *pte;\n" - "+\n" - "+\tif (pte_none(ptent))\n" - "+\t\treturn false;\n" - "+\n" - "+\tif (pte_present(ptent)) {\n" - "+\t\tstruct page *page;\n" - "+\n" - "+\t\tpage = vm_normal_page(vma, addr, ptent);\n" - "+\t\tif (unlikely(details) && page) {\n" - "+\t\t\t/*\n" - "+\t\t\t * unmap_shared_mapping_pages() wants to\n" - "+\t\t\t * invalidate cache without truncating:\n" - "+\t\t\t * unmap shared but keep private pages.\n" - "+\t\t\t */\n" - "+\t\t\tif (details->check_mapping &&\n" - "+\t\t\t details->check_mapping != page->mapping)\n" - "+\t\t\t\treturn false;\n" - "+\t\t\t/*\n" - "+\t\t\t * Each page->index must be checked when\n" - "+\t\t\t * invalidating or truncating nonlinear.\n" - "+\t\t\t */\n" - "+\t\t\tif (details->nonlinear_vma &&\n" - "+\t\t\t (page->index < details->first_index ||\n" - "+\t\t\t page->index > details->last_index))\n" - "+\t\t\t\treturn false;\n" - "+\t\t}\n" - "+\t\tptent = ptep_get_and_clear_full(mm, addr, pte,\n" - "+\t\t\t\t\t\ttlb->fullmm);\n" - "+\t\ttlb_remove_tlb_entry(tlb, pte, addr);\n" - "+\t\tif (unlikely(!page))\n" - "+\t\t\treturn false;\n" - "+\t\tif (unlikely(details) && details->nonlinear_vma\n" - "+\t\t && linear_page_index(details->nonlinear_vma,\n" - "+\t\t\t\t\taddr) != page->index) {\n" - "+\t\t\tpte_t ptfile = pgoff_to_pte(page->index);\n" - "+\t\t\tif (pte_soft_dirty(ptent))\n" - "+\t\t\t\tpte_file_mksoft_dirty(ptfile);\n" - "+\t\t\tset_pte_at(mm, addr, pte, ptfile);\n" - "+\t\t}\n" - "+\t\tif (PageAnon(page))\n" - "+\t\t\trss[MM_ANONPAGES]--;\n" - "+\t\telse {\n" - "+\t\t\tif (pte_dirty(ptent)) {\n" - "+\t\t\t\t*force_flush = 1;\n" - "+\t\t\t\tset_page_dirty(page);\n" - "+\t\t\t}\n" - "+\t\t\tif (pte_young(ptent) &&\n" - "+\t\t\t likely(!(vma->vm_flags & VM_SEQ_READ)))\n" - "+\t\t\t\tmark_page_accessed(page);\n" - "+\t\t\trss[MM_FILEPAGES]--;\n" - "+\t\t}\n" - "+\t\tpage_remove_rmap(page);\n" - "+\t\tif (unlikely(page_mapcount(page) < 0))\n" - "+\t\t\tprint_bad_pte(vma, addr, ptent, page);\n" - "+\t\tif (unlikely(!__tlb_remove_page(tlb, page))) {\n" - "+\t\t\t*force_flush = 1;\n" - "+\t\t\treturn true;\n" - "+\t\t}\n" - "+\t\treturn false;\n" - "+\t}\n" - "+\t/*\n" - "+\t * If details->check_mapping, we leave swap entries;\n" - "+\t * if details->nonlinear_vma, we leave file entries.\n" - "+\t */\n" - "+\tif (unlikely(details))\n" - "+\t\treturn false;\n" - "+\tif (pte_file(ptent)) {\n" - "+\t\tif (unlikely(!(vma->vm_flags & VM_NONLINEAR)))\n" - "+\t\t\tprint_bad_pte(vma, addr, ptent, NULL);\n" - "+\t} else {\n" - "+\t\tswp_entry_t entry = pte_to_swp_entry(ptent);\n" - "+\n" - "+\t\tif (!non_swap_entry(entry))\n" - "+\t\t\trss[MM_SWAPENTS]--;\n" - "+\t\telse if (is_migration_entry(entry)) {\n" - "+\t\t\tstruct page *page;\n" - "+\n" - "+\t\t\tpage = migration_entry_to_page(entry);\n" - "+\n" - "+\t\t\tif (PageAnon(page))\n" - "+\t\t\t\trss[MM_ANONPAGES]--;\n" - "+\t\t\telse\n" - "+\t\t\t\trss[MM_FILEPAGES]--;\n" - "+\t\t}\n" - "+\t\tif (unlikely(!free_swap_and_cache(entry)))\n" - "+\t\t\tprint_bad_pte(vma, addr, ptent, NULL);\n" - "+\t}\n" - "+\tpte_clear_not_present_full(mm, addr, pte, tlb->fullmm);\n" - "+\treturn false;\n" - "+}\n" - "+\n" - " static unsigned long zap_pte_range(struct mmu_gather *tlb,\n" - " \t\t\t\tstruct vm_area_struct *vma, pmd_t *pmd,\n" - " \t\t\t\tunsigned long addr, unsigned long end,\n" - "@@ -1089,95 +1188,8 @@ again:\n" - " \tpte = start_pte;\n" - " \tarch_enter_lazy_mmu_mode();\n" - " \tdo {\n" - "-\t\tpte_t ptent = *pte;\n" - "-\t\tif (pte_none(ptent)) {\n" - "-\t\t\tcontinue;\n" - "-\t\t}\n" - "-\n" - "-\t\tif (pte_present(ptent)) {\n" - "-\t\t\tstruct page *page;\n" - "-\n" - "-\t\t\tpage = vm_normal_page(vma, addr, ptent);\n" - "-\t\t\tif (unlikely(details) && page) {\n" - "-\t\t\t\t/*\n" - "-\t\t\t\t * unmap_shared_mapping_pages() wants to\n" - "-\t\t\t\t * invalidate cache without truncating:\n" - "-\t\t\t\t * unmap shared but keep private pages.\n" - "-\t\t\t\t */\n" - "-\t\t\t\tif (details->check_mapping &&\n" - "-\t\t\t\t details->check_mapping != page->mapping)\n" - "-\t\t\t\t\tcontinue;\n" - "-\t\t\t\t/*\n" - "-\t\t\t\t * Each page->index must be checked when\n" - "-\t\t\t\t * invalidating or truncating nonlinear.\n" - "-\t\t\t\t */\n" - "-\t\t\t\tif (details->nonlinear_vma &&\n" - "-\t\t\t\t (page->index < details->first_index ||\n" - "-\t\t\t\t page->index > details->last_index))\n" - "-\t\t\t\t\tcontinue;\n" - "-\t\t\t}\n" - "-\t\t\tptent = ptep_get_and_clear_full(mm, addr, pte,\n" - "-\t\t\t\t\t\t\ttlb->fullmm);\n" - "-\t\t\ttlb_remove_tlb_entry(tlb, pte, addr);\n" - "-\t\t\tif (unlikely(!page))\n" - "-\t\t\t\tcontinue;\n" - "-\t\t\tif (unlikely(details) && details->nonlinear_vma\n" - "-\t\t\t && linear_page_index(details->nonlinear_vma,\n" - "-\t\t\t\t\t\taddr) != page->index) {\n" - "-\t\t\t\tpte_t ptfile = pgoff_to_pte(page->index);\n" - "-\t\t\t\tif (pte_soft_dirty(ptent))\n" - "-\t\t\t\t\tpte_file_mksoft_dirty(ptfile);\n" - "-\t\t\t\tset_pte_at(mm, addr, pte, ptfile);\n" - "-\t\t\t}\n" - "-\t\t\tif (PageAnon(page))\n" - "-\t\t\t\trss[MM_ANONPAGES]--;\n" - "-\t\t\telse {\n" - "-\t\t\t\tif (pte_dirty(ptent)) {\n" - "-\t\t\t\t\tforce_flush = 1;\n" - "-\t\t\t\t\tset_page_dirty(page);\n" - "-\t\t\t\t}\n" - "-\t\t\t\tif (pte_young(ptent) &&\n" - "-\t\t\t\t likely(!(vma->vm_flags & VM_SEQ_READ)))\n" - "-\t\t\t\t\tmark_page_accessed(page);\n" - "-\t\t\t\trss[MM_FILEPAGES]--;\n" - "-\t\t\t}\n" - "-\t\t\tpage_remove_rmap(page);\n" - "-\t\t\tif (unlikely(page_mapcount(page) < 0))\n" - "-\t\t\t\tprint_bad_pte(vma, addr, ptent, page);\n" - "-\t\t\tif (unlikely(!__tlb_remove_page(tlb, page))) {\n" - "-\t\t\t\tforce_flush = 1;\n" - "-\t\t\t\tbreak;\n" - "-\t\t\t}\n" - "-\t\t\tcontinue;\n" - "-\t\t}\n" - "-\t\t/*\n" - "-\t\t * If details->check_mapping, we leave swap entries;\n" - "-\t\t * if details->nonlinear_vma, we leave file entries.\n" - "-\t\t */\n" - "-\t\tif (unlikely(details))\n" - "-\t\t\tcontinue;\n" - "-\t\tif (pte_file(ptent)) {\n" - "-\t\t\tif (unlikely(!(vma->vm_flags & VM_NONLINEAR)))\n" - "-\t\t\t\tprint_bad_pte(vma, addr, ptent, NULL);\n" - "-\t\t} else {\n" - "-\t\t\tswp_entry_t entry = pte_to_swp_entry(ptent);\n" - "-\n" - "-\t\t\tif (!non_swap_entry(entry))\n" - "-\t\t\t\trss[MM_SWAPENTS]--;\n" - "-\t\t\telse if (is_migration_entry(entry)) {\n" - "-\t\t\t\tstruct page *page;\n" - "-\n" - "-\t\t\t\tpage = migration_entry_to_page(entry);\n" - "-\n" - "-\t\t\t\tif (PageAnon(page))\n" - "-\t\t\t\t\trss[MM_ANONPAGES]--;\n" - "-\t\t\t\telse\n" - "-\t\t\t\t\trss[MM_FILEPAGES]--;\n" - "-\t\t\t}\n" - "-\t\t\tif (unlikely(!free_swap_and_cache(entry)))\n" - "-\t\t\t\tprint_bad_pte(vma, addr, ptent, NULL);\n" - "-\t\t}\n" - "-\t\tpte_clear_not_present_full(mm, addr, pte, tlb->fullmm);\n" - "+\t\tif (zap_pte(tlb, vma, pte, addr, details, rss, &force_flush))\n" - "+\t\t\tbreak;\n" - " \t} while (pte++, addr += PAGE_SIZE, addr != end);\n" - " \n" - " \tadd_mm_rss_vec(mm, rss);\n" - "-- \n" - 2.0.1 - "\01:5\0" - "fn\00004-mm-Introduce-zap_pte_single.patch\0" - "b\0" - ">From 50c81e697f68aba7362dbf77b9017f8bba666e17 Mon Sep 17 00:00:00 2001\n" - "From: Matthew Wilcox <willy@linux.intel.com>\n" - "Date: Fri, 25 Jul 2014 15:10:12 -0400\n" - "Subject: [PATCH 4/4] mm: Introduce zap_pte_single()\n" - "\n" - "zap_pte_single() is a new wrapper around zap_pte() that does all the\n" - "necessary setup for insert_pte() and insert_page().\n" - "---\n" - " mm/memory.c | 44 ++++++++++++++++++++++++++++++++++----------\n" - " 1 file changed, 34 insertions(+), 10 deletions(-)\n" - "\n" - "diff --git a/mm/memory.c b/mm/memory.c\n" - "index 6a35f98..a8e17ce 100644\n" - "--- a/mm/memory.c\n" - "+++ b/mm/memory.c\n" - "@@ -1077,7 +1077,8 @@ static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma,\n" - " \t\t\t\tstruct zap_details *details, int *rss,\n" - " \t\t\t\tint *force_flush)\n" - " {\n" - "-\tstruct mm_struct *mm = tlb->mm;\n" - "+\tstruct mm_struct *mm = tlb ? tlb->mm : vma->vm_mm;\n" - "+\tbool fullmm = tlb ? tlb->fullmm : false;\n" - " \tpte_t ptent = *pte;\n" - " \n" - " \tif (pte_none(ptent))\n" - "@@ -1105,9 +1106,9 @@ static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma,\n" - " \t\t\t page->index > details->last_index))\n" - " \t\t\t\treturn false;\n" - " \t\t}\n" - "-\t\tptent = ptep_get_and_clear_full(mm, addr, pte,\n" - "-\t\t\t\t\t\ttlb->fullmm);\n" - "-\t\ttlb_remove_tlb_entry(tlb, pte, addr);\n" - "+\t\tptent = ptep_get_and_clear_full(mm, addr, pte, fullmm);\n" - "+\t\tif (tlb)\n" - "+\t\t\ttlb_remove_tlb_entry(tlb, pte, addr);\n" - " \t\tif (unlikely(!page))\n" - " \t\t\treturn false;\n" - " \t\tif (unlikely(details) && details->nonlinear_vma\n" - "@@ -1133,7 +1134,7 @@ static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma,\n" - " \t\tpage_remove_rmap(page);\n" - " \t\tif (unlikely(page_mapcount(page) < 0))\n" - " \t\t\tprint_bad_pte(vma, addr, ptent, page);\n" - "-\t\tif (unlikely(!__tlb_remove_page(tlb, page))) {\n" - "+\t\tif (unlikely(tlb && !__tlb_remove_page(tlb, page))) {\n" - " \t\t\t*force_flush = 1;\n" - " \t\t\treturn true;\n" - " \t\t}\n" - "@@ -1166,10 +1167,27 @@ static bool zap_pte(struct mmu_gather *tlb, struct vm_area_struct *vma,\n" - " \t\tif (unlikely(!free_swap_and_cache(entry)))\n" - " \t\t\tprint_bad_pte(vma, addr, ptent, NULL);\n" - " \t}\n" - "-\tpte_clear_not_present_full(mm, addr, pte, tlb->fullmm);\n" - "+\tpte_clear_not_present_full(mm, addr, pte, fullmm);\n" - " \treturn false;\n" - " }\n" - " \n" - "+static void zap_pte_single(struct vm_area_struct *vma, pte_t *pte,\n" - "+\t\t\t\tunsigned long addr)\n" - "+{\n" - "+\tstruct mm_struct *mm = vma->vm_mm;\n" - "+\tint force_flush = 0;\n" - "+\tint rss[NR_MM_COUNTERS];\n" - "+\n" - "+\tVM_BUG_ON(!mutex_is_locked(&vma->vm_file->f_mapping->i_mmap_mutex));\n" - "+\n" - "+\tinit_rss_vec(rss);\n" - "+\tupdate_hiwater_rss(mm);\n" - "+\tflush_cache_page(vma, addr, pte_pfn(*pte));\n" - "+\tzap_pte(NULL, vma, pte, addr, NULL, rss, &force_flush);\n" - "+\tflush_tlb_page(vma, addr);\n" - "+\tadd_mm_rss_vec(mm, rss);\n" - "+}\n" - "+\n" - " static unsigned long zap_pte_range(struct mmu_gather *tlb,\n" - " \t\t\t\tstruct vm_area_struct *vma, pmd_t *pmd,\n" - " \t\t\t\tunsigned long addr, unsigned long end,\n" - "@@ -1494,6 +1512,7 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,\n" - " \tint retval;\n" - " \tpte_t *pte;\n" - " \tspinlock_t *ptl;\n" - "+\tbool replaced = false;\n" - " \n" - " \tretval = -EINVAL;\n" - " \tif (PageAnon(page))\n" - "@@ -1507,8 +1526,8 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,\n" - " \tif (!pte_none(*pte)) {\n" - " \t\tif (!replace)\n" - " \t\t\tgoto out_unlock;\n" - "-\t\tVM_BUG_ON(!mutex_is_locked(&vma->vm_file->f_mapping->i_mmap_mutex));\n" - "-\t\tzap_page_range_single(vma, addr, PAGE_SIZE, NULL);\n" - "+\t\tzap_pte_single(vma, pte, addr);\n" - "+\t\treplaced = true;\n" - " \t}\n" - " \n" - " \t/* Ok, finally just insert the thing.. */\n" - "@@ -1519,6 +1538,8 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,\n" - " \n" - " \tretval = 0;\n" - " \tpte_unmap_unlock(pte, ptl);\n" - "+\tif (replaced)\n" - "+\t\tmmu_notifier_invalidate_page(mm, addr);\n" - " \treturn retval;\n" - " out_unlock:\n" - " \tpte_unmap_unlock(pte, ptl);\n" - "@@ -1576,6 +1597,7 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr,\n" - " \tint retval;\n" - " \tpte_t *pte, entry;\n" - " \tspinlock_t *ptl;\n" - "+\tbool replaced = false;\n" - " \n" - " \tretval = -ENOMEM;\n" - " \tpte = get_locked_pte(mm, addr, &ptl);\n" - "@@ -1585,8 +1607,8 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr,\n" - " \tif (!pte_none(*pte)) {\n" - " \t\tif (!replace)\n" - " \t\t\tgoto out_unlock;\n" - "-\t\tVM_BUG_ON(!mutex_is_locked(&vma->vm_file->f_mapping->i_mmap_mutex));\n" - "-\t\tzap_page_range_single(vma, addr, PAGE_SIZE, NULL);\n" - "+\t\tzap_pte_single(vma, pte, addr);\n" - "+\t\treplaced = true;\n" - " \t}\n" - " \n" - " \t/* Ok, finally just insert the thing.. */\n" - "@@ -1597,6 +1619,8 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr,\n" - " \tretval = 0;\n" - " out_unlock:\n" - " \tpte_unmap_unlock(pte, ptl);\n" - "+\tif (replaced)\n" - "+\t\tmmu_notifier_invalidate_page(mm, addr);\n" - " out:\n" - " \treturn retval;\n" - " }\n" - "-- \n" - 2.0.1 - "\01:6\0" - "fn\0double-map.c\0" - "b\0" - "#include <stdio.h>\n" - "#include <stdlib.h>\n" - "#include <string.h>\n" - "#include <sys/types.h>\n" - "#include <sys/mman.h>\n" - "#include <fcntl.h>\n" - "#include <unistd.h>\n" - "#include <errno.h>\n" - "\n" - "int\n" - "main(int argc, char *argv[])\n" - "{\n" - "\tint fd;\n" - "\tvoid *addr, *addr2;\n" - "\tchar buf[4096];\n" - "\n" - "\tif (argc != 2) {\n" - "\t\tfprintf(stderr, \"usage: %s filename\\n\", argv[0]);\n" - "\t\texit(1);\n" - "\t}\n" - "\n" - "\tif ((fd = open(argv[1], O_CREAT|O_RDWR, 0666)) < 0) {\n" - "\t\tperror(argv[1]);\n" - "\t\texit(1);\n" - "\t}\n" - "\n" - "\tif (ftruncate(fd, 4096) < 0) {\n" - "\t\tperror(\"ftruncate\");\n" - "\t\texit(1);\n" - "\t}\n" - "\n" - "\tif ((addr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED,\n" - "\t\t\t\t\tfd, 0)) == MAP_FAILED) {\n" - "\t\tperror(\"mmap\");\n" - "\t\texit(1);\n" - "\t}\n" - "\n" - "\tif ((addr2 = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED,\n" - "\t\t\t\t\tfd, 0)) == MAP_FAILED) {\n" - "\t\tperror(\"mmap\");\n" - "\t\texit(1);\n" - "\t}\n" - "\n" - "printf(\"addr = %p addr2 = %p\\n\", addr, addr2);\n" - "\n" - "\tclose(fd);\n" - "\n" - "\t/* first read */\n" - "\tmemcpy(buf, addr, 2048);\n" - "\n" - "getc(stdin);\n" - "\n" - "\t/* second read */\n" - "\tmemcpy(buf + 2048, addr2, 2048);\n" - "\n" - "getc(stdin);\n" - "\n" - "\t/* now write a bit */\n" - "\tmemcpy(addr, buf, 8);\n" - "\n" - "\tprintf(\"%s: test passed.\\n\", argv[0]);\n" - "\texit(0);\n" - } -5011d30ebdd66d512a569a035b094a6271230d5611f618edacce328e59332dc0 +cf4b32084a2a16a84f9405507f93a33c5cfe26e0295e5b1a341beea0457f989a
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.