diff options
| -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 | /* |
