diff options
| -rw-r--r-- | mm/memcontrol.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 31a1d3b71eee..52840adae62a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
| @@ -1132,11 +1132,14 @@ static unsigned int get_swappiness(struct mem_cgroup *memcg) | |||
| 1132 | static void mem_cgroup_start_move(struct mem_cgroup *mem) | 1132 | static void mem_cgroup_start_move(struct mem_cgroup *mem) |
| 1133 | { | 1133 | { |
| 1134 | int cpu; | 1134 | int cpu; |
| 1135 | /* Because this is for moving account, reuse mc.lock */ | 1135 | |
| 1136 | spin_lock(&mc.lock); | 1136 | get_online_cpus(); |
| 1137 | for_each_possible_cpu(cpu) | 1137 | spin_lock(&mem->pcp_counter_lock); |
| 1138 | for_each_online_cpu(cpu) | ||
| 1138 | per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) += 1; | 1139 | per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) += 1; |
| 1139 | spin_unlock(&mc.lock); | 1140 | mem->nocpu_base.count[MEM_CGROUP_ON_MOVE] += 1; |
| 1141 | spin_unlock(&mem->pcp_counter_lock); | ||
| 1142 | put_online_cpus(); | ||
| 1140 | 1143 | ||
| 1141 | synchronize_rcu(); | 1144 | synchronize_rcu(); |
| 1142 | } | 1145 | } |
| @@ -1147,10 +1150,13 @@ static void mem_cgroup_end_move(struct mem_cgroup *mem) | |||
| 1147 | 1150 | ||
| 1148 | if (!mem) | 1151 | if (!mem) |
| 1149 | return; | 1152 | return; |
| 1150 | spin_lock(&mc.lock); | 1153 | get_online_cpus(); |
| 1151 | for_each_possible_cpu(cpu) | 1154 | spin_lock(&mem->pcp_counter_lock); |
| 1155 | for_each_online_cpu(cpu) | ||
| 1152 | per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) -= 1; | 1156 | per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) -= 1; |
| 1153 | spin_unlock(&mc.lock); | 1157 | mem->nocpu_base.count[MEM_CGROUP_ON_MOVE] -= 1; |
| 1158 | spin_unlock(&mem->pcp_counter_lock); | ||
| 1159 | put_online_cpus(); | ||
| 1154 | } | 1160 | } |
| 1155 | /* | 1161 | /* |
| 1156 | * 2 routines for checking "mem" is under move_account() or not. | 1162 | * 2 routines for checking "mem" is under move_account() or not. |
| @@ -1751,6 +1757,17 @@ static void mem_cgroup_drain_pcp_counter(struct mem_cgroup *mem, int cpu) | |||
| 1751 | per_cpu(mem->stat->count[i], cpu) = 0; | 1757 | per_cpu(mem->stat->count[i], cpu) = 0; |
| 1752 | mem->nocpu_base.count[i] += x; | 1758 | mem->nocpu_base.count[i] += x; |
| 1753 | } | 1759 | } |
| 1760 | /* need to clear ON_MOVE value, works as a kind of lock. */ | ||
| 1761 | per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) = 0; | ||
| 1762 | spin_unlock(&mem->pcp_counter_lock); | ||
| 1763 | } | ||
| 1764 | |||
| 1765 | static void synchronize_mem_cgroup_on_move(struct mem_cgroup *mem, int cpu) | ||
| 1766 | { | ||
| 1767 | int idx = MEM_CGROUP_ON_MOVE; | ||
| 1768 | |||
| 1769 | spin_lock(&mem->pcp_counter_lock); | ||
| 1770 | per_cpu(mem->stat->count[idx], cpu) = mem->nocpu_base.count[idx]; | ||
| 1754 | spin_unlock(&mem->pcp_counter_lock); | 1771 | spin_unlock(&mem->pcp_counter_lock); |
| 1755 | } | 1772 | } |
| 1756 | 1773 | ||
| @@ -1762,6 +1779,12 @@ static int __cpuinit memcg_cpu_hotplug_callback(struct notifier_block *nb, | |||
| 1762 | struct memcg_stock_pcp *stock; | 1779 | struct memcg_stock_pcp *stock; |
| 1763 | struct mem_cgroup *iter; | 1780 | struct mem_cgroup *iter; |
| 1764 | 1781 | ||
| 1782 | if ((action == CPU_ONLINE)) { | ||
| 1783 | for_each_mem_cgroup_all(iter) | ||
| 1784 | synchronize_mem_cgroup_on_move(iter, cpu); | ||
| 1785 | return NOTIFY_OK; | ||
| 1786 | } | ||
| 1787 | |||
| 1765 | if ((action != CPU_DEAD) || action != CPU_DEAD_FROZEN) | 1788 | if ((action != CPU_DEAD) || action != CPU_DEAD_FROZEN) |
| 1766 | return NOTIFY_OK; | 1789 | return NOTIFY_OK; |
| 1767 | 1790 | ||
