aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorSuleiman Souhlal <ssouhlal@FreeBSD.org>2012-12-18 17:21:36 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 18:02:12 -0500
commita0956d54492eb7257b09230680a8812b42cdee92 (patch)
treee0faecd5b7a22fe254654e09e87dca946ade0402 /mm
parentc2974058a9caa82c9dd9e1e11e4f2c6ce42ff17e (diff)
memcg: make it possible to use the stock for more than one page
We currently have a percpu stock cache scheme that charges one page at a time from memcg->res, the user counter. When the kernel memory controller comes into play, we'll need to charge more than that. This is because kernel memory allocations will also draw from the user counter, and can be bigger than a single page, as it is the case with the stack (usually 2 pages) or some higher order slabs. [glommer@parallels.com: added a changelog ] Signed-off-by: Suleiman Souhlal <suleiman@google.com> Signed-off-by: Glauber Costa <glommer@parallels.com> Acked-by: David Rientjes <rientjes@google.com> Acked-by: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Acked-by: Michal Hocko <mhocko@suse.cz> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Tejun Heo <tj@kernel.org> Cc: Christoph Lameter <cl@linux.com> Cc: Frederic Weisbecker <fweisbec@redhat.com> Cc: Greg Thelen <gthelen@google.com> Cc: JoonSoo Kim <js1304@gmail.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Pekka Enberg <penberg@cs.helsinki.fi> Cc: Rik van Riel <riel@redhat.com> Cc: Suleiman Souhlal <suleiman@google.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.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index bbfac5063ca..92887b28624 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2060,20 +2060,28 @@ struct memcg_stock_pcp {
2060static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); 2060static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock);
2061static DEFINE_MUTEX(percpu_charge_mutex); 2061static DEFINE_MUTEX(percpu_charge_mutex);
2062 2062
2063/* 2063/**
2064 * Try to consume stocked charge on this cpu. If success, one page is consumed 2064 * consume_stock: Try to consume stocked charge on this cpu.
2065 * from local stock and true is returned. If the stock is 0 or charges from a 2065 * @memcg: memcg to consume from.
2066 * cgroup which is not current target, returns false. This stock will be 2066 * @nr_pages: how many pages to charge.
2067 * refilled. 2067 *
2068 * The charges will only happen if @memcg matches the current cpu's memcg
2069 * stock, and at least @nr_pages are available in that stock. Failure to
2070 * service an allocation will refill the stock.
2071 *
2072 * returns true if successful, false otherwise.
2068 */ 2073 */
2069static bool consume_stock(struct mem_cgroup *memcg) 2074static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages)
2070{ 2075{
2071 struct memcg_stock_pcp *stock; 2076 struct memcg_stock_pcp *stock;
2072 bool ret = true; 2077 bool ret = true;
2073 2078
2079 if (nr_pages > CHARGE_BATCH)
2080 return false;
2081
2074 stock = &get_cpu_var(memcg_stock); 2082 stock = &get_cpu_var(memcg_stock);
2075 if (memcg == stock->cached && stock->nr_pages) 2083 if (memcg == stock->cached && stock->nr_pages >= nr_pages)
2076 stock->nr_pages--; 2084 stock->nr_pages -= nr_pages;
2077 else /* need to call res_counter_charge */ 2085 else /* need to call res_counter_charge */
2078 ret = false; 2086 ret = false;
2079 put_cpu_var(memcg_stock); 2087 put_cpu_var(memcg_stock);
@@ -2371,7 +2379,7 @@ again:
2371 memcg = *ptr; 2379 memcg = *ptr;
2372 if (mem_cgroup_is_root(memcg)) 2380 if (mem_cgroup_is_root(memcg))
2373 goto done; 2381 goto done;
2374 if (nr_pages == 1 && consume_stock(memcg)) 2382 if (consume_stock(memcg, nr_pages))
2375 goto done; 2383 goto done;
2376 css_get(&memcg->css); 2384 css_get(&memcg->css);
2377 } else { 2385 } else {
@@ -2396,7 +2404,7 @@ again:
2396 rcu_read_unlock(); 2404 rcu_read_unlock();
2397 goto done; 2405 goto done;
2398 } 2406 }
2399 if (nr_pages == 1 && consume_stock(memcg)) { 2407 if (consume_stock(memcg, nr_pages)) {
2400 /* 2408 /*
2401 * It seems dagerous to access memcg without css_get(). 2409 * It seems dagerous to access memcg without css_get().
2402 * But considering how consume_stok works, it's not 2410 * But considering how consume_stok works, it's not