summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorHugh Dickins <hughd@google.com>2014-06-04 16:11:04 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 16:54:13 -0700
commit2a7a0e0fdc49a08740a69d51ef44ef09763072b0 (patch)
tree88d883113fd544867f6b67b4cea3ab663f88a831 /mm
parent4a0da71b96b9d4080c0820e9e7d02470ebe62dc6 (diff)
downloadkernel-common-2a7a0e0fdc49a08740a69d51ef44ef09763072b0.tar.gz
kernel-common-2a7a0e0fdc49a08740a69d51ef44ef09763072b0.tar.bz2
kernel-common-2a7a0e0fdc49a08740a69d51ef44ef09763072b0.zip
mm, memcg: periodically schedule when emptying page list
mem_cgroup_force_empty_list() can iterate a large number of pages on an lru and mem_cgroup_move_parent() doesn't return an errno unless certain criteria, none of which indicate that the iteration may be taking too long, is met. We have encountered the following stack trace many times indicating "need_resched set for > 51000020 ns (51 ticks) without schedule", for example: scheduler_tick() <timer irq> mem_cgroup_move_account+0x4d/0x1d5 mem_cgroup_move_parent+0x8d/0x109 mem_cgroup_reparent_charges+0x149/0x2ba mem_cgroup_css_offline+0xeb/0x11b cgroup_offline_fn+0x68/0x16b process_one_work+0x129/0x350 If this iteration is taking too long, we still need to do cond_resched() even when an individual page is not busy. [rientjes@google.com: changelog] Signed-off-by: Hugh Dickins <hughd@google.com> Signed-off-by: David Rientjes <rientjes@google.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Acked-by: Michal Hocko <mhocko@suse.cz> 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.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index d176edb1d5e8..a500cb0594c4 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4675,9 +4675,9 @@ static void mem_cgroup_force_empty_list(struct mem_cgroup *memcg,
if (mem_cgroup_move_parent(page, pc, memcg)) {
/* found lock contention or "pc" is obsolete. */
busy = page;
- cond_resched();
} else
busy = NULL;
+ cond_resched();
} while (!list_empty(list));
}