diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index f4ec4e7ca4cd..930de9437271 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -2091,6 +2091,7 @@ struct memcg_stock_pcp { | |||
2091 | #define FLUSHING_CACHED_CHARGE (0) | 2091 | #define FLUSHING_CACHED_CHARGE (0) |
2092 | }; | 2092 | }; |
2093 | static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); | 2093 | static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); |
2094 | static DEFINE_MUTEX(percpu_charge_mutex); | ||
2094 | 2095 | ||
2095 | /* | 2096 | /* |
2096 | * Try to consume stocked charge on this cpu. If success, one page is consumed | 2097 | * Try to consume stocked charge on this cpu. If success, one page is consumed |
@@ -2197,8 +2198,7 @@ static void drain_all_stock(struct mem_cgroup *root_mem, bool sync) | |||
2197 | 2198 | ||
2198 | for_each_online_cpu(cpu) { | 2199 | for_each_online_cpu(cpu) { |
2199 | struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu); | 2200 | struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu); |
2200 | if (mem_cgroup_same_or_subtree(root_mem, stock->cached) && | 2201 | if (test_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) |
2201 | test_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) | ||
2202 | flush_work(&stock->work); | 2202 | flush_work(&stock->work); |
2203 | } | 2203 | } |
2204 | out: | 2204 | out: |
@@ -2213,14 +2213,22 @@ out: | |||
2213 | */ | 2213 | */ |
2214 | static void drain_all_stock_async(struct mem_cgroup *root_mem) | 2214 | static void drain_all_stock_async(struct mem_cgroup *root_mem) |
2215 | { | 2215 | { |
2216 | /* | ||
2217 | * If someone calls draining, avoid adding more kworker runs. | ||
2218 | */ | ||
2219 | if (!mutex_trylock(&percpu_charge_mutex)) | ||
2220 | return; | ||
2216 | drain_all_stock(root_mem, false); | 2221 | drain_all_stock(root_mem, false); |
2222 | mutex_unlock(&percpu_charge_mutex); | ||
2217 | } | 2223 | } |
2218 | 2224 | ||
2219 | /* This is a synchronous drain interface. */ | 2225 | /* This is a synchronous drain interface. */ |
2220 | static void drain_all_stock_sync(struct mem_cgroup *root_mem) | 2226 | static void drain_all_stock_sync(struct mem_cgroup *root_mem) |
2221 | { | 2227 | { |
2222 | /* called when force_empty is called */ | 2228 | /* called when force_empty is called */ |
2229 | mutex_lock(&percpu_charge_mutex); | ||
2223 | drain_all_stock(root_mem, true); | 2230 | drain_all_stock(root_mem, true); |
2231 | mutex_unlock(&percpu_charge_mutex); | ||
2224 | } | 2232 | } |
2225 | 2233 | ||
2226 | /* | 2234 | /* |