diff options
-rw-r--r-- | Documentation/cgroups/memory.txt | 13 | ||||
-rw-r--r-- | mm/memcontrol.c | 34 |
2 files changed, 19 insertions, 28 deletions
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt index 6a066a270fc5..dd88540bb995 100644 --- a/Documentation/cgroups/memory.txt +++ b/Documentation/cgroups/memory.txt | |||
@@ -376,14 +376,15 @@ cgroup might have some charge associated with it, even though all | |||
376 | tasks have migrated away from it. (because we charge against pages, not | 376 | tasks have migrated away from it. (because we charge against pages, not |
377 | against tasks.) | 377 | against tasks.) |
378 | 378 | ||
379 | Such charges are freed or moved to their parent. At moving, both of RSS | 379 | We move the stats to root (if use_hierarchy==0) or parent (if |
380 | and CACHES are moved to parent. | 380 | use_hierarchy==1), and no change on the charge except uncharging |
381 | rmdir() may return -EBUSY if freeing/moving fails. See 5.1 also. | 381 | from the child. |
382 | 382 | ||
383 | Charges recorded in swap information is not updated at removal of cgroup. | 383 | Charges recorded in swap information is not updated at removal of cgroup. |
384 | Recorded information is discarded and a cgroup which uses swap (swapcache) | 384 | Recorded information is discarded and a cgroup which uses swap (swapcache) |
385 | will be charged as a new owner of it. | 385 | will be charged as a new owner of it. |
386 | 386 | ||
387 | About use_hierarchy, see Section 6. | ||
387 | 388 | ||
388 | 5. Misc. interfaces. | 389 | 5. Misc. interfaces. |
389 | 390 | ||
@@ -396,13 +397,15 @@ will be charged as a new owner of it. | |||
396 | 397 | ||
397 | Almost all pages tracked by this memory cgroup will be unmapped and freed. | 398 | Almost all pages tracked by this memory cgroup will be unmapped and freed. |
398 | Some pages cannot be freed because they are locked or in-use. Such pages are | 399 | Some pages cannot be freed because they are locked or in-use. Such pages are |
399 | moved to parent and this cgroup will be empty. This may return -EBUSY if | 400 | moved to parent(if use_hierarchy==1) or root (if use_hierarchy==0) and this |
400 | VM is too busy to free/move all pages immediately. | 401 | cgroup will be empty. |
401 | 402 | ||
402 | Typical use case of this interface is that calling this before rmdir(). | 403 | Typical use case of this interface is that calling this before rmdir(). |
403 | Because rmdir() moves all pages to parent, some out-of-use page caches can be | 404 | Because rmdir() moves all pages to parent, some out-of-use page caches can be |
404 | moved to the parent. If you want to avoid that, force_empty will be useful. | 405 | moved to the parent. If you want to avoid that, force_empty will be useful. |
405 | 406 | ||
407 | About use_hierarchy, see Section 6. | ||
408 | |||
406 | 5.2 stat file | 409 | 5.2 stat file |
407 | 410 | ||
408 | memory.stat file includes following statistics | 411 | memory.stat file includes following statistics |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 1262a8bc402b..96cd9ebefb2c 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -2678,15 +2678,13 @@ static int mem_cgroup_move_parent(struct page *page, | |||
2678 | struct mem_cgroup *child, | 2678 | struct mem_cgroup *child, |
2679 | gfp_t gfp_mask) | 2679 | gfp_t gfp_mask) |
2680 | { | 2680 | { |
2681 | struct cgroup *cg = child->css.cgroup; | ||
2682 | struct cgroup *pcg = cg->parent; | ||
2683 | struct mem_cgroup *parent; | 2681 | struct mem_cgroup *parent; |
2684 | unsigned int nr_pages; | 2682 | unsigned int nr_pages; |
2685 | unsigned long uninitialized_var(flags); | 2683 | unsigned long uninitialized_var(flags); |
2686 | int ret; | 2684 | int ret; |
2687 | 2685 | ||
2688 | /* Is ROOT ? */ | 2686 | /* Is ROOT ? */ |
2689 | if (!pcg) | 2687 | if (mem_cgroup_is_root(child)) |
2690 | return -EINVAL; | 2688 | return -EINVAL; |
2691 | 2689 | ||
2692 | ret = -EBUSY; | 2690 | ret = -EBUSY; |
@@ -2697,33 +2695,23 @@ static int mem_cgroup_move_parent(struct page *page, | |||
2697 | 2695 | ||
2698 | nr_pages = hpage_nr_pages(page); | 2696 | nr_pages = hpage_nr_pages(page); |
2699 | 2697 | ||
2700 | parent = mem_cgroup_from_cont(pcg); | 2698 | parent = parent_mem_cgroup(child); |
2701 | if (!parent->use_hierarchy) { | 2699 | /* |
2702 | ret = __mem_cgroup_try_charge(NULL, | 2700 | * If no parent, move charges to root cgroup. |
2703 | gfp_mask, nr_pages, &parent, false); | 2701 | */ |
2704 | if (ret) | 2702 | if (!parent) |
2705 | goto put_back; | 2703 | parent = root_mem_cgroup; |
2706 | } | ||
2707 | 2704 | ||
2708 | if (nr_pages > 1) | 2705 | if (nr_pages > 1) |
2709 | flags = compound_lock_irqsave(page); | 2706 | flags = compound_lock_irqsave(page); |
2710 | 2707 | ||
2711 | if (parent->use_hierarchy) { | 2708 | ret = mem_cgroup_move_account(page, nr_pages, |
2712 | ret = mem_cgroup_move_account(page, nr_pages, | 2709 | pc, child, parent, false); |
2713 | pc, child, parent, false); | 2710 | if (!ret) |
2714 | if (!ret) | 2711 | __mem_cgroup_cancel_local_charge(child, nr_pages); |
2715 | __mem_cgroup_cancel_local_charge(child, nr_pages); | ||
2716 | } else { | ||
2717 | ret = mem_cgroup_move_account(page, nr_pages, | ||
2718 | pc, child, parent, true); | ||
2719 | |||
2720 | if (ret) | ||
2721 | __mem_cgroup_cancel_charge(parent, nr_pages); | ||
2722 | } | ||
2723 | 2712 | ||
2724 | if (nr_pages > 1) | 2713 | if (nr_pages > 1) |
2725 | compound_unlock_irqrestore(page, flags); | 2714 | compound_unlock_irqrestore(page, flags); |
2726 | put_back: | ||
2727 | putback_lru_page(page); | 2715 | putback_lru_page(page); |
2728 | put: | 2716 | put: |
2729 | put_page(page); | 2717 | put_page(page); |