aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorJohannes Weiner <jweiner@redhat.com>2011-08-25 18:59:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-08-25 19:25:33 -0400
commit5af12d0efdbd9967cc71a0a10c4025c4255a6254 (patch)
treee5e036671dc7ae02bebaf201126d6c19104e02d1 /mm
parenta801876638c5ce650223476c4eb8f37cea32dc1c (diff)
memcg: pin execution to current cpu while draining stock
Commit d1a05b6973c7 ("memcg do not try to drain per-cpu caches without pages") added a drain_local_stock() call to a preemptible section. The draining task looks up the cpu-local stock twice to set the draining-flag, then to drain the stock and clear the flag again. If the task is migrated to a different CPU in between, noone will clear the flag on the first stock and it will be forever undrainable. Its charge can not be recovered and the cgroup can not be deleted anymore. Properly pin the task to the executing CPU while draining stocks. Signed-off-by: Johannes Weiner <jweiner@redhat.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com 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.c9
1 files changed, 2 insertions, 7 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 930de9437271..0e40f0205732 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2169,13 +2169,7 @@ static void drain_all_stock(struct mem_cgroup *root_mem, bool sync)
2169 2169
2170 /* Notify other cpus that system-wide "drain" is running */ 2170 /* Notify other cpus that system-wide "drain" is running */
2171 get_online_cpus(); 2171 get_online_cpus();
2172 /* 2172 curcpu = get_cpu();
2173 * Get a hint for avoiding draining charges on the current cpu,
2174 * which must be exhausted by our charging. It is not required that
2175 * this be a precise check, so we use raw_smp_processor_id() instead of
2176 * getcpu()/putcpu().
2177 */
2178 curcpu = raw_smp_processor_id();
2179 for_each_online_cpu(cpu) { 2173 for_each_online_cpu(cpu) {
2180 struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu); 2174 struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu);
2181 struct mem_cgroup *mem; 2175 struct mem_cgroup *mem;
@@ -2192,6 +2186,7 @@ static void drain_all_stock(struct mem_cgroup *root_mem, bool sync)
2192 schedule_work_on(cpu, &stock->work); 2186 schedule_work_on(cpu, &stock->work);
2193 } 2187 }
2194 } 2188 }
2189 put_cpu();
2195 2190
2196 if (!sync) 2191 if (!sync)
2197 goto out; 2192 goto out;