diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2011-03-23 19:42:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-23 22:46:29 -0400 |
commit | 11c9ea4e80fc3be83485667204c68d0a732f3757 (patch) | |
tree | 71f68fb56e427c3ebe12e205e6ea56d72e7bd6ea /mm | |
parent | e7018b8d27e0c9aa2200e5b393e0fe9093c6565c (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.c | 24 |
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) |
1651 | struct memcg_stock_pcp { | 1651 | struct 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 | }; |
1656 | static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); | 1656 | static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); |
1657 | static atomic_t memcg_drain_count; | 1657 | static 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 | */ |
1709 | static void refill_stock(struct mem_cgroup *mem, int val) | 1711 | static 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); |
2017 | done: | 2019 | done: |
2018 | *memcg = mem; | 2020 | *memcg = mem; |