Commit 11c9ea4e authored by Johannes Weiner's avatar Johannes Weiner Committed by Linus Torvalds

memcg: convert per-cpu stock from bytes to page granularity

We never keep subpage quantities in the per-cpu stock.
Signed-off-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
Acked-by: default avatarKAMEZAWA 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e7018b8d
...@@ -1650,14 +1650,14 @@ EXPORT_SYMBOL(mem_cgroup_update_page_stat); ...@@ -1650,14 +1650,14 @@ EXPORT_SYMBOL(mem_cgroup_update_page_stat);
#define CHARGE_SIZE (32 * PAGE_SIZE) #define CHARGE_SIZE (32 * PAGE_SIZE)
struct memcg_stock_pcp { struct memcg_stock_pcp {
struct mem_cgroup *cached; /* this never be root cgroup */ struct mem_cgroup *cached; /* this never be root cgroup */
int charge; unsigned int nr_pages;
struct work_struct work; struct work_struct work;
}; };
static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock);
static atomic_t memcg_drain_count; static atomic_t memcg_drain_count;
/* /*
* Try to consume stocked charge on this cpu. If success, PAGE_SIZE is consumed * Try to consume stocked charge on this cpu. If success, one page is consumed
* from local stock and true is returned. If the stock is 0 or charges from a * from local stock and true is returned. If the stock is 0 or charges from a
* cgroup which is not current target, returns false. This stock will be * cgroup which is not current target, returns false. This stock will be
* refilled. * refilled.
...@@ -1668,8 +1668,8 @@ static bool consume_stock(struct mem_cgroup *mem) ...@@ -1668,8 +1668,8 @@ static bool consume_stock(struct mem_cgroup *mem)
bool ret = true; bool ret = true;
stock = &get_cpu_var(memcg_stock); stock = &get_cpu_var(memcg_stock);
if (mem == stock->cached && stock->charge) if (mem == stock->cached && stock->nr_pages)
stock->charge -= PAGE_SIZE; stock->nr_pages--;
else /* need to call res_counter_charge */ else /* need to call res_counter_charge */
ret = false; ret = false;
put_cpu_var(memcg_stock); put_cpu_var(memcg_stock);
...@@ -1683,13 +1683,15 @@ static void drain_stock(struct memcg_stock_pcp *stock) ...@@ -1683,13 +1683,15 @@ static void drain_stock(struct memcg_stock_pcp *stock)
{ {
struct mem_cgroup *old = stock->cached; struct mem_cgroup *old = stock->cached;
if (stock->charge) { if (stock->nr_pages) {
res_counter_uncharge(&old->res, stock->charge); unsigned long bytes = stock->nr_pages * PAGE_SIZE;
res_counter_uncharge(&old->res, bytes);
if (do_swap_account) if (do_swap_account)
res_counter_uncharge(&old->memsw, stock->charge); res_counter_uncharge(&old->memsw, bytes);
stock->nr_pages = 0;
} }
stock->cached = NULL; stock->cached = NULL;
stock->charge = 0;
} }
/* /*
...@@ -1706,7 +1708,7 @@ static void drain_local_stock(struct work_struct *dummy) ...@@ -1706,7 +1708,7 @@ static void drain_local_stock(struct work_struct *dummy)
* Cache charges(val) which is from res_counter, to local per_cpu area. * Cache charges(val) which is from res_counter, to local per_cpu area.
* This will be consumed by consume_stock() function, later. * This will be consumed by consume_stock() function, later.
*/ */
static void refill_stock(struct mem_cgroup *mem, int val) static void refill_stock(struct mem_cgroup *mem, unsigned int nr_pages)
{ {
struct memcg_stock_pcp *stock = &get_cpu_var(memcg_stock); struct memcg_stock_pcp *stock = &get_cpu_var(memcg_stock);
...@@ -1714,7 +1716,7 @@ static void refill_stock(struct mem_cgroup *mem, int val) ...@@ -1714,7 +1716,7 @@ static void refill_stock(struct mem_cgroup *mem, int val)
drain_stock(stock); drain_stock(stock);
stock->cached = mem; stock->cached = mem;
} }
stock->charge += val; stock->nr_pages += nr_pages;
put_cpu_var(memcg_stock); put_cpu_var(memcg_stock);
} }
...@@ -2012,7 +2014,7 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm, ...@@ -2012,7 +2014,7 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
} while (ret != CHARGE_OK); } while (ret != CHARGE_OK);
if (csize > page_size) if (csize > page_size)
refill_stock(mem, csize - page_size); refill_stock(mem, (csize - page_size) >> PAGE_SHIFT);
css_put(&mem->css); css_put(&mem->css);
done: done:
*memcg = mem; *memcg = mem;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment