aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c65
1 files changed, 9 insertions, 56 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 9a3e73b69dad..43a53743cbb4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1899,12 +1899,11 @@ int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
1899EXPORT_SYMBOL_GPL(apply_to_page_range); 1899EXPORT_SYMBOL_GPL(apply_to_page_range);
1900 1900
1901/* 1901/*
1902 * handle_pte_fault chooses page fault handler according to an entry 1902 * handle_pte_fault chooses page fault handler according to an entry which was
1903 * which was read non-atomically. Before making any commitment, on 1903 * read non-atomically. Before making any commitment, on those architectures
1904 * those architectures or configurations (e.g. i386 with PAE) which 1904 * or configurations (e.g. i386 with PAE) which might give a mix of unmatched
1905 * might give a mix of unmatched parts, do_swap_page and do_nonlinear_fault 1905 * parts, do_swap_page must check under lock before unmapping the pte and
1906 * must check under lock before unmapping the pte and proceeding 1906 * proceeding (but do_wp_page is only called after already making such a check;
1907 * (but do_wp_page is only called after already making such a check;
1908 * and do_anonymous_page can safely check later on). 1907 * and do_anonymous_page can safely check later on).
1909 */ 1908 */
1910static inline int pte_unmap_same(struct mm_struct *mm, pmd_t *pmd, 1909static inline int pte_unmap_same(struct mm_struct *mm, pmd_t *pmd,
@@ -2710,8 +2709,6 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address,
2710 entry = mk_pte(page, vma->vm_page_prot); 2709 entry = mk_pte(page, vma->vm_page_prot);
2711 if (write) 2710 if (write)
2712 entry = maybe_mkwrite(pte_mkdirty(entry), vma); 2711 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
2713 else if (pte_file(*pte) && pte_file_soft_dirty(*pte))
2714 entry = pte_mksoft_dirty(entry);
2715 if (anon) { 2712 if (anon) {
2716 inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES); 2713 inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES);
2717 page_add_new_anon_rmap(page, vma, address); 2714 page_add_new_anon_rmap(page, vma, address);
@@ -2846,8 +2843,7 @@ static int do_read_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2846 * if page by the offset is not ready to be mapped (cold cache or 2843 * if page by the offset is not ready to be mapped (cold cache or
2847 * something). 2844 * something).
2848 */ 2845 */
2849 if (vma->vm_ops->map_pages && !(flags & FAULT_FLAG_NONLINEAR) && 2846 if (vma->vm_ops->map_pages && fault_around_bytes >> PAGE_SHIFT > 1) {
2850 fault_around_bytes >> PAGE_SHIFT > 1) {
2851 pte = pte_offset_map_lock(mm, pmd, address, &ptl); 2847 pte = pte_offset_map_lock(mm, pmd, address, &ptl);
2852 do_fault_around(vma, address, pte, pgoff, flags); 2848 do_fault_around(vma, address, pte, pgoff, flags);
2853 if (!pte_same(*pte, orig_pte)) 2849 if (!pte_same(*pte, orig_pte))
@@ -2992,7 +2988,7 @@ static int do_shared_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2992 * The mmap_sem may have been released depending on flags and our 2988 * The mmap_sem may have been released depending on flags and our
2993 * return value. See filemap_fault() and __lock_page_or_retry(). 2989 * return value. See filemap_fault() and __lock_page_or_retry().
2994 */ 2990 */
2995static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma, 2991static int do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2996 unsigned long address, pte_t *page_table, pmd_t *pmd, 2992 unsigned long address, pte_t *page_table, pmd_t *pmd,
2997 unsigned int flags, pte_t orig_pte) 2993 unsigned int flags, pte_t orig_pte)
2998{ 2994{
@@ -3009,46 +3005,6 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
3009 return do_shared_fault(mm, vma, address, pmd, pgoff, flags, orig_pte); 3005 return do_shared_fault(mm, vma, address, pmd, pgoff, flags, orig_pte);
3010} 3006}
3011 3007
3012/*
3013 * Fault of a previously existing named mapping. Repopulate the pte
3014 * from the encoded file_pte if possible. This enables swappable
3015 * nonlinear vmas.
3016 *
3017 * We enter with non-exclusive mmap_sem (to exclude vma changes,
3018 * but allow concurrent faults), and pte mapped but not yet locked.
3019 * We return with pte unmapped and unlocked.
3020 * The mmap_sem may have been released depending on flags and our
3021 * return value. See filemap_fault() and __lock_page_or_retry().
3022 */
3023static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
3024 unsigned long address, pte_t *page_table, pmd_t *pmd,
3025 unsigned int flags, pte_t orig_pte)
3026{
3027 pgoff_t pgoff;
3028
3029 flags |= FAULT_FLAG_NONLINEAR;
3030
3031 if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
3032 return 0;
3033
3034 if (unlikely(!(vma->vm_flags & VM_NONLINEAR))) {
3035 /*
3036 * Page table corrupted: show pte and kill process.
3037 */
3038 print_bad_pte(vma, address, orig_pte, NULL);
3039 return VM_FAULT_SIGBUS;
3040 }
3041
3042 pgoff = pte_to_pgoff(orig_pte);
3043 if (!(flags & FAULT_FLAG_WRITE))
3044 return do_read_fault(mm, vma, address, pmd, pgoff, flags,
3045 orig_pte);
3046 if (!(vma->vm_flags & VM_SHARED))
3047 return do_cow_fault(mm, vma, address, pmd, pgoff, flags,
3048 orig_pte);
3049 return do_shared_fault(mm, vma, address, pmd, pgoff, flags, orig_pte);
3050}
3051
3052static int numa_migrate_prep(struct page *page, struct vm_area_struct *vma, 3008static int numa_migrate_prep(struct page *page, struct vm_area_struct *vma,
3053 unsigned long addr, int page_nid, 3009 unsigned long addr, int page_nid,
3054 int *flags) 3010 int *flags)
@@ -3176,15 +3132,12 @@ static int handle_pte_fault(struct mm_struct *mm,
3176 if (pte_none(entry)) { 3132 if (pte_none(entry)) {
3177 if (vma->vm_ops) { 3133 if (vma->vm_ops) {
3178 if (likely(vma->vm_ops->fault)) 3134 if (likely(vma->vm_ops->fault))
3179 return do_linear_fault(mm, vma, address, 3135 return do_fault(mm, vma, address, pte,
3180 pte, pmd, flags, entry); 3136 pmd, flags, entry);
3181 } 3137 }
3182 return do_anonymous_page(mm, vma, address, 3138 return do_anonymous_page(mm, vma, address,
3183 pte, pmd, flags); 3139 pte, pmd, flags);
3184 } 3140 }
3185 if (pte_file(entry))
3186 return do_nonlinear_fault(mm, vma, address,
3187 pte, pmd, flags, entry);
3188 return do_swap_page(mm, vma, address, 3141 return do_swap_page(mm, vma, address,
3189 pte, pmd, flags, entry); 3142 pte, pmd, flags, entry);
3190 } 3143 }