diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2014-08-06 19:05:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-06 21:01:17 -0400 |
commit | 06b078fc065fe1fe7097675c8ee416aa2ef94fb3 (patch) | |
tree | 749a33193bae4b45994df23e67f4656d70eceeb9 /mm/memcontrol.c | |
parent | 6539cc053869bd32a2db731b215b7c73b11f68d3 (diff) |
mm: memcontrol: rearrange charging fast path
The charging path currently starts out with OOM condition checks when
OOM is the rarest possible case.
Rearrange this code to run OOM/task dying checks only after trying the
percpu charge and the res_counter charge and bail out before entering
reclaim. Attempting a charge does not hurt an (oom-)killed task as much
as every charge attempt having to check OOM conditions. Also, only
check __GFP_NOFAIL when the charge would actually fail.
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 | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index fe3ad310656d..f7b6bec9f538 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -2575,22 +2575,6 @@ static int mem_cgroup_try_charge(struct mem_cgroup *memcg, | |||
2575 | 2575 | ||
2576 | if (mem_cgroup_is_root(memcg)) | 2576 | if (mem_cgroup_is_root(memcg)) |
2577 | goto done; | 2577 | goto done; |
2578 | /* | ||
2579 | * Unlike in global OOM situations, memcg is not in a physical | ||
2580 | * memory shortage. Allow dying and OOM-killed tasks to | ||
2581 | * bypass the last charges so that they can exit quickly and | ||
2582 | * free their memory. | ||
2583 | */ | ||
2584 | if (unlikely(test_thread_flag(TIF_MEMDIE) || | ||
2585 | fatal_signal_pending(current) || | ||
2586 | current->flags & PF_EXITING)) | ||
2587 | goto bypass; | ||
2588 | |||
2589 | if (unlikely(task_in_memcg_oom(current))) | ||
2590 | goto nomem; | ||
2591 | |||
2592 | if (gfp_mask & __GFP_NOFAIL) | ||
2593 | oom = false; | ||
2594 | retry: | 2578 | retry: |
2595 | if (consume_stock(memcg, nr_pages)) | 2579 | if (consume_stock(memcg, nr_pages)) |
2596 | goto done; | 2580 | goto done; |
@@ -2612,6 +2596,20 @@ retry: | |||
2612 | goto retry; | 2596 | goto retry; |
2613 | } | 2597 | } |
2614 | 2598 | ||
2599 | /* | ||
2600 | * Unlike in global OOM situations, memcg is not in a physical | ||
2601 | * memory shortage. Allow dying and OOM-killed tasks to | ||
2602 | * bypass the last charges so that they can exit quickly and | ||
2603 | * free their memory. | ||
2604 | */ | ||
2605 | if (unlikely(test_thread_flag(TIF_MEMDIE) || | ||
2606 | fatal_signal_pending(current) || | ||
2607 | current->flags & PF_EXITING)) | ||
2608 | goto bypass; | ||
2609 | |||
2610 | if (unlikely(task_in_memcg_oom(current))) | ||
2611 | goto nomem; | ||
2612 | |||
2615 | if (!(gfp_mask & __GFP_WAIT)) | 2613 | if (!(gfp_mask & __GFP_WAIT)) |
2616 | goto nomem; | 2614 | goto nomem; |
2617 | 2615 | ||
@@ -2640,6 +2638,9 @@ retry: | |||
2640 | if (mem_cgroup_wait_acct_move(mem_over_limit)) | 2638 | if (mem_cgroup_wait_acct_move(mem_over_limit)) |
2641 | goto retry; | 2639 | goto retry; |
2642 | 2640 | ||
2641 | if (gfp_mask & __GFP_NOFAIL) | ||
2642 | goto bypass; | ||
2643 | |||
2643 | if (fatal_signal_pending(current)) | 2644 | if (fatal_signal_pending(current)) |
2644 | goto bypass; | 2645 | goto bypass; |
2645 | 2646 | ||