aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2011-03-23 19:42:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-23 22:46:29 -0400
commit11c9ea4e80fc3be83485667204c68d0a732f3757 (patch)
tree71f68fb56e427c3ebe12e205e6ea56d72e7bd6ea /mm
parente7018b8d27e0c9aa2200e5b393e0fe9093c6565c (diff)
memcg: convert per-cpu stock from bytes to page granularity
We never keep subpage quantities in the per-cpu stock. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Cc: Balbir Singh <balbir@linux.vnet.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 09a450684f70..91120a04f935 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1650,14 +1650,14 @@ EXPORT_SYMBOL(mem_cgroup_update_page_stat);
1650#define CHARGE_SIZE (32 * PAGE_SIZE) 1650#define CHARGE_SIZE (32 * PAGE_SIZE)
1651struct memcg_stock_pcp { 1651struct memcg_stock_pcp {
1652 struct mem_cgroup *cached; /* this never be root cgroup */ 1652 struct mem_cgroup *cached; /* this never be root cgroup */
1653 int charge; 1653 unsigned int nr_pages;
1654 struct work_struct work; 1654 struct work_struct work;
1655}; 1655};
1656static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); 1656static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock);
1657static atomic_t memcg_drain_count; 1657static atomic_t memcg_drain_count;
1658 1658
1659/* 1659/*
1660 * Try to consume stocked charge on this cpu. If success, PAGE_SIZE is consumed 1660 * Try to consume stocked charge on this cpu. If success, one page is consumed
1661 * from local stock and true is returned. If the stock is 0 or charges from a 1661 * from local stock and true is returned. If the stock is 0 or charges from a
1662 * cgroup which is not current target, returns false. This stock will be 1662 * cgroup which is not current target, returns false. This stock will be
1663 * refilled. 1663 * refilled.
@@ -1668,8 +1668,8 @@ static bool consume_stock(struct mem_cgroup *mem)
1668 bool ret = true; 1668 bool ret = true;
1669 1669
1670 stock = &get_cpu_var(memcg_stock); 1670 stock = &get_cpu_var(memcg_stock);
1671 if (mem == stock->cached && stock->charge) 1671 if (mem == stock->cached && stock->nr_pages)
1672 stock->charge -= PAGE_SIZE; 1672 stock->nr_pages--;
1673 else /* need to call res_counter_charge */ 1673 else /* need to call res_counter_charge */
1674 ret = false; 1674 ret = false;
1675 put_cpu_var(memcg_stock); 1675 put_cpu_var(memcg_stock);
@@ -1683,13 +1683,15 @@ static void drain_stock(struct memcg_stock_pcp *stock)
1683{ 1683{
1684 struct mem_cgroup *old = stock->cached; 1684 struct mem_cgroup *old = stock->cached;
1685 1685
1686 if (stock->charge) { 1686 if (stock->nr_pages) {
1687 res_counter_uncharge(&old->res, stock->charge); 1687 unsigned long bytes = stock->nr_pages * PAGE_SIZE;
1688
1689 res_counter_uncharge(&old->res, bytes);
1688 if (do_swap_account) 1690 if (do_swap_account)
1689 res_counter_uncharge(&old->memsw, stock->charge); 1691 res_counter_uncharge(&old->memsw, bytes);
1692 stock->nr_pages = 0;
1690 } 1693 }
1691 stock->cached = NULL; 1694 stock->cached = NULL;
1692 stock->charge = 0;
1693} 1695}
1694 1696
1695/* 1697/*
@@ -1706,7 +1708,7 @@ static void drain_local_stock(struct work_struct *dummy)
1706 * Cache charges(val) which is from res_counter, to local per_cpu area. 1708 * Cache charges(val) which is from res_counter, to local per_cpu area.
1707 * This will be consumed by consume_stock() function, later. 1709 * This will be consumed by consume_stock() function, later.
1708 */ 1710 */
1709static void refill_stock(struct mem_cgroup *mem, int val) 1711static void refill_stock(struct mem_cgroup *mem, unsigned int nr_pages)
1710{ 1712{
1711 struct memcg_stock_pcp *stock = &get_cpu_var(memcg_stock); 1713 struct memcg_stock_pcp *stock = &get_cpu_var(memcg_stock);
1712 1714
@@ -1714,7 +1716,7 @@ static void refill_stock(struct mem_cgroup *mem, int val)
1714 drain_stock(stock); 1716 drain_stock(stock);
1715 stock->cached = mem; 1717 stock->cached = mem;
1716 } 1718 }
1717 stock->charge += val; 1719 stock->nr_pages += nr_pages;
1718 put_cpu_var(memcg_stock); 1720 put_cpu_var(memcg_stock);
1719} 1721}
1720 1722
@@ -2012,7 +2014,7 @@ again:
2012 } while (ret != CHARGE_OK); 2014 } while (ret != CHARGE_OK);
2013 2015
2014 if (csize > page_size) 2016 if (csize > page_size)
2015 refill_stock(mem, csize - page_size); 2017 refill_stock(mem, (csize - page_size) >> PAGE_SHIFT);
2016 css_put(&mem->css); 2018 css_put(&mem->css);
2017done: 2019done:
2018 *memcg = mem; 2020 *memcg = mem;