diff options
-rw-r--r-- | mm/memcontrol.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index bbfac5063ca..92887b28624 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -2060,20 +2060,28 @@ struct memcg_stock_pcp { | |||
2060 | static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); | 2060 | static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); |
2061 | static DEFINE_MUTEX(percpu_charge_mutex); | 2061 | static DEFINE_MUTEX(percpu_charge_mutex); |
2062 | 2062 | ||
2063 | /* | 2063 | /** |
2064 | * Try to consume stocked charge on this cpu. If success, one page is consumed | 2064 | * consume_stock: Try to consume stocked charge on this cpu. |
2065 | * from local stock and true is returned. If the stock is 0 or charges from a | 2065 | * @memcg: memcg to consume from. |
2066 | * cgroup which is not current target, returns false. This stock will be | 2066 | * @nr_pages: how many pages to charge. |
2067 | * refilled. | 2067 | * |
2068 | * The charges will only happen if @memcg matches the current cpu's memcg | ||
2069 | * stock, and at least @nr_pages are available in that stock. Failure to | ||
2070 | * service an allocation will refill the stock. | ||
2071 | * | ||
2072 | * returns true if successful, false otherwise. | ||
2068 | */ | 2073 | */ |
2069 | static bool consume_stock(struct mem_cgroup *memcg) | 2074 | static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages) |
2070 | { | 2075 | { |
2071 | struct memcg_stock_pcp *stock; | 2076 | struct memcg_stock_pcp *stock; |
2072 | bool ret = true; | 2077 | bool ret = true; |
2073 | 2078 | ||
2079 | if (nr_pages > CHARGE_BATCH) | ||
2080 | return false; | ||
2081 | |||
2074 | stock = &get_cpu_var(memcg_stock); | 2082 | stock = &get_cpu_var(memcg_stock); |
2075 | if (memcg == stock->cached && stock->nr_pages) | 2083 | if (memcg == stock->cached && stock->nr_pages >= nr_pages) |
2076 | stock->nr_pages--; | 2084 | stock->nr_pages -= nr_pages; |
2077 | else /* need to call res_counter_charge */ | 2085 | else /* need to call res_counter_charge */ |
2078 | ret = false; | 2086 | ret = false; |
2079 | put_cpu_var(memcg_stock); | 2087 | put_cpu_var(memcg_stock); |
@@ -2371,7 +2379,7 @@ again: | |||
2371 | memcg = *ptr; | 2379 | memcg = *ptr; |
2372 | if (mem_cgroup_is_root(memcg)) | 2380 | if (mem_cgroup_is_root(memcg)) |
2373 | goto done; | 2381 | goto done; |
2374 | if (nr_pages == 1 && consume_stock(memcg)) | 2382 | if (consume_stock(memcg, nr_pages)) |
2375 | goto done; | 2383 | goto done; |
2376 | css_get(&memcg->css); | 2384 | css_get(&memcg->css); |
2377 | } else { | 2385 | } else { |
@@ -2396,7 +2404,7 @@ again: | |||
2396 | rcu_read_unlock(); | 2404 | rcu_read_unlock(); |
2397 | goto done; | 2405 | goto done; |
2398 | } | 2406 | } |
2399 | if (nr_pages == 1 && consume_stock(memcg)) { | 2407 | if (consume_stock(memcg, nr_pages)) { |
2400 | /* | 2408 | /* |
2401 | * It seems dagerous to access memcg without css_get(). | 2409 | * It seems dagerous to access memcg without css_get(). |
2402 | * But considering how consume_stok works, it's not | 2410 | * But considering how consume_stok works, it's not |