aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index b66512771167..7be9b35d7ffb 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -994,14 +994,15 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
994 if (pc->mem_cgroup != from) 994 if (pc->mem_cgroup != from)
995 goto out; 995 goto out;
996 996
997 css_put(&from->css);
998 res_counter_uncharge(&from->res, PAGE_SIZE); 997 res_counter_uncharge(&from->res, PAGE_SIZE);
999 mem_cgroup_charge_statistics(from, pc, false); 998 mem_cgroup_charge_statistics(from, pc, false);
1000 if (do_swap_account) 999 if (do_swap_account)
1001 res_counter_uncharge(&from->memsw, PAGE_SIZE); 1000 res_counter_uncharge(&from->memsw, PAGE_SIZE);
1001 css_put(&from->css);
1002
1003 css_get(&to->css);
1002 pc->mem_cgroup = to; 1004 pc->mem_cgroup = to;
1003 mem_cgroup_charge_statistics(to, pc, true); 1005 mem_cgroup_charge_statistics(to, pc, true);
1004 css_get(&to->css);
1005 ret = 0; 1006 ret = 0;
1006out: 1007out:
1007 unlock_page_cgroup(pc); 1008 unlock_page_cgroup(pc);
@@ -1034,8 +1035,10 @@ static int mem_cgroup_move_parent(struct page_cgroup *pc,
1034 if (ret || !parent) 1035 if (ret || !parent)
1035 return ret; 1036 return ret;
1036 1037
1037 if (!get_page_unless_zero(page)) 1038 if (!get_page_unless_zero(page)) {
1038 return -EBUSY; 1039 ret = -EBUSY;
1040 goto uncharge;
1041 }
1039 1042
1040 ret = isolate_lru_page(page); 1043 ret = isolate_lru_page(page);
1041 1044
@@ -1044,19 +1047,23 @@ static int mem_cgroup_move_parent(struct page_cgroup *pc,
1044 1047
1045 ret = mem_cgroup_move_account(pc, child, parent); 1048 ret = mem_cgroup_move_account(pc, child, parent);
1046 1049
1047 /* drop extra refcnt by try_charge() (move_account increment one) */
1048 css_put(&parent->css);
1049 putback_lru_page(page); 1050 putback_lru_page(page);
1050 if (!ret) { 1051 if (!ret) {
1051 put_page(page); 1052 put_page(page);
1053 /* drop extra refcnt by try_charge() */
1054 css_put(&parent->css);
1052 return 0; 1055 return 0;
1053 } 1056 }
1054 /* uncharge if move fails */ 1057
1055cancel: 1058cancel:
1059 put_page(page);
1060uncharge:
1061 /* drop extra refcnt by try_charge() */
1062 css_put(&parent->css);
1063 /* uncharge if move fails */
1056 res_counter_uncharge(&parent->res, PAGE_SIZE); 1064 res_counter_uncharge(&parent->res, PAGE_SIZE);
1057 if (do_swap_account) 1065 if (do_swap_account)
1058 res_counter_uncharge(&parent->memsw, PAGE_SIZE); 1066 res_counter_uncharge(&parent->memsw, PAGE_SIZE);
1059 put_page(page);
1060 return ret; 1067 return ret;
1061} 1068}
1062 1069