diff options
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 95 |
1 files changed, 67 insertions, 28 deletions
diff --git a/mm/memory.c b/mm/memory.c index 098f00d05461..305537fc8640 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -789,6 +789,46 @@ out: | |||
789 | return pfn_to_page(pfn); | 789 | return pfn_to_page(pfn); |
790 | } | 790 | } |
791 | 791 | ||
792 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
793 | struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, | ||
794 | pmd_t pmd) | ||
795 | { | ||
796 | unsigned long pfn = pmd_pfn(pmd); | ||
797 | |||
798 | /* | ||
799 | * There is no pmd_special() but there may be special pmds, e.g. | ||
800 | * in a direct-access (dax) mapping, so let's just replicate the | ||
801 | * !HAVE_PTE_SPECIAL case from vm_normal_page() here. | ||
802 | */ | ||
803 | if (unlikely(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))) { | ||
804 | if (vma->vm_flags & VM_MIXEDMAP) { | ||
805 | if (!pfn_valid(pfn)) | ||
806 | return NULL; | ||
807 | goto out; | ||
808 | } else { | ||
809 | unsigned long off; | ||
810 | off = (addr - vma->vm_start) >> PAGE_SHIFT; | ||
811 | if (pfn == vma->vm_pgoff + off) | ||
812 | return NULL; | ||
813 | if (!is_cow_mapping(vma->vm_flags)) | ||
814 | return NULL; | ||
815 | } | ||
816 | } | ||
817 | |||
818 | if (is_zero_pfn(pfn)) | ||
819 | return NULL; | ||
820 | if (unlikely(pfn > highest_memmap_pfn)) | ||
821 | return NULL; | ||
822 | |||
823 | /* | ||
824 | * NOTE! We still have PageReserved() pages in the page tables. | ||
825 | * eg. VDSO mappings can cause them to exist. | ||
826 | */ | ||
827 | out: | ||
828 | return pfn_to_page(pfn); | ||
829 | } | ||
830 | #endif | ||
831 | |||
792 | /* | 832 | /* |
793 | * copy one vm_area from one task to the other. Assumes the page tables | 833 | * copy one vm_area from one task to the other. Assumes the page tables |
794 | * already present in the new task to be cleared in the whole range | 834 | * already present in the new task to be cleared in the whole range |
@@ -2054,7 +2094,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, | |||
2054 | VM_BUG_ON_PAGE(PageAnon(page), page); | 2094 | VM_BUG_ON_PAGE(PageAnon(page), page); |
2055 | mapping = page->mapping; | 2095 | mapping = page->mapping; |
2056 | unlock_page(page); | 2096 | unlock_page(page); |
2057 | page_cache_release(page); | 2097 | put_page(page); |
2058 | 2098 | ||
2059 | if ((dirtied || page_mkwrite) && mapping) { | 2099 | if ((dirtied || page_mkwrite) && mapping) { |
2060 | /* | 2100 | /* |
@@ -2188,7 +2228,7 @@ static int wp_page_copy(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2188 | } | 2228 | } |
2189 | 2229 | ||
2190 | if (new_page) | 2230 | if (new_page) |
2191 | page_cache_release(new_page); | 2231 | put_page(new_page); |
2192 | 2232 | ||
2193 | pte_unmap_unlock(page_table, ptl); | 2233 | pte_unmap_unlock(page_table, ptl); |
2194 | mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); | 2234 | mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); |
@@ -2203,14 +2243,14 @@ static int wp_page_copy(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2203 | munlock_vma_page(old_page); | 2243 | munlock_vma_page(old_page); |
2204 | unlock_page(old_page); | 2244 | unlock_page(old_page); |
2205 | } | 2245 | } |
2206 | page_cache_release(old_page); | 2246 | put_page(old_page); |
2207 | } | 2247 | } |
2208 | return page_copied ? VM_FAULT_WRITE : 0; | 2248 | return page_copied ? VM_FAULT_WRITE : 0; |
2209 | oom_free_new: | 2249 | oom_free_new: |
2210 | page_cache_release(new_page); | 2250 | put_page(new_page); |
2211 | oom: | 2251 | oom: |
2212 | if (old_page) | 2252 | if (old_page) |
2213 | page_cache_release(old_page); | 2253 | put_page(old_page); |
2214 | return VM_FAULT_OOM; | 2254 | return VM_FAULT_OOM; |
2215 | } | 2255 | } |
2216 | 2256 | ||
@@ -2258,7 +2298,7 @@ static int wp_page_shared(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2258 | { | 2298 | { |
2259 | int page_mkwrite = 0; | 2299 | int page_mkwrite = 0; |
2260 | 2300 | ||
2261 | page_cache_get(old_page); | 2301 | get_page(old_page); |
2262 | 2302 | ||
2263 | if (vma->vm_ops && vma->vm_ops->page_mkwrite) { | 2303 | if (vma->vm_ops && vma->vm_ops->page_mkwrite) { |
2264 | int tmp; | 2304 | int tmp; |
@@ -2267,7 +2307,7 @@ static int wp_page_shared(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2267 | tmp = do_page_mkwrite(vma, old_page, address); | 2307 | tmp = do_page_mkwrite(vma, old_page, address); |
2268 | if (unlikely(!tmp || (tmp & | 2308 | if (unlikely(!tmp || (tmp & |
2269 | (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) { | 2309 | (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) { |
2270 | page_cache_release(old_page); | 2310 | put_page(old_page); |
2271 | return tmp; | 2311 | return tmp; |
2272 | } | 2312 | } |
2273 | /* | 2313 | /* |
@@ -2281,7 +2321,7 @@ static int wp_page_shared(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2281 | if (!pte_same(*page_table, orig_pte)) { | 2321 | if (!pte_same(*page_table, orig_pte)) { |
2282 | unlock_page(old_page); | 2322 | unlock_page(old_page); |
2283 | pte_unmap_unlock(page_table, ptl); | 2323 | pte_unmap_unlock(page_table, ptl); |
2284 | page_cache_release(old_page); | 2324 | put_page(old_page); |
2285 | return 0; | 2325 | return 0; |
2286 | } | 2326 | } |
2287 | page_mkwrite = 1; | 2327 | page_mkwrite = 1; |
@@ -2341,7 +2381,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2341 | */ | 2381 | */ |
2342 | if (PageAnon(old_page) && !PageKsm(old_page)) { | 2382 | if (PageAnon(old_page) && !PageKsm(old_page)) { |
2343 | if (!trylock_page(old_page)) { | 2383 | if (!trylock_page(old_page)) { |
2344 | page_cache_get(old_page); | 2384 | get_page(old_page); |
2345 | pte_unmap_unlock(page_table, ptl); | 2385 | pte_unmap_unlock(page_table, ptl); |
2346 | lock_page(old_page); | 2386 | lock_page(old_page); |
2347 | page_table = pte_offset_map_lock(mm, pmd, address, | 2387 | page_table = pte_offset_map_lock(mm, pmd, address, |
@@ -2349,10 +2389,10 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2349 | if (!pte_same(*page_table, orig_pte)) { | 2389 | if (!pte_same(*page_table, orig_pte)) { |
2350 | unlock_page(old_page); | 2390 | unlock_page(old_page); |
2351 | pte_unmap_unlock(page_table, ptl); | 2391 | pte_unmap_unlock(page_table, ptl); |
2352 | page_cache_release(old_page); | 2392 | put_page(old_page); |
2353 | return 0; | 2393 | return 0; |
2354 | } | 2394 | } |
2355 | page_cache_release(old_page); | 2395 | put_page(old_page); |
2356 | } | 2396 | } |
2357 | if (reuse_swap_page(old_page)) { | 2397 | if (reuse_swap_page(old_page)) { |
2358 | /* | 2398 | /* |
@@ -2375,7 +2415,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2375 | /* | 2415 | /* |
2376 | * Ok, we need to copy. Oh, well.. | 2416 | * Ok, we need to copy. Oh, well.. |
2377 | */ | 2417 | */ |
2378 | page_cache_get(old_page); | 2418 | get_page(old_page); |
2379 | 2419 | ||
2380 | pte_unmap_unlock(page_table, ptl); | 2420 | pte_unmap_unlock(page_table, ptl); |
2381 | return wp_page_copy(mm, vma, address, page_table, pmd, | 2421 | return wp_page_copy(mm, vma, address, page_table, pmd, |
@@ -2400,7 +2440,6 @@ static inline void unmap_mapping_range_tree(struct rb_root *root, | |||
2400 | 2440 | ||
2401 | vba = vma->vm_pgoff; | 2441 | vba = vma->vm_pgoff; |
2402 | vea = vba + vma_pages(vma) - 1; | 2442 | vea = vba + vma_pages(vma) - 1; |
2403 | /* Assume for now that PAGE_CACHE_SHIFT == PAGE_SHIFT */ | ||
2404 | zba = details->first_index; | 2443 | zba = details->first_index; |
2405 | if (zba < vba) | 2444 | if (zba < vba) |
2406 | zba = vba; | 2445 | zba = vba; |
@@ -2619,7 +2658,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2619 | * parallel locked swapcache. | 2658 | * parallel locked swapcache. |
2620 | */ | 2659 | */ |
2621 | unlock_page(swapcache); | 2660 | unlock_page(swapcache); |
2622 | page_cache_release(swapcache); | 2661 | put_page(swapcache); |
2623 | } | 2662 | } |
2624 | 2663 | ||
2625 | if (flags & FAULT_FLAG_WRITE) { | 2664 | if (flags & FAULT_FLAG_WRITE) { |
@@ -2641,10 +2680,10 @@ out_nomap: | |||
2641 | out_page: | 2680 | out_page: |
2642 | unlock_page(page); | 2681 | unlock_page(page); |
2643 | out_release: | 2682 | out_release: |
2644 | page_cache_release(page); | 2683 | put_page(page); |
2645 | if (page != swapcache) { | 2684 | if (page != swapcache) { |
2646 | unlock_page(swapcache); | 2685 | unlock_page(swapcache); |
2647 | page_cache_release(swapcache); | 2686 | put_page(swapcache); |
2648 | } | 2687 | } |
2649 | return ret; | 2688 | return ret; |
2650 | } | 2689 | } |
@@ -2752,7 +2791,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2752 | if (userfaultfd_missing(vma)) { | 2791 | if (userfaultfd_missing(vma)) { |
2753 | pte_unmap_unlock(page_table, ptl); | 2792 | pte_unmap_unlock(page_table, ptl); |
2754 | mem_cgroup_cancel_charge(page, memcg, false); | 2793 | mem_cgroup_cancel_charge(page, memcg, false); |
2755 | page_cache_release(page); | 2794 | put_page(page); |
2756 | return handle_userfault(vma, address, flags, | 2795 | return handle_userfault(vma, address, flags, |
2757 | VM_UFFD_MISSING); | 2796 | VM_UFFD_MISSING); |
2758 | } | 2797 | } |
@@ -2771,10 +2810,10 @@ unlock: | |||
2771 | return 0; | 2810 | return 0; |
2772 | release: | 2811 | release: |
2773 | mem_cgroup_cancel_charge(page, memcg, false); | 2812 | mem_cgroup_cancel_charge(page, memcg, false); |
2774 | page_cache_release(page); | 2813 | put_page(page); |
2775 | goto unlock; | 2814 | goto unlock; |
2776 | oom_free_page: | 2815 | oom_free_page: |
2777 | page_cache_release(page); | 2816 | put_page(page); |
2778 | oom: | 2817 | oom: |
2779 | return VM_FAULT_OOM; | 2818 | return VM_FAULT_OOM; |
2780 | } | 2819 | } |
@@ -2807,7 +2846,7 @@ static int __do_fault(struct vm_area_struct *vma, unsigned long address, | |||
2807 | if (unlikely(PageHWPoison(vmf.page))) { | 2846 | if (unlikely(PageHWPoison(vmf.page))) { |
2808 | if (ret & VM_FAULT_LOCKED) | 2847 | if (ret & VM_FAULT_LOCKED) |
2809 | unlock_page(vmf.page); | 2848 | unlock_page(vmf.page); |
2810 | page_cache_release(vmf.page); | 2849 | put_page(vmf.page); |
2811 | return VM_FAULT_HWPOISON; | 2850 | return VM_FAULT_HWPOISON; |
2812 | } | 2851 | } |
2813 | 2852 | ||
@@ -2996,7 +3035,7 @@ static int do_read_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2996 | if (unlikely(!pte_same(*pte, orig_pte))) { | 3035 | if (unlikely(!pte_same(*pte, orig_pte))) { |
2997 | pte_unmap_unlock(pte, ptl); | 3036 | pte_unmap_unlock(pte, ptl); |
2998 | unlock_page(fault_page); | 3037 | unlock_page(fault_page); |
2999 | page_cache_release(fault_page); | 3038 | put_page(fault_page); |
3000 | return ret; | 3039 | return ret; |
3001 | } | 3040 | } |
3002 | do_set_pte(vma, address, fault_page, pte, false, false); | 3041 | do_set_pte(vma, address, fault_page, pte, false, false); |
@@ -3024,7 +3063,7 @@ static int do_cow_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3024 | return VM_FAULT_OOM; | 3063 | return VM_FAULT_OOM; |
3025 | 3064 | ||
3026 | if (mem_cgroup_try_charge(new_page, mm, GFP_KERNEL, &memcg, false)) { | 3065 | if (mem_cgroup_try_charge(new_page, mm, GFP_KERNEL, &memcg, false)) { |
3027 | page_cache_release(new_page); | 3066 | put_page(new_page); |
3028 | return VM_FAULT_OOM; | 3067 | return VM_FAULT_OOM; |
3029 | } | 3068 | } |
3030 | 3069 | ||
@@ -3041,7 +3080,7 @@ static int do_cow_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3041 | pte_unmap_unlock(pte, ptl); | 3080 | pte_unmap_unlock(pte, ptl); |
3042 | if (fault_page) { | 3081 | if (fault_page) { |
3043 | unlock_page(fault_page); | 3082 | unlock_page(fault_page); |
3044 | page_cache_release(fault_page); | 3083 | put_page(fault_page); |
3045 | } else { | 3084 | } else { |
3046 | /* | 3085 | /* |
3047 | * The fault handler has no page to lock, so it holds | 3086 | * The fault handler has no page to lock, so it holds |
@@ -3057,7 +3096,7 @@ static int do_cow_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3057 | pte_unmap_unlock(pte, ptl); | 3096 | pte_unmap_unlock(pte, ptl); |
3058 | if (fault_page) { | 3097 | if (fault_page) { |
3059 | unlock_page(fault_page); | 3098 | unlock_page(fault_page); |
3060 | page_cache_release(fault_page); | 3099 | put_page(fault_page); |
3061 | } else { | 3100 | } else { |
3062 | /* | 3101 | /* |
3063 | * The fault handler has no page to lock, so it holds | 3102 | * The fault handler has no page to lock, so it holds |
@@ -3068,7 +3107,7 @@ static int do_cow_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3068 | return ret; | 3107 | return ret; |
3069 | uncharge_out: | 3108 | uncharge_out: |
3070 | mem_cgroup_cancel_charge(new_page, memcg, false); | 3109 | mem_cgroup_cancel_charge(new_page, memcg, false); |
3071 | page_cache_release(new_page); | 3110 | put_page(new_page); |
3072 | return ret; | 3111 | return ret; |
3073 | } | 3112 | } |
3074 | 3113 | ||
@@ -3096,7 +3135,7 @@ static int do_shared_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3096 | tmp = do_page_mkwrite(vma, fault_page, address); | 3135 | tmp = do_page_mkwrite(vma, fault_page, address); |
3097 | if (unlikely(!tmp || | 3136 | if (unlikely(!tmp || |
3098 | (tmp & (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) { | 3137 | (tmp & (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) { |
3099 | page_cache_release(fault_page); | 3138 | put_page(fault_page); |
3100 | return tmp; | 3139 | return tmp; |
3101 | } | 3140 | } |
3102 | } | 3141 | } |
@@ -3105,7 +3144,7 @@ static int do_shared_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3105 | if (unlikely(!pte_same(*pte, orig_pte))) { | 3144 | if (unlikely(!pte_same(*pte, orig_pte))) { |
3106 | pte_unmap_unlock(pte, ptl); | 3145 | pte_unmap_unlock(pte, ptl); |
3107 | unlock_page(fault_page); | 3146 | unlock_page(fault_page); |
3108 | page_cache_release(fault_page); | 3147 | put_page(fault_page); |
3109 | return ret; | 3148 | return ret; |
3110 | } | 3149 | } |
3111 | do_set_pte(vma, address, fault_page, pte, true, false); | 3150 | do_set_pte(vma, address, fault_page, pte, true, false); |
@@ -3736,7 +3775,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, | |||
3736 | buf, maddr + offset, bytes); | 3775 | buf, maddr + offset, bytes); |
3737 | } | 3776 | } |
3738 | kunmap(page); | 3777 | kunmap(page); |
3739 | page_cache_release(page); | 3778 | put_page(page); |
3740 | } | 3779 | } |
3741 | len -= bytes; | 3780 | len -= bytes; |
3742 | buf += bytes; | 3781 | buf += bytes; |