aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/memcontrol.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 1ae8c439584a..f99f5991d6bb 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -313,7 +313,8 @@ soft_limit_tree_from_page(struct page *page)
313static void 313static void
314__mem_cgroup_insert_exceeded(struct mem_cgroup *mem, 314__mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
315 struct mem_cgroup_per_zone *mz, 315 struct mem_cgroup_per_zone *mz,
316 struct mem_cgroup_tree_per_zone *mctz) 316 struct mem_cgroup_tree_per_zone *mctz,
317 unsigned long long new_usage_in_excess)
317{ 318{
318 struct rb_node **p = &mctz->rb_root.rb_node; 319 struct rb_node **p = &mctz->rb_root.rb_node;
319 struct rb_node *parent = NULL; 320 struct rb_node *parent = NULL;
@@ -322,7 +323,9 @@ __mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
322 if (mz->on_tree) 323 if (mz->on_tree)
323 return; 324 return;
324 325
325 mz->usage_in_excess = res_counter_soft_limit_excess(&mem->res); 326 mz->usage_in_excess = new_usage_in_excess;
327 if (!mz->usage_in_excess)
328 return;
326 while (*p) { 329 while (*p) {
327 parent = *p; 330 parent = *p;
328 mz_node = rb_entry(parent, struct mem_cgroup_per_zone, 331 mz_node = rb_entry(parent, struct mem_cgroup_per_zone,
@@ -382,7 +385,7 @@ static bool mem_cgroup_soft_limit_check(struct mem_cgroup *mem)
382 385
383static void mem_cgroup_update_tree(struct mem_cgroup *mem, struct page *page) 386static void mem_cgroup_update_tree(struct mem_cgroup *mem, struct page *page)
384{ 387{
385 unsigned long long new_usage_in_excess; 388 unsigned long long excess;
386 struct mem_cgroup_per_zone *mz; 389 struct mem_cgroup_per_zone *mz;
387 struct mem_cgroup_tree_per_zone *mctz; 390 struct mem_cgroup_tree_per_zone *mctz;
388 int nid = page_to_nid(page); 391 int nid = page_to_nid(page);
@@ -395,25 +398,21 @@ static void mem_cgroup_update_tree(struct mem_cgroup *mem, struct page *page)
395 */ 398 */
396 for (; mem; mem = parent_mem_cgroup(mem)) { 399 for (; mem; mem = parent_mem_cgroup(mem)) {
397 mz = mem_cgroup_zoneinfo(mem, nid, zid); 400 mz = mem_cgroup_zoneinfo(mem, nid, zid);
398 new_usage_in_excess = 401 excess = res_counter_soft_limit_excess(&mem->res);
399 res_counter_soft_limit_excess(&mem->res);
400 /* 402 /*
401 * We have to update the tree if mz is on RB-tree or 403 * We have to update the tree if mz is on RB-tree or
402 * mem is over its softlimit. 404 * mem is over its softlimit.
403 */ 405 */
404 if (new_usage_in_excess || mz->on_tree) { 406 if (excess || mz->on_tree) {
405 spin_lock(&mctz->lock); 407 spin_lock(&mctz->lock);
406 /* if on-tree, remove it */ 408 /* if on-tree, remove it */
407 if (mz->on_tree) 409 if (mz->on_tree)
408 __mem_cgroup_remove_exceeded(mem, mz, mctz); 410 __mem_cgroup_remove_exceeded(mem, mz, mctz);
409 /* 411 /*
410 * if over soft limit, insert again. mz->usage_in_excess 412 * Insert again. mz->usage_in_excess will be updated.
411 * will be updated properly. 413 * If excess is 0, no tree ops.
412 */ 414 */
413 if (new_usage_in_excess) 415 __mem_cgroup_insert_exceeded(mem, mz, mctz, excess);
414 __mem_cgroup_insert_exceeded(mem, mz, mctz);
415 else
416 mz->usage_in_excess = 0;
417 spin_unlock(&mctz->lock); 416 spin_unlock(&mctz->lock);
418 } 417 }
419 } 418 }
@@ -2221,6 +2220,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
2221 unsigned long reclaimed; 2220 unsigned long reclaimed;
2222 int loop = 0; 2221 int loop = 0;
2223 struct mem_cgroup_tree_per_zone *mctz; 2222 struct mem_cgroup_tree_per_zone *mctz;
2223 unsigned long long excess;
2224 2224
2225 if (order > 0) 2225 if (order > 0)
2226 return 0; 2226 return 0;
@@ -2272,9 +2272,8 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
2272 break; 2272 break;
2273 } while (1); 2273 } while (1);
2274 } 2274 }
2275 mz->usage_in_excess =
2276 res_counter_soft_limit_excess(&mz->mem->res);
2277 __mem_cgroup_remove_exceeded(mz->mem, mz, mctz); 2275 __mem_cgroup_remove_exceeded(mz->mem, mz, mctz);
2276 excess = res_counter_soft_limit_excess(&mz->mem->res);
2278 /* 2277 /*
2279 * One school of thought says that we should not add 2278 * One school of thought says that we should not add
2280 * back the node to the tree if reclaim returns 0. 2279 * back the node to the tree if reclaim returns 0.
@@ -2283,8 +2282,8 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
2283 * memory to reclaim from. Consider this as a longer 2282 * memory to reclaim from. Consider this as a longer
2284 * term TODO. 2283 * term TODO.
2285 */ 2284 */
2286 if (mz->usage_in_excess) 2285 /* If excess == 0, no tree ops */
2287 __mem_cgroup_insert_exceeded(mz->mem, mz, mctz); 2286 __mem_cgroup_insert_exceeded(mz->mem, mz, mctz, excess);
2288 spin_unlock(&mctz->lock); 2287 spin_unlock(&mctz->lock);
2289 css_put(&mz->mem->css); 2288 css_put(&mz->mem->css);
2290 loop++; 2289 loop++;