aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c110
1 files changed, 56 insertions, 54 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 556859fec4ef..d0e57a3cda18 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -776,7 +776,8 @@ static void memcg_check_events(struct mem_cgroup *memcg, struct page *page)
776 /* threshold event is triggered in finer grain than soft limit */ 776 /* threshold event is triggered in finer grain than soft limit */
777 if (unlikely(mem_cgroup_event_ratelimit(memcg, 777 if (unlikely(mem_cgroup_event_ratelimit(memcg,
778 MEM_CGROUP_TARGET_THRESH))) { 778 MEM_CGROUP_TARGET_THRESH))) {
779 bool do_softlimit, do_numainfo; 779 bool do_softlimit;
780 bool do_numainfo __maybe_unused;
780 781
781 do_softlimit = mem_cgroup_event_ratelimit(memcg, 782 do_softlimit = mem_cgroup_event_ratelimit(memcg,
782 MEM_CGROUP_TARGET_SOFTLIMIT); 783 MEM_CGROUP_TARGET_SOFTLIMIT);
@@ -1041,6 +1042,19 @@ struct lruvec *mem_cgroup_lru_add_list(struct zone *zone, struct page *page,
1041 1042
1042 pc = lookup_page_cgroup(page); 1043 pc = lookup_page_cgroup(page);
1043 memcg = pc->mem_cgroup; 1044 memcg = pc->mem_cgroup;
1045
1046 /*
1047 * Surreptitiously switch any uncharged page to root:
1048 * an uncharged page off lru does nothing to secure
1049 * its former mem_cgroup from sudden removal.
1050 *
1051 * Our caller holds lru_lock, and PageCgroupUsed is updated
1052 * under page_cgroup lock: between them, they make all uses
1053 * of pc->mem_cgroup safe.
1054 */
1055 if (!PageCgroupUsed(pc) && memcg != root_mem_cgroup)
1056 pc->mem_cgroup = memcg = root_mem_cgroup;
1057
1044 mz = page_cgroup_zoneinfo(memcg, page); 1058 mz = page_cgroup_zoneinfo(memcg, page);
1045 /* compound_order() is stabilized through lru_lock */ 1059 /* compound_order() is stabilized through lru_lock */
1046 MEM_CGROUP_ZSTAT(mz, lru) += 1 << compound_order(page); 1060 MEM_CGROUP_ZSTAT(mz, lru) += 1 << compound_order(page);
@@ -2407,8 +2421,12 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg,
2407 struct page *page, 2421 struct page *page,
2408 unsigned int nr_pages, 2422 unsigned int nr_pages,
2409 struct page_cgroup *pc, 2423 struct page_cgroup *pc,
2410 enum charge_type ctype) 2424 enum charge_type ctype,
2425 bool lrucare)
2411{ 2426{
2427 struct zone *uninitialized_var(zone);
2428 bool was_on_lru = false;
2429
2412 lock_page_cgroup(pc); 2430 lock_page_cgroup(pc);
2413 if (unlikely(PageCgroupUsed(pc))) { 2431 if (unlikely(PageCgroupUsed(pc))) {
2414 unlock_page_cgroup(pc); 2432 unlock_page_cgroup(pc);
@@ -2419,6 +2437,21 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg,
2419 * we don't need page_cgroup_lock about tail pages, becase they are not 2437 * we don't need page_cgroup_lock about tail pages, becase they are not
2420 * accessed by any other context at this point. 2438 * accessed by any other context at this point.
2421 */ 2439 */
2440
2441 /*
2442 * In some cases, SwapCache and FUSE(splice_buf->radixtree), the page
2443 * may already be on some other mem_cgroup's LRU. Take care of it.
2444 */
2445 if (lrucare) {
2446 zone = page_zone(page);
2447 spin_lock_irq(&zone->lru_lock);
2448 if (PageLRU(page)) {
2449 ClearPageLRU(page);
2450 del_page_from_lru_list(zone, page, page_lru(page));
2451 was_on_lru = true;
2452 }
2453 }
2454
2422 pc->mem_cgroup = memcg; 2455 pc->mem_cgroup = memcg;
2423 /* 2456 /*
2424 * We access a page_cgroup asynchronously without lock_page_cgroup(). 2457 * We access a page_cgroup asynchronously without lock_page_cgroup().
@@ -2442,9 +2475,18 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg,
2442 break; 2475 break;
2443 } 2476 }
2444 2477
2478 if (lrucare) {
2479 if (was_on_lru) {
2480 VM_BUG_ON(PageLRU(page));
2481 SetPageLRU(page);
2482 add_page_to_lru_list(zone, page, page_lru(page));
2483 }
2484 spin_unlock_irq(&zone->lru_lock);
2485 }
2486
2445 mem_cgroup_charge_statistics(memcg, PageCgroupCache(pc), nr_pages); 2487 mem_cgroup_charge_statistics(memcg, PageCgroupCache(pc), nr_pages);
2446 unlock_page_cgroup(pc); 2488 unlock_page_cgroup(pc);
2447 WARN_ON_ONCE(PageLRU(page)); 2489
2448 /* 2490 /*
2449 * "charge_statistics" updated event counter. Then, check it. 2491 * "charge_statistics" updated event counter. Then, check it.
2450 * Insert ancestor (and ancestor's ancestors), to softlimit RB-tree. 2492 * Insert ancestor (and ancestor's ancestors), to softlimit RB-tree.
@@ -2642,7 +2684,7 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
2642 ret = __mem_cgroup_try_charge(mm, gfp_mask, nr_pages, &memcg, oom); 2684 ret = __mem_cgroup_try_charge(mm, gfp_mask, nr_pages, &memcg, oom);
2643 if (ret == -ENOMEM) 2685 if (ret == -ENOMEM)
2644 return ret; 2686 return ret;
2645 __mem_cgroup_commit_charge(memcg, page, nr_pages, pc, ctype); 2687 __mem_cgroup_commit_charge(memcg, page, nr_pages, pc, ctype, false);
2646 return 0; 2688 return 0;
2647} 2689}
2648 2690
@@ -2662,35 +2704,6 @@ static void
2662__mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr, 2704__mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr,
2663 enum charge_type ctype); 2705 enum charge_type ctype);
2664 2706
2665static void
2666__mem_cgroup_commit_charge_lrucare(struct page *page, struct mem_cgroup *memcg,
2667 enum charge_type ctype)
2668{
2669 struct page_cgroup *pc = lookup_page_cgroup(page);
2670 struct zone *zone = page_zone(page);
2671 unsigned long flags;
2672 bool removed = false;
2673
2674 /*
2675 * In some case, SwapCache, FUSE(splice_buf->radixtree), the page
2676 * is already on LRU. It means the page may on some other page_cgroup's
2677 * LRU. Take care of it.
2678 */
2679 spin_lock_irqsave(&zone->lru_lock, flags);
2680 if (PageLRU(page)) {
2681 del_page_from_lru_list(zone, page, page_lru(page));
2682 ClearPageLRU(page);
2683 removed = true;
2684 }
2685 __mem_cgroup_commit_charge(memcg, page, 1, pc, ctype);
2686 if (removed) {
2687 add_page_to_lru_list(zone, page, page_lru(page));
2688 SetPageLRU(page);
2689 }
2690 spin_unlock_irqrestore(&zone->lru_lock, flags);
2691 return;
2692}
2693
2694int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, 2707int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
2695 gfp_t gfp_mask) 2708 gfp_t gfp_mask)
2696{ 2709{
@@ -2768,13 +2781,16 @@ static void
2768__mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *memcg, 2781__mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *memcg,
2769 enum charge_type ctype) 2782 enum charge_type ctype)
2770{ 2783{
2784 struct page_cgroup *pc;
2785
2771 if (mem_cgroup_disabled()) 2786 if (mem_cgroup_disabled())
2772 return; 2787 return;
2773 if (!memcg) 2788 if (!memcg)
2774 return; 2789 return;
2775 cgroup_exclude_rmdir(&memcg->css); 2790 cgroup_exclude_rmdir(&memcg->css);
2776 2791
2777 __mem_cgroup_commit_charge_lrucare(page, memcg, ctype); 2792 pc = lookup_page_cgroup(page);
2793 __mem_cgroup_commit_charge(memcg, page, 1, pc, ctype, true);
2778 /* 2794 /*
2779 * Now swap is on-memory. This means this page may be 2795 * Now swap is on-memory. This means this page may be
2780 * counted both as mem and swap....double count. 2796 * counted both as mem and swap....double count.
@@ -3026,23 +3042,6 @@ void mem_cgroup_uncharge_end(void)
3026 batch->memcg = NULL; 3042 batch->memcg = NULL;
3027} 3043}
3028 3044
3029/*
3030 * A function for resetting pc->mem_cgroup for newly allocated pages.
3031 * This function should be called if the newpage will be added to LRU
3032 * before start accounting.
3033 */
3034void mem_cgroup_reset_owner(struct page *newpage)
3035{
3036 struct page_cgroup *pc;
3037
3038 if (mem_cgroup_disabled())
3039 return;
3040
3041 pc = lookup_page_cgroup(newpage);
3042 VM_BUG_ON(PageCgroupUsed(pc));
3043 pc->mem_cgroup = root_mem_cgroup;
3044}
3045
3046#ifdef CONFIG_SWAP 3045#ifdef CONFIG_SWAP
3047/* 3046/*
3048 * called after __delete_from_swap_cache() and drop "page" account. 3047 * called after __delete_from_swap_cache() and drop "page" account.
@@ -3247,7 +3246,7 @@ int mem_cgroup_prepare_migration(struct page *page,
3247 ctype = MEM_CGROUP_CHARGE_TYPE_CACHE; 3246 ctype = MEM_CGROUP_CHARGE_TYPE_CACHE;
3248 else 3247 else
3249 ctype = MEM_CGROUP_CHARGE_TYPE_SHMEM; 3248 ctype = MEM_CGROUP_CHARGE_TYPE_SHMEM;
3250 __mem_cgroup_commit_charge(memcg, newpage, 1, pc, ctype); 3249 __mem_cgroup_commit_charge(memcg, newpage, 1, pc, ctype, false);
3251 return ret; 3250 return ret;
3252} 3251}
3253 3252
@@ -3331,7 +3330,7 @@ void mem_cgroup_replace_page_cache(struct page *oldpage,
3331 * the newpage may be on LRU(or pagevec for LRU) already. We lock 3330 * the newpage may be on LRU(or pagevec for LRU) already. We lock
3332 * LRU while we overwrite pc->mem_cgroup. 3331 * LRU while we overwrite pc->mem_cgroup.
3333 */ 3332 */
3334 __mem_cgroup_commit_charge_lrucare(newpage, memcg, type); 3333 __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true);
3335} 3334}
3336 3335
3337#ifdef CONFIG_DEBUG_VM 3336#ifdef CONFIG_DEBUG_VM
@@ -4413,6 +4412,9 @@ static void mem_cgroup_usage_unregister_event(struct cgroup *cgrp,
4413 */ 4412 */
4414 BUG_ON(!thresholds); 4413 BUG_ON(!thresholds);
4415 4414
4415 if (!thresholds->primary)
4416 goto unlock;
4417
4416 usage = mem_cgroup_usage(memcg, type == _MEMSWAP); 4418 usage = mem_cgroup_usage(memcg, type == _MEMSWAP);
4417 4419
4418 /* Check if a threshold crossed before removing */ 4420 /* Check if a threshold crossed before removing */
@@ -4461,7 +4463,7 @@ swap_buffers:
4461 4463
4462 /* To be sure that nobody uses thresholds */ 4464 /* To be sure that nobody uses thresholds */
4463 synchronize_rcu(); 4465 synchronize_rcu();
4464 4466unlock:
4465 mutex_unlock(&memcg->thresholds_lock); 4467 mutex_unlock(&memcg->thresholds_lock);
4466} 4468}
4467 4469