diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2014-08-06 19:05:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-06 21:01:17 -0400 |
commit | 9476db974d9e18885123fcebc09f4596bb922e5f (patch) | |
tree | 70701f82e65c98a0ee5314d0eb3da9863e0f2091 /mm/memcontrol.c | |
parent | 0029e19ebf84dcd70b226820daa7747b28d5956d (diff) |
mm: memcontrol: simplify move precharge function
The move precharge function does some baroque things: it tries raw
res_counter charging of the entire amount first, and then falls back to
a loop of one-by-one charges, with checks for pending signals and
cond_resched() batching.
Just use mem_cgroup_try_charge() without __GFP_WAIT for the first bulk
charge attempt. In the one-by-one loop, remove the signal check (this
is already checked in try_charge), and simply call cond_resched() after
every charge - it's not that expensive.
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Michal Hocko <mhocko@suse.cz>
Cc: Hugh Dickins <hughd@google.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Vladimir Davydov <vdavydov@parallels.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 48 |
1 files changed, 15 insertions, 33 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 8aaca8267dfe..8a4159efa3c0 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -6385,56 +6385,38 @@ static void mem_cgroup_css_reset(struct cgroup_subsys_state *css) | |||
6385 | 6385 | ||
6386 | #ifdef CONFIG_MMU | 6386 | #ifdef CONFIG_MMU |
6387 | /* Handlers for move charge at task migration. */ | 6387 | /* Handlers for move charge at task migration. */ |
6388 | #define PRECHARGE_COUNT_AT_ONCE 256 | ||
6389 | static int mem_cgroup_do_precharge(unsigned long count) | 6388 | static int mem_cgroup_do_precharge(unsigned long count) |
6390 | { | 6389 | { |
6391 | int ret = 0; | 6390 | int ret = 0; |
6392 | int batch_count = PRECHARGE_COUNT_AT_ONCE; | ||
6393 | struct mem_cgroup *memcg = mc.to; | ||
6394 | 6391 | ||
6395 | if (mem_cgroup_is_root(memcg)) { | 6392 | if (mem_cgroup_is_root(mc.to)) { |
6396 | mc.precharge += count; | 6393 | mc.precharge += count; |
6397 | /* we don't need css_get for root */ | 6394 | /* we don't need css_get for root */ |
6398 | return ret; | 6395 | return ret; |
6399 | } | 6396 | } |
6400 | /* try to charge at once */ | 6397 | |
6401 | if (count > 1) { | 6398 | /* Try a single bulk charge without reclaim first */ |
6402 | struct res_counter *dummy; | 6399 | ret = mem_cgroup_try_charge(mc.to, GFP_KERNEL & ~__GFP_WAIT, count); |
6403 | /* | 6400 | if (!ret) { |
6404 | * "memcg" cannot be under rmdir() because we've already checked | ||
6405 | * by cgroup_lock_live_cgroup() that it is not removed and we | ||
6406 | * are still under the same cgroup_mutex. So we can postpone | ||
6407 | * css_get(). | ||
6408 | */ | ||
6409 | if (res_counter_charge(&memcg->res, PAGE_SIZE * count, &dummy)) | ||
6410 | goto one_by_one; | ||
6411 | if (do_swap_account && res_counter_charge(&memcg->memsw, | ||
6412 | PAGE_SIZE * count, &dummy)) { | ||
6413 | res_counter_uncharge(&memcg->res, PAGE_SIZE * count); | ||
6414 | goto one_by_one; | ||
6415 | } | ||
6416 | mc.precharge += count; | 6401 | mc.precharge += count; |
6417 | return ret; | 6402 | return ret; |
6418 | } | 6403 | } |
6419 | one_by_one: | 6404 | |
6420 | /* fall back to one by one charge */ | 6405 | /* Try charges one by one with reclaim */ |
6421 | while (count--) { | 6406 | while (count--) { |
6422 | if (signal_pending(current)) { | 6407 | ret = mem_cgroup_try_charge(mc.to, |
6423 | ret = -EINTR; | ||
6424 | break; | ||
6425 | } | ||
6426 | if (!batch_count--) { | ||
6427 | batch_count = PRECHARGE_COUNT_AT_ONCE; | ||
6428 | cond_resched(); | ||
6429 | } | ||
6430 | ret = mem_cgroup_try_charge(memcg, | ||
6431 | GFP_KERNEL & ~__GFP_NORETRY, 1); | 6408 | GFP_KERNEL & ~__GFP_NORETRY, 1); |
6409 | /* | ||
6410 | * In case of failure, any residual charges against | ||
6411 | * mc.to will be dropped by mem_cgroup_clear_mc() | ||
6412 | * later on. | ||
6413 | */ | ||
6432 | if (ret) | 6414 | if (ret) |
6433 | /* mem_cgroup_clear_mc() will do uncharge later */ | ||
6434 | return ret; | 6415 | return ret; |
6435 | mc.precharge++; | 6416 | mc.precharge++; |
6417 | cond_resched(); | ||
6436 | } | 6418 | } |
6437 | return ret; | 6419 | return 0; |
6438 | } | 6420 | } |
6439 | 6421 | ||
6440 | /** | 6422 | /** |