aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c68
1 files changed, 32 insertions, 36 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 29bc4400378d..3be1afab8523 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2796,37 +2796,6 @@ int mem_cgroup_newpage_charge(struct page *page,
2796 MEM_CGROUP_CHARGE_TYPE_ANON); 2796 MEM_CGROUP_CHARGE_TYPE_ANON);
2797} 2797}
2798 2798
2799static void
2800__mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr,
2801 enum charge_type ctype);
2802
2803int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
2804 gfp_t gfp_mask)
2805{
2806 struct mem_cgroup *memcg = NULL;
2807 enum charge_type type = MEM_CGROUP_CHARGE_TYPE_CACHE;
2808 int ret;
2809
2810 if (mem_cgroup_disabled())
2811 return 0;
2812 if (PageCompound(page))
2813 return 0;
2814
2815 if (unlikely(!mm))
2816 mm = &init_mm;
2817 if (!page_is_file_cache(page))
2818 type = MEM_CGROUP_CHARGE_TYPE_SHMEM;
2819
2820 if (!PageSwapCache(page))
2821 ret = mem_cgroup_charge_common(page, mm, gfp_mask, type);
2822 else { /* page is swapcache/shmem */
2823 ret = mem_cgroup_try_charge_swapin(mm, page, gfp_mask, &memcg);
2824 if (!ret)
2825 __mem_cgroup_commit_charge_swapin(page, memcg, type);
2826 }
2827 return ret;
2828}
2829
2830/* 2799/*
2831 * While swap-in, try_charge -> commit or cancel, the page is locked. 2800 * While swap-in, try_charge -> commit or cancel, the page is locked.
2832 * And when try_charge() successfully returns, one refcnt to memcg without 2801 * And when try_charge() successfully returns, one refcnt to memcg without
@@ -2873,6 +2842,15 @@ charge_cur_mm:
2873 return ret; 2842 return ret;
2874} 2843}
2875 2844
2845void mem_cgroup_cancel_charge_swapin(struct mem_cgroup *memcg)
2846{
2847 if (mem_cgroup_disabled())
2848 return;
2849 if (!memcg)
2850 return;
2851 __mem_cgroup_cancel_charge(memcg, 1);
2852}
2853
2876static void 2854static void
2877__mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *memcg, 2855__mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *memcg,
2878 enum charge_type ctype) 2856 enum charge_type ctype)
@@ -2910,13 +2888,31 @@ void mem_cgroup_commit_charge_swapin(struct page *page,
2910 MEM_CGROUP_CHARGE_TYPE_ANON); 2888 MEM_CGROUP_CHARGE_TYPE_ANON);
2911} 2889}
2912 2890
2913void mem_cgroup_cancel_charge_swapin(struct mem_cgroup *memcg) 2891int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
2892 gfp_t gfp_mask)
2914{ 2893{
2894 struct mem_cgroup *memcg = NULL;
2895 enum charge_type type = MEM_CGROUP_CHARGE_TYPE_CACHE;
2896 int ret;
2897
2915 if (mem_cgroup_disabled()) 2898 if (mem_cgroup_disabled())
2916 return; 2899 return 0;
2917 if (!memcg) 2900 if (PageCompound(page))
2918 return; 2901 return 0;
2919 __mem_cgroup_cancel_charge(memcg, 1); 2902
2903 if (unlikely(!mm))
2904 mm = &init_mm;
2905 if (!page_is_file_cache(page))
2906 type = MEM_CGROUP_CHARGE_TYPE_SHMEM;
2907
2908 if (!PageSwapCache(page))
2909 ret = mem_cgroup_charge_common(page, mm, gfp_mask, type);
2910 else { /* page is swapcache/shmem */
2911 ret = mem_cgroup_try_charge_swapin(mm, page, gfp_mask, &memcg);
2912 if (!ret)
2913 __mem_cgroup_commit_charge_swapin(page, memcg, type);
2914 }
2915 return ret;
2920} 2916}
2921 2917
2922static void mem_cgroup_do_uncharge(struct mem_cgroup *memcg, 2918static void mem_cgroup_do_uncharge(struct mem_cgroup *memcg,