diff options
-rw-r--r-- | mm/hugetlb.c | 64 | ||||
-rw-r--r-- | mm/memory-failure.c | 16 | ||||
-rw-r--r-- | mm/migrate.c | 13 | ||||
-rw-r--r-- | mm/rmap.c | 4 | ||||
-rw-r--r-- | mm/userfaultfd.c | 11 |
5 files changed, 20 insertions, 88 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index aedc1b183cf9..df2e7dd5ff17 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -3238,7 +3238,6 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, | |||
3238 | struct page *ptepage; | 3238 | struct page *ptepage; |
3239 | unsigned long addr; | 3239 | unsigned long addr; |
3240 | int cow; | 3240 | int cow; |
3241 | struct address_space *mapping = vma->vm_file->f_mapping; | ||
3242 | struct hstate *h = hstate_vma(vma); | 3241 | struct hstate *h = hstate_vma(vma); |
3243 | unsigned long sz = huge_page_size(h); | 3242 | unsigned long sz = huge_page_size(h); |
3244 | struct mmu_notifier_range range; | 3243 | struct mmu_notifier_range range; |
@@ -3250,23 +3249,13 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, | |||
3250 | mmu_notifier_range_init(&range, src, vma->vm_start, | 3249 | mmu_notifier_range_init(&range, src, vma->vm_start, |
3251 | vma->vm_end); | 3250 | vma->vm_end); |
3252 | mmu_notifier_invalidate_range_start(&range); | 3251 | mmu_notifier_invalidate_range_start(&range); |
3253 | } else { | ||
3254 | /* | ||
3255 | * For shared mappings i_mmap_rwsem must be held to call | ||
3256 | * huge_pte_alloc, otherwise the returned ptep could go | ||
3257 | * away if part of a shared pmd and another thread calls | ||
3258 | * huge_pmd_unshare. | ||
3259 | */ | ||
3260 | i_mmap_lock_read(mapping); | ||
3261 | } | 3252 | } |
3262 | 3253 | ||
3263 | for (addr = vma->vm_start; addr < vma->vm_end; addr += sz) { | 3254 | for (addr = vma->vm_start; addr < vma->vm_end; addr += sz) { |
3264 | spinlock_t *src_ptl, *dst_ptl; | 3255 | spinlock_t *src_ptl, *dst_ptl; |
3265 | |||
3266 | src_pte = huge_pte_offset(src, addr, sz); | 3256 | src_pte = huge_pte_offset(src, addr, sz); |
3267 | if (!src_pte) | 3257 | if (!src_pte) |
3268 | continue; | 3258 | continue; |
3269 | |||
3270 | dst_pte = huge_pte_alloc(dst, addr, sz); | 3259 | dst_pte = huge_pte_alloc(dst, addr, sz); |
3271 | if (!dst_pte) { | 3260 | if (!dst_pte) { |
3272 | ret = -ENOMEM; | 3261 | ret = -ENOMEM; |
@@ -3337,8 +3326,6 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, | |||
3337 | 3326 | ||
3338 | if (cow) | 3327 | if (cow) |
3339 | mmu_notifier_invalidate_range_end(&range); | 3328 | mmu_notifier_invalidate_range_end(&range); |
3340 | else | ||
3341 | i_mmap_unlock_read(mapping); | ||
3342 | 3329 | ||
3343 | return ret; | 3330 | return ret; |
3344 | } | 3331 | } |
@@ -3784,18 +3771,14 @@ retry: | |||
3784 | }; | 3771 | }; |
3785 | 3772 | ||
3786 | /* | 3773 | /* |
3787 | * hugetlb_fault_mutex and i_mmap_rwsem must be | 3774 | * hugetlb_fault_mutex must be dropped before |
3788 | * dropped before handling userfault. Reacquire | 3775 | * handling userfault. Reacquire after handling |
3789 | * after handling fault to make calling code simpler. | 3776 | * fault to make calling code simpler. |
3790 | */ | 3777 | */ |
3791 | hash = hugetlb_fault_mutex_hash(h, mm, vma, mapping, | 3778 | hash = hugetlb_fault_mutex_hash(h, mm, vma, mapping, |
3792 | idx, haddr); | 3779 | idx, haddr); |
3793 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); | 3780 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); |
3794 | i_mmap_unlock_read(mapping); | ||
3795 | |||
3796 | ret = handle_userfault(&vmf, VM_UFFD_MISSING); | 3781 | ret = handle_userfault(&vmf, VM_UFFD_MISSING); |
3797 | |||
3798 | i_mmap_lock_read(mapping); | ||
3799 | mutex_lock(&hugetlb_fault_mutex_table[hash]); | 3782 | mutex_lock(&hugetlb_fault_mutex_table[hash]); |
3800 | goto out; | 3783 | goto out; |
3801 | } | 3784 | } |
@@ -3943,11 +3926,6 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3943 | 3926 | ||
3944 | ptep = huge_pte_offset(mm, haddr, huge_page_size(h)); | 3927 | ptep = huge_pte_offset(mm, haddr, huge_page_size(h)); |
3945 | if (ptep) { | 3928 | if (ptep) { |
3946 | /* | ||
3947 | * Since we hold no locks, ptep could be stale. That is | ||
3948 | * OK as we are only making decisions based on content and | ||
3949 | * not actually modifying content here. | ||
3950 | */ | ||
3951 | entry = huge_ptep_get(ptep); | 3929 | entry = huge_ptep_get(ptep); |
3952 | if (unlikely(is_hugetlb_entry_migration(entry))) { | 3930 | if (unlikely(is_hugetlb_entry_migration(entry))) { |
3953 | migration_entry_wait_huge(vma, mm, ptep); | 3931 | migration_entry_wait_huge(vma, mm, ptep); |
@@ -3955,31 +3933,20 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3955 | } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) | 3933 | } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) |
3956 | return VM_FAULT_HWPOISON_LARGE | | 3934 | return VM_FAULT_HWPOISON_LARGE | |
3957 | VM_FAULT_SET_HINDEX(hstate_index(h)); | 3935 | VM_FAULT_SET_HINDEX(hstate_index(h)); |
3936 | } else { | ||
3937 | ptep = huge_pte_alloc(mm, haddr, huge_page_size(h)); | ||
3938 | if (!ptep) | ||
3939 | return VM_FAULT_OOM; | ||
3958 | } | 3940 | } |
3959 | 3941 | ||
3960 | /* | ||
3961 | * Acquire i_mmap_rwsem before calling huge_pte_alloc and hold | ||
3962 | * until finished with ptep. This prevents huge_pmd_unshare from | ||
3963 | * being called elsewhere and making the ptep no longer valid. | ||
3964 | * | ||
3965 | * ptep could have already be assigned via huge_pte_offset. That | ||
3966 | * is OK, as huge_pte_alloc will return the same value unless | ||
3967 | * something changed. | ||
3968 | */ | ||
3969 | mapping = vma->vm_file->f_mapping; | 3942 | mapping = vma->vm_file->f_mapping; |
3970 | i_mmap_lock_read(mapping); | 3943 | idx = vma_hugecache_offset(h, vma, haddr); |
3971 | ptep = huge_pte_alloc(mm, haddr, huge_page_size(h)); | ||
3972 | if (!ptep) { | ||
3973 | i_mmap_unlock_read(mapping); | ||
3974 | return VM_FAULT_OOM; | ||
3975 | } | ||
3976 | 3944 | ||
3977 | /* | 3945 | /* |
3978 | * Serialize hugepage allocation and instantiation, so that we don't | 3946 | * Serialize hugepage allocation and instantiation, so that we don't |
3979 | * get spurious allocation failures if two CPUs race to instantiate | 3947 | * get spurious allocation failures if two CPUs race to instantiate |
3980 | * the same page in the page cache. | 3948 | * the same page in the page cache. |
3981 | */ | 3949 | */ |
3982 | idx = vma_hugecache_offset(h, vma, haddr); | ||
3983 | hash = hugetlb_fault_mutex_hash(h, mm, vma, mapping, idx, haddr); | 3950 | hash = hugetlb_fault_mutex_hash(h, mm, vma, mapping, idx, haddr); |
3984 | mutex_lock(&hugetlb_fault_mutex_table[hash]); | 3951 | mutex_lock(&hugetlb_fault_mutex_table[hash]); |
3985 | 3952 | ||
@@ -4067,7 +4034,6 @@ out_ptl: | |||
4067 | } | 4034 | } |
4068 | out_mutex: | 4035 | out_mutex: |
4069 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); | 4036 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); |
4070 | i_mmap_unlock_read(mapping); | ||
4071 | /* | 4037 | /* |
4072 | * Generally it's safe to hold refcount during waiting page lock. But | 4038 | * Generally it's safe to hold refcount during waiting page lock. But |
4073 | * here we just wait to defer the next page fault to avoid busy loop and | 4039 | * here we just wait to defer the next page fault to avoid busy loop and |
@@ -4672,12 +4638,10 @@ void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, | |||
4672 | * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc() | 4638 | * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc() |
4673 | * and returns the corresponding pte. While this is not necessary for the | 4639 | * and returns the corresponding pte. While this is not necessary for the |
4674 | * !shared pmd case because we can allocate the pmd later as well, it makes the | 4640 | * !shared pmd case because we can allocate the pmd later as well, it makes the |
4675 | * code much cleaner. | 4641 | * code much cleaner. pmd allocation is essential for the shared case because |
4676 | * | 4642 | * pud has to be populated inside the same i_mmap_rwsem section - otherwise |
4677 | * This routine must be called with i_mmap_rwsem held in at least read mode. | 4643 | * racing tasks could either miss the sharing (see huge_pte_offset) or select a |
4678 | * For hugetlbfs, this prevents removal of any page table entries associated | 4644 | * bad pmd for sharing. |
4679 | * with the address space. This is important as we are setting up sharing | ||
4680 | * based on existing page table entries (mappings). | ||
4681 | */ | 4645 | */ |
4682 | pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) | 4646 | pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) |
4683 | { | 4647 | { |
@@ -4694,6 +4658,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) | |||
4694 | if (!vma_shareable(vma, addr)) | 4658 | if (!vma_shareable(vma, addr)) |
4695 | return (pte_t *)pmd_alloc(mm, pud, addr); | 4659 | return (pte_t *)pmd_alloc(mm, pud, addr); |
4696 | 4660 | ||
4661 | i_mmap_lock_write(mapping); | ||
4697 | vma_interval_tree_foreach(svma, &mapping->i_mmap, idx, idx) { | 4662 | vma_interval_tree_foreach(svma, &mapping->i_mmap, idx, idx) { |
4698 | if (svma == vma) | 4663 | if (svma == vma) |
4699 | continue; | 4664 | continue; |
@@ -4723,6 +4688,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) | |||
4723 | spin_unlock(ptl); | 4688 | spin_unlock(ptl); |
4724 | out: | 4689 | out: |
4725 | pte = (pte_t *)pmd_alloc(mm, pud, addr); | 4690 | pte = (pte_t *)pmd_alloc(mm, pud, addr); |
4691 | i_mmap_unlock_write(mapping); | ||
4726 | return pte; | 4692 | return pte; |
4727 | } | 4693 | } |
4728 | 4694 | ||
@@ -4733,7 +4699,7 @@ out: | |||
4733 | * indicated by page_count > 1, unmap is achieved by clearing pud and | 4699 | * indicated by page_count > 1, unmap is achieved by clearing pud and |
4734 | * decrementing the ref count. If count == 1, the pte page is not shared. | 4700 | * decrementing the ref count. If count == 1, the pte page is not shared. |
4735 | * | 4701 | * |
4736 | * Called with page table lock held and i_mmap_rwsem held in write mode. | 4702 | * called with page table lock held. |
4737 | * | 4703 | * |
4738 | * returns: 1 successfully unmapped a shared pte page | 4704 | * returns: 1 successfully unmapped a shared pte page |
4739 | * 0 the underlying pte page is not shared, or it is the last user | 4705 | * 0 the underlying pte page is not shared, or it is the last user |
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 6379fff1a5ff..7c72f2a95785 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -966,7 +966,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
966 | enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS; | 966 | enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS; |
967 | struct address_space *mapping; | 967 | struct address_space *mapping; |
968 | LIST_HEAD(tokill); | 968 | LIST_HEAD(tokill); |
969 | bool unmap_success = true; | 969 | bool unmap_success; |
970 | int kill = 1, forcekill; | 970 | int kill = 1, forcekill; |
971 | struct page *hpage = *hpagep; | 971 | struct page *hpage = *hpagep; |
972 | bool mlocked = PageMlocked(hpage); | 972 | bool mlocked = PageMlocked(hpage); |
@@ -1028,19 +1028,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
1028 | if (kill) | 1028 | if (kill) |
1029 | collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED); | 1029 | collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED); |
1030 | 1030 | ||
1031 | if (!PageHuge(hpage)) { | 1031 | unmap_success = try_to_unmap(hpage, ttu); |
1032 | unmap_success = try_to_unmap(hpage, ttu); | ||
1033 | } else if (mapping) { | ||
1034 | /* | ||
1035 | * For hugetlb pages, try_to_unmap could potentially call | ||
1036 | * huge_pmd_unshare. Because of this, take semaphore in | ||
1037 | * write mode here and set TTU_RMAP_LOCKED to indicate we | ||
1038 | * have taken the lock at this higer level. | ||
1039 | */ | ||
1040 | i_mmap_lock_write(mapping); | ||
1041 | unmap_success = try_to_unmap(hpage, ttu|TTU_RMAP_LOCKED); | ||
1042 | i_mmap_unlock_write(mapping); | ||
1043 | } | ||
1044 | if (!unmap_success) | 1032 | if (!unmap_success) |
1045 | pr_err("Memory failure: %#lx: failed to unmap page (mapcount=%d)\n", | 1033 | pr_err("Memory failure: %#lx: failed to unmap page (mapcount=%d)\n", |
1046 | pfn, page_mapcount(hpage)); | 1034 | pfn, page_mapcount(hpage)); |
diff --git a/mm/migrate.c b/mm/migrate.c index ccf8966caf6f..a16b15090df3 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -1324,19 +1324,8 @@ static int unmap_and_move_huge_page(new_page_t get_new_page, | |||
1324 | goto put_anon; | 1324 | goto put_anon; |
1325 | 1325 | ||
1326 | if (page_mapped(hpage)) { | 1326 | if (page_mapped(hpage)) { |
1327 | struct address_space *mapping = page_mapping(hpage); | ||
1328 | |||
1329 | /* | ||
1330 | * try_to_unmap could potentially call huge_pmd_unshare. | ||
1331 | * Because of this, take semaphore in write mode here and | ||
1332 | * set TTU_RMAP_LOCKED to let lower levels know we have | ||
1333 | * taken the lock. | ||
1334 | */ | ||
1335 | i_mmap_lock_write(mapping); | ||
1336 | try_to_unmap(hpage, | 1327 | try_to_unmap(hpage, |
1337 | TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS| | 1328 | TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS); |
1338 | TTU_RMAP_LOCKED); | ||
1339 | i_mmap_unlock_write(mapping); | ||
1340 | page_was_mapped = 1; | 1329 | page_was_mapped = 1; |
1341 | } | 1330 | } |
1342 | 1331 | ||
@@ -25,7 +25,6 @@ | |||
25 | * page->flags PG_locked (lock_page) | 25 | * page->flags PG_locked (lock_page) |
26 | * hugetlbfs_i_mmap_rwsem_key (in huge_pmd_share) | 26 | * hugetlbfs_i_mmap_rwsem_key (in huge_pmd_share) |
27 | * mapping->i_mmap_rwsem | 27 | * mapping->i_mmap_rwsem |
28 | * hugetlb_fault_mutex (hugetlbfs specific page fault mutex) | ||
29 | * anon_vma->rwsem | 28 | * anon_vma->rwsem |
30 | * mm->page_table_lock or pte_lock | 29 | * mm->page_table_lock or pte_lock |
31 | * zone_lru_lock (in mark_page_accessed, isolate_lru_page) | 30 | * zone_lru_lock (in mark_page_accessed, isolate_lru_page) |
@@ -1379,9 +1378,6 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma, | |||
1379 | /* | 1378 | /* |
1380 | * If sharing is possible, start and end will be adjusted | 1379 | * If sharing is possible, start and end will be adjusted |
1381 | * accordingly. | 1380 | * accordingly. |
1382 | * | ||
1383 | * If called for a huge page, caller must hold i_mmap_rwsem | ||
1384 | * in write mode as it is possible to call huge_pmd_unshare. | ||
1385 | */ | 1381 | */ |
1386 | adjust_range_if_pmd_sharing_possible(vma, &range.start, | 1382 | adjust_range_if_pmd_sharing_possible(vma, &range.start, |
1387 | &range.end); | 1383 | &range.end); |
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 065c1ce191c4..d59b5a73dfb3 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c | |||
@@ -267,14 +267,10 @@ retry: | |||
267 | VM_BUG_ON(dst_addr & ~huge_page_mask(h)); | 267 | VM_BUG_ON(dst_addr & ~huge_page_mask(h)); |
268 | 268 | ||
269 | /* | 269 | /* |
270 | * Serialize via i_mmap_rwsem and hugetlb_fault_mutex. | 270 | * Serialize via hugetlb_fault_mutex |
271 | * i_mmap_rwsem ensures the dst_pte remains valid even | ||
272 | * in the case of shared pmds. fault mutex prevents | ||
273 | * races with other faulting threads. | ||
274 | */ | 271 | */ |
275 | mapping = dst_vma->vm_file->f_mapping; | ||
276 | i_mmap_lock_read(mapping); | ||
277 | idx = linear_page_index(dst_vma, dst_addr); | 272 | idx = linear_page_index(dst_vma, dst_addr); |
273 | mapping = dst_vma->vm_file->f_mapping; | ||
278 | hash = hugetlb_fault_mutex_hash(h, dst_mm, dst_vma, mapping, | 274 | hash = hugetlb_fault_mutex_hash(h, dst_mm, dst_vma, mapping, |
279 | idx, dst_addr); | 275 | idx, dst_addr); |
280 | mutex_lock(&hugetlb_fault_mutex_table[hash]); | 276 | mutex_lock(&hugetlb_fault_mutex_table[hash]); |
@@ -283,7 +279,6 @@ retry: | |||
283 | dst_pte = huge_pte_alloc(dst_mm, dst_addr, huge_page_size(h)); | 279 | dst_pte = huge_pte_alloc(dst_mm, dst_addr, huge_page_size(h)); |
284 | if (!dst_pte) { | 280 | if (!dst_pte) { |
285 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); | 281 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); |
286 | i_mmap_unlock_read(mapping); | ||
287 | goto out_unlock; | 282 | goto out_unlock; |
288 | } | 283 | } |
289 | 284 | ||
@@ -291,7 +286,6 @@ retry: | |||
291 | dst_pteval = huge_ptep_get(dst_pte); | 286 | dst_pteval = huge_ptep_get(dst_pte); |
292 | if (!huge_pte_none(dst_pteval)) { | 287 | if (!huge_pte_none(dst_pteval)) { |
293 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); | 288 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); |
294 | i_mmap_unlock_read(mapping); | ||
295 | goto out_unlock; | 289 | goto out_unlock; |
296 | } | 290 | } |
297 | 291 | ||
@@ -299,7 +293,6 @@ retry: | |||
299 | dst_addr, src_addr, &page); | 293 | dst_addr, src_addr, &page); |
300 | 294 | ||
301 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); | 295 | mutex_unlock(&hugetlb_fault_mutex_table[hash]); |
302 | i_mmap_unlock_read(mapping); | ||
303 | vm_alloc_shared = vm_shared; | 296 | vm_alloc_shared = vm_shared; |
304 | 297 | ||
305 | cond_resched(); | 298 | cond_resched(); |