diff options
author | Shachar Raindel <raindel@mellanox.com> | 2015-04-14 18:46:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-14 19:49:03 -0400 |
commit | 93e478d4c36ecaf15b942988b8272102d661d44e (patch) | |
tree | c3d5af0f964bf1585e71d52baf436081fd567087 | |
parent | 2f38ab2c3c7fef04dca0313fd89d91f142ca9281 (diff) |
mm: refactor do_wp_page handling of shared vma into a function
The do_wp_page function is extremely long. Extract the logic for
handling a page belonging to a shared vma into a function of its own.
This helps the readability of the code, without doing any functional
change in it.
Signed-off-by: Shachar Raindel <raindel@mellanox.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Rik van Riel <riel@redhat.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Haggai Eran <haggaie@mellanox.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Matthew Wilcox <matthew.r.wilcox@intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Peter Feiner <pfeiner@google.com>
Cc: Michel Lespinasse <walken@google.com>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | mm/memory.c | 86 |
1 files changed, 48 insertions, 38 deletions
diff --git a/mm/memory.c b/mm/memory.c index cfd3c78f00fe..ac20b2a6a0c3 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2181,6 +2181,52 @@ oom: | |||
2181 | return VM_FAULT_OOM; | 2181 | return VM_FAULT_OOM; |
2182 | } | 2182 | } |
2183 | 2183 | ||
2184 | static int wp_page_shared(struct mm_struct *mm, struct vm_area_struct *vma, | ||
2185 | unsigned long address, pte_t *page_table, | ||
2186 | pmd_t *pmd, spinlock_t *ptl, pte_t orig_pte, | ||
2187 | struct page *old_page) | ||
2188 | __releases(ptl) | ||
2189 | { | ||
2190 | int page_mkwrite = 0; | ||
2191 | |||
2192 | page_cache_get(old_page); | ||
2193 | |||
2194 | /* | ||
2195 | * Only catch write-faults on shared writable pages, | ||
2196 | * read-only shared pages can get COWed by | ||
2197 | * get_user_pages(.write=1, .force=1). | ||
2198 | */ | ||
2199 | if (vma->vm_ops && vma->vm_ops->page_mkwrite) { | ||
2200 | int tmp; | ||
2201 | |||
2202 | pte_unmap_unlock(page_table, ptl); | ||
2203 | tmp = do_page_mkwrite(vma, old_page, address); | ||
2204 | if (unlikely(!tmp || (tmp & | ||
2205 | (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) { | ||
2206 | page_cache_release(old_page); | ||
2207 | return tmp; | ||
2208 | } | ||
2209 | /* | ||
2210 | * Since we dropped the lock we need to revalidate | ||
2211 | * the PTE as someone else may have changed it. If | ||
2212 | * they did, we just return, as we can count on the | ||
2213 | * MMU to tell us if they didn't also make it writable. | ||
2214 | */ | ||
2215 | page_table = pte_offset_map_lock(mm, pmd, address, | ||
2216 | &ptl); | ||
2217 | if (!pte_same(*page_table, orig_pte)) { | ||
2218 | unlock_page(old_page); | ||
2219 | pte_unmap_unlock(page_table, ptl); | ||
2220 | page_cache_release(old_page); | ||
2221 | return 0; | ||
2222 | } | ||
2223 | page_mkwrite = 1; | ||
2224 | } | ||
2225 | |||
2226 | return wp_page_reuse(mm, vma, address, page_table, ptl, | ||
2227 | orig_pte, old_page, page_mkwrite, 1); | ||
2228 | } | ||
2229 | |||
2184 | /* | 2230 | /* |
2185 | * This routine handles present pages, when users try to write | 2231 | * This routine handles present pages, when users try to write |
2186 | * to a shared page. It is done by copying the page to a new address | 2232 | * to a shared page. It is done by copying the page to a new address |
@@ -2259,44 +2305,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2259 | unlock_page(old_page); | 2305 | unlock_page(old_page); |
2260 | } else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) == | 2306 | } else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) == |
2261 | (VM_WRITE|VM_SHARED))) { | 2307 | (VM_WRITE|VM_SHARED))) { |
2262 | int page_mkwrite = 0; | 2308 | return wp_page_shared(mm, vma, address, page_table, pmd, |
2263 | 2309 | ptl, orig_pte, old_page); | |
2264 | page_cache_get(old_page); | ||
2265 | |||
2266 | /* | ||
2267 | * Only catch write-faults on shared writable pages, | ||
2268 | * read-only shared pages can get COWed by | ||
2269 | * get_user_pages(.write=1, .force=1). | ||
2270 | */ | ||
2271 | if (vma->vm_ops && vma->vm_ops->page_mkwrite) { | ||
2272 | int tmp; | ||
2273 | |||
2274 | pte_unmap_unlock(page_table, ptl); | ||
2275 | tmp = do_page_mkwrite(vma, old_page, address); | ||
2276 | if (unlikely(!tmp || (tmp & | ||
2277 | (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) { | ||
2278 | page_cache_release(old_page); | ||
2279 | return tmp; | ||
2280 | } | ||
2281 | /* | ||
2282 | * Since we dropped the lock we need to revalidate | ||
2283 | * the PTE as someone else may have changed it. If | ||
2284 | * they did, we just return, as we can count on the | ||
2285 | * MMU to tell us if they didn't also make it writable. | ||
2286 | */ | ||
2287 | page_table = pte_offset_map_lock(mm, pmd, address, | ||
2288 | &ptl); | ||
2289 | if (!pte_same(*page_table, orig_pte)) { | ||
2290 | unlock_page(old_page); | ||
2291 | pte_unmap_unlock(page_table, ptl); | ||
2292 | page_cache_release(old_page); | ||
2293 | return 0; | ||
2294 | } | ||
2295 | page_mkwrite = 1; | ||
2296 | } | ||
2297 | |||
2298 | return wp_page_reuse(mm, vma, address, page_table, ptl, | ||
2299 | orig_pte, old_page, page_mkwrite, 1); | ||
2300 | } | 2310 | } |
2301 | 2311 | ||
2302 | /* | 2312 | /* |