diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 68 |
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 | ||
2799 | static void | ||
2800 | __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr, | ||
2801 | enum charge_type ctype); | ||
2802 | |||
2803 | int 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 | ||
2845 | void 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 | |||
2876 | static void | 2854 | static 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 | ||
2913 | void mem_cgroup_cancel_charge_swapin(struct mem_cgroup *memcg) | 2891 | int 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 | ||
2922 | static void mem_cgroup_do_uncharge(struct mem_cgroup *memcg, | 2918 | static void mem_cgroup_do_uncharge(struct mem_cgroup *memcg, |