From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> An event counter MEM_CGROUP_ON_MOVE is used for quick check whether file stat update can be done in async manner or not. Now, it use percpu counter and for_each_possible_cpu to update. This patch replaces for_each_possible_cpu to for_each_online_cpu and adds necessary synchronization logic at CPU HOTPLUG. Changelog: - make use of cpu independent "core" value to synchronize. - replaces mc.lock with pcp_coutner_lock. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> --- mm/memcontrol.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) Index: mmotm-0915/mm/memcontrol.c =================================================================== --- mmotm-0915.orig/mm/memcontrol.c +++ mmotm-0915/mm/memcontrol.c @@ -1116,11 +1116,14 @@ static unsigned int get_swappiness(struc static void mem_cgroup_start_move(struct mem_cgroup *mem) { int cpu; - /* Because this is for moving account, reuse mc.lock */ - spin_lock(&mc.lock); - for_each_possible_cpu(cpu) + + get_online_cpus(); + spin_lock(&mem->pcp_counter_lock); + for_each_online_cpu(cpu) per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) += 1; - spin_unlock(&mc.lock); + mem->nocpu_base.count[MEM_CGROUP_ON_MOVE] += 1; + spin_unlock(&mem->pcp_counter_lock); + put_online_cpus(); synchronize_rcu(); } @@ -1131,10 +1134,13 @@ static void mem_cgroup_end_move(struct m if (!mem) return; - spin_lock(&mc.lock); - for_each_possible_cpu(cpu) + get_online_cpus(); + spin_lock(&mem->pcp_counter_lock); + for_each_online_cpu(cpu) per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) -= 1; - spin_unlock(&mc.lock); + mem->nocpu_base.count[MEM_CGROUP_ON_MOVE] -= 1; + spin_unlock(&mem->pcp_counter_lock); + put_online_cpus(); } /* * 2 routines for checking "mem" is under move_account() or not. @@ -1735,6 +1741,17 @@ static void mem_cgroup_drain_pcp_counter per_cpu(mem->stat->count[i], cpu) = 0; mem->nocpu_base.count[i] += x; } + /* need to clear ON_MOVE value, works as a kind of lock. */ + per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE],cpu) = 0; + spin_unlock(&mem->pcp_counter_lock); +} + +static void synchronize_mem_cgroup_on_move(struct mem_cgroup *mem, int cpu) +{ + int idx = MEM_CGROUP_ON_MOVE; + + spin_lock(&mem->pcp_counter_lock); + per_cpu(mem->stat->count[idx],cpu) = mem->nocpu_base.count[idx]; spin_unlock(&mem->pcp_counter_lock); } @@ -1746,6 +1763,12 @@ static int __cpuinit memcg_cpu_hotplug_c struct memcg_stock_pcp *stock; struct mem_cgroup *iter; + if ((action == CPU_ONLINE)) { + for_each_mem_cgroup_all(iter) + synchronize_mem_cgroup_on_move(iter, cpu); + return NOTIFY_OK; + } + if ((action != CPU_DEAD) || action != CPU_DEAD_FROZEN) return NOTIFY_OK; -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxxx For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>