diff options
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/mm/memory.c b/mm/memory.c index ba5189e322e6..1358012ffa73 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2431,7 +2431,8 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2431 | lock_page(page); | 2431 | lock_page(page); |
2432 | delayacct_clear_flag(DELAYACCT_PF_SWAPIN); | 2432 | delayacct_clear_flag(DELAYACCT_PF_SWAPIN); |
2433 | 2433 | ||
2434 | if (mem_cgroup_try_charge(mm, GFP_HIGHUSER_MOVABLE, &ptr) == -ENOMEM) { | 2434 | if (mem_cgroup_try_charge_swapin(mm, page, |
2435 | GFP_HIGHUSER_MOVABLE, &ptr) == -ENOMEM) { | ||
2435 | ret = VM_FAULT_OOM; | 2436 | ret = VM_FAULT_OOM; |
2436 | unlock_page(page); | 2437 | unlock_page(page); |
2437 | goto out; | 2438 | goto out; |
@@ -2449,8 +2450,20 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2449 | goto out_nomap; | 2450 | goto out_nomap; |
2450 | } | 2451 | } |
2451 | 2452 | ||
2452 | /* The page isn't present yet, go ahead with the fault. */ | 2453 | /* |
2454 | * The page isn't present yet, go ahead with the fault. | ||
2455 | * | ||
2456 | * Be careful about the sequence of operations here. | ||
2457 | * To get its accounting right, reuse_swap_page() must be called | ||
2458 | * while the page is counted on swap but not yet in mapcount i.e. | ||
2459 | * before page_add_anon_rmap() and swap_free(); try_to_free_swap() | ||
2460 | * must be called after the swap_free(), or it will never succeed. | ||
2461 | * And mem_cgroup_commit_charge_swapin(), which uses the swp_entry | ||
2462 | * in page->private, must be called before reuse_swap_page(), | ||
2463 | * which may delete_from_swap_cache(). | ||
2464 | */ | ||
2453 | 2465 | ||
2466 | mem_cgroup_commit_charge_swapin(page, ptr); | ||
2454 | inc_mm_counter(mm, anon_rss); | 2467 | inc_mm_counter(mm, anon_rss); |
2455 | pte = mk_pte(page, vma->vm_page_prot); | 2468 | pte = mk_pte(page, vma->vm_page_prot); |
2456 | if (write_access && reuse_swap_page(page)) { | 2469 | if (write_access && reuse_swap_page(page)) { |
@@ -2461,7 +2474,6 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2461 | flush_icache_page(vma, page); | 2474 | flush_icache_page(vma, page); |
2462 | set_pte_at(mm, address, page_table, pte); | 2475 | set_pte_at(mm, address, page_table, pte); |
2463 | page_add_anon_rmap(page, vma, address); | 2476 | page_add_anon_rmap(page, vma, address); |
2464 | mem_cgroup_commit_charge_swapin(page, ptr); | ||
2465 | 2477 | ||
2466 | swap_free(entry); | 2478 | swap_free(entry); |
2467 | if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page)) | 2479 | if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page)) |