diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index da53a252b259..e1ee6ad9c971 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -829,6 +829,32 @@ void mem_cgroup_del_lru(struct page *page) | |||
829 | mem_cgroup_del_lru_list(page, page_lru(page)); | 829 | mem_cgroup_del_lru_list(page, page_lru(page)); |
830 | } | 830 | } |
831 | 831 | ||
832 | /* | ||
833 | * Writeback is about to end against a page which has been marked for immediate | ||
834 | * reclaim. If it still appears to be reclaimable, move it to the tail of the | ||
835 | * inactive list. | ||
836 | */ | ||
837 | void mem_cgroup_rotate_reclaimable_page(struct page *page) | ||
838 | { | ||
839 | struct mem_cgroup_per_zone *mz; | ||
840 | struct page_cgroup *pc; | ||
841 | enum lru_list lru = page_lru(page); | ||
842 | |||
843 | if (mem_cgroup_disabled()) | ||
844 | return; | ||
845 | |||
846 | pc = lookup_page_cgroup(page); | ||
847 | /* unused or root page is not rotated. */ | ||
848 | if (!PageCgroupUsed(pc)) | ||
849 | return; | ||
850 | /* Ensure pc->mem_cgroup is visible after reading PCG_USED. */ | ||
851 | smp_rmb(); | ||
852 | if (mem_cgroup_is_root(pc->mem_cgroup)) | ||
853 | return; | ||
854 | mz = page_cgroup_zoneinfo(pc); | ||
855 | list_move_tail(&pc->lru, &mz->lists[lru]); | ||
856 | } | ||
857 | |||
832 | void mem_cgroup_rotate_lru_list(struct page *page, enum lru_list lru) | 858 | void mem_cgroup_rotate_lru_list(struct page *page, enum lru_list lru) |
833 | { | 859 | { |
834 | struct mem_cgroup_per_zone *mz; | 860 | struct mem_cgroup_per_zone *mz; |
@@ -2883,7 +2909,7 @@ static inline int mem_cgroup_move_swap_account(swp_entry_t entry, | |||
2883 | * page belongs to. | 2909 | * page belongs to. |
2884 | */ | 2910 | */ |
2885 | int mem_cgroup_prepare_migration(struct page *page, | 2911 | int mem_cgroup_prepare_migration(struct page *page, |
2886 | struct page *newpage, struct mem_cgroup **ptr) | 2912 | struct page *newpage, struct mem_cgroup **ptr, gfp_t gfp_mask) |
2887 | { | 2913 | { |
2888 | struct page_cgroup *pc; | 2914 | struct page_cgroup *pc; |
2889 | struct mem_cgroup *mem = NULL; | 2915 | struct mem_cgroup *mem = NULL; |
@@ -2940,7 +2966,7 @@ int mem_cgroup_prepare_migration(struct page *page, | |||
2940 | return 0; | 2966 | return 0; |
2941 | 2967 | ||
2942 | *ptr = mem; | 2968 | *ptr = mem; |
2943 | ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, ptr, false, PAGE_SIZE); | 2969 | ret = __mem_cgroup_try_charge(NULL, gfp_mask, ptr, false, PAGE_SIZE); |
2944 | css_put(&mem->css);/* drop extra refcnt */ | 2970 | css_put(&mem->css);/* drop extra refcnt */ |
2945 | if (ret || *ptr == NULL) { | 2971 | if (ret || *ptr == NULL) { |
2946 | if (PageAnon(page)) { | 2972 | if (PageAnon(page)) { |
@@ -4737,7 +4763,8 @@ static int mem_cgroup_count_precharge_pte_range(pmd_t *pmd, | |||
4737 | pte_t *pte; | 4763 | pte_t *pte; |
4738 | spinlock_t *ptl; | 4764 | spinlock_t *ptl; |
4739 | 4765 | ||
4740 | VM_BUG_ON(pmd_trans_huge(*pmd)); | 4766 | split_huge_page_pmd(walk->mm, pmd); |
4767 | |||
4741 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); | 4768 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); |
4742 | for (; addr != end; pte++, addr += PAGE_SIZE) | 4769 | for (; addr != end; pte++, addr += PAGE_SIZE) |
4743 | if (is_target_pte_for_mc(vma, addr, *pte, NULL)) | 4770 | if (is_target_pte_for_mc(vma, addr, *pte, NULL)) |
@@ -4899,8 +4926,8 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd, | |||
4899 | pte_t *pte; | 4926 | pte_t *pte; |
4900 | spinlock_t *ptl; | 4927 | spinlock_t *ptl; |
4901 | 4928 | ||
4929 | split_huge_page_pmd(walk->mm, pmd); | ||
4902 | retry: | 4930 | retry: |
4903 | VM_BUG_ON(pmd_trans_huge(*pmd)); | ||
4904 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); | 4931 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); |
4905 | for (; addr != end; addr += PAGE_SIZE) { | 4932 | for (; addr != end; addr += PAGE_SIZE) { |
4906 | pte_t ptent = *(pte++); | 4933 | pte_t ptent = *(pte++); |