aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c125
1 files changed, 54 insertions, 71 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a500cb0594c4..a9559b91603c 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -676,9 +676,11 @@ static void disarm_static_keys(struct mem_cgroup *memcg)
676static void drain_all_stock_async(struct mem_cgroup *memcg); 676static void drain_all_stock_async(struct mem_cgroup *memcg);
677 677
678static struct mem_cgroup_per_zone * 678static struct mem_cgroup_per_zone *
679mem_cgroup_zoneinfo(struct mem_cgroup *memcg, int nid, int zid) 679mem_cgroup_zone_zoneinfo(struct mem_cgroup *memcg, struct zone *zone)
680{ 680{
681 VM_BUG_ON((unsigned)nid >= nr_node_ids); 681 int nid = zone_to_nid(zone);
682 int zid = zone_idx(zone);
683
682 return &memcg->nodeinfo[nid]->zoneinfo[zid]; 684 return &memcg->nodeinfo[nid]->zoneinfo[zid];
683} 685}
684 686
@@ -688,12 +690,12 @@ struct cgroup_subsys_state *mem_cgroup_css(struct mem_cgroup *memcg)
688} 690}
689 691
690static struct mem_cgroup_per_zone * 692static struct mem_cgroup_per_zone *
691page_cgroup_zoneinfo(struct mem_cgroup *memcg, struct page *page) 693mem_cgroup_page_zoneinfo(struct mem_cgroup *memcg, struct page *page)
692{ 694{
693 int nid = page_to_nid(page); 695 int nid = page_to_nid(page);
694 int zid = page_zonenum(page); 696 int zid = page_zonenum(page);
695 697
696 return mem_cgroup_zoneinfo(memcg, nid, zid); 698 return &memcg->nodeinfo[nid]->zoneinfo[zid];
697} 699}
698 700
699static struct mem_cgroup_tree_per_zone * 701static struct mem_cgroup_tree_per_zone *
@@ -711,11 +713,9 @@ soft_limit_tree_from_page(struct page *page)
711 return &soft_limit_tree.rb_tree_per_node[nid]->rb_tree_per_zone[zid]; 713 return &soft_limit_tree.rb_tree_per_node[nid]->rb_tree_per_zone[zid];
712} 714}
713 715
714static void 716static void __mem_cgroup_insert_exceeded(struct mem_cgroup_per_zone *mz,
715__mem_cgroup_insert_exceeded(struct mem_cgroup *memcg, 717 struct mem_cgroup_tree_per_zone *mctz,
716 struct mem_cgroup_per_zone *mz, 718 unsigned long long new_usage_in_excess)
717 struct mem_cgroup_tree_per_zone *mctz,
718 unsigned long long new_usage_in_excess)
719{ 719{
720 struct rb_node **p = &mctz->rb_root.rb_node; 720 struct rb_node **p = &mctz->rb_root.rb_node;
721 struct rb_node *parent = NULL; 721 struct rb_node *parent = NULL;
@@ -745,10 +745,8 @@ __mem_cgroup_insert_exceeded(struct mem_cgroup *memcg,
745 mz->on_tree = true; 745 mz->on_tree = true;
746} 746}
747 747
748static void 748static void __mem_cgroup_remove_exceeded(struct mem_cgroup_per_zone *mz,
749__mem_cgroup_remove_exceeded(struct mem_cgroup *memcg, 749 struct mem_cgroup_tree_per_zone *mctz)
750 struct mem_cgroup_per_zone *mz,
751 struct mem_cgroup_tree_per_zone *mctz)
752{ 750{
753 if (!mz->on_tree) 751 if (!mz->on_tree)
754 return; 752 return;
@@ -756,13 +754,11 @@ __mem_cgroup_remove_exceeded(struct mem_cgroup *memcg,
756 mz->on_tree = false; 754 mz->on_tree = false;
757} 755}
758 756
759static void 757static void mem_cgroup_remove_exceeded(struct mem_cgroup_per_zone *mz,
760mem_cgroup_remove_exceeded(struct mem_cgroup *memcg, 758 struct mem_cgroup_tree_per_zone *mctz)
761 struct mem_cgroup_per_zone *mz,
762 struct mem_cgroup_tree_per_zone *mctz)
763{ 759{
764 spin_lock(&mctz->lock); 760 spin_lock(&mctz->lock);
765 __mem_cgroup_remove_exceeded(memcg, mz, mctz); 761 __mem_cgroup_remove_exceeded(mz, mctz);
766 spin_unlock(&mctz->lock); 762 spin_unlock(&mctz->lock);
767} 763}
768 764
@@ -772,16 +768,14 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, struct page *page)
772 unsigned long long excess; 768 unsigned long long excess;
773 struct mem_cgroup_per_zone *mz; 769 struct mem_cgroup_per_zone *mz;
774 struct mem_cgroup_tree_per_zone *mctz; 770 struct mem_cgroup_tree_per_zone *mctz;
775 int nid = page_to_nid(page);
776 int zid = page_zonenum(page);
777 mctz = soft_limit_tree_from_page(page);
778 771
772 mctz = soft_limit_tree_from_page(page);
779 /* 773 /*
780 * Necessary to update all ancestors when hierarchy is used. 774 * Necessary to update all ancestors when hierarchy is used.
781 * because their event counter is not touched. 775 * because their event counter is not touched.
782 */ 776 */
783 for (; memcg; memcg = parent_mem_cgroup(memcg)) { 777 for (; memcg; memcg = parent_mem_cgroup(memcg)) {
784 mz = mem_cgroup_zoneinfo(memcg, nid, zid); 778 mz = mem_cgroup_page_zoneinfo(memcg, page);
785 excess = res_counter_soft_limit_excess(&memcg->res); 779 excess = res_counter_soft_limit_excess(&memcg->res);
786 /* 780 /*
787 * We have to update the tree if mz is on RB-tree or 781 * We have to update the tree if mz is on RB-tree or
@@ -791,12 +785,12 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, struct page *page)
791 spin_lock(&mctz->lock); 785 spin_lock(&mctz->lock);
792 /* if on-tree, remove it */ 786 /* if on-tree, remove it */
793 if (mz->on_tree) 787 if (mz->on_tree)
794 __mem_cgroup_remove_exceeded(memcg, mz, mctz); 788 __mem_cgroup_remove_exceeded(mz, mctz);
795 /* 789 /*
796 * Insert again. mz->usage_in_excess will be updated. 790 * Insert again. mz->usage_in_excess will be updated.
797 * If excess is 0, no tree ops. 791 * If excess is 0, no tree ops.
798 */ 792 */
799 __mem_cgroup_insert_exceeded(memcg, mz, mctz, excess); 793 __mem_cgroup_insert_exceeded(mz, mctz, excess);
800 spin_unlock(&mctz->lock); 794 spin_unlock(&mctz->lock);
801 } 795 }
802 } 796 }
@@ -804,15 +798,15 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, struct page *page)
804 798
805static void mem_cgroup_remove_from_trees(struct mem_cgroup *memcg) 799static void mem_cgroup_remove_from_trees(struct mem_cgroup *memcg)
806{ 800{
807 int node, zone;
808 struct mem_cgroup_per_zone *mz;
809 struct mem_cgroup_tree_per_zone *mctz; 801 struct mem_cgroup_tree_per_zone *mctz;
802 struct mem_cgroup_per_zone *mz;
803 int nid, zid;
810 804
811 for_each_node(node) { 805 for_each_node(nid) {
812 for (zone = 0; zone < MAX_NR_ZONES; zone++) { 806 for (zid = 0; zid < MAX_NR_ZONES; zid++) {
813 mz = mem_cgroup_zoneinfo(memcg, node, zone); 807 mz = &memcg->nodeinfo[nid]->zoneinfo[zid];
814 mctz = soft_limit_tree_node_zone(node, zone); 808 mctz = soft_limit_tree_node_zone(nid, zid);
815 mem_cgroup_remove_exceeded(memcg, mz, mctz); 809 mem_cgroup_remove_exceeded(mz, mctz);
816 } 810 }
817 } 811 }
818} 812}
@@ -835,7 +829,7 @@ retry:
835 * we will to add it back at the end of reclaim to its correct 829 * we will to add it back at the end of reclaim to its correct
836 * position in the tree. 830 * position in the tree.
837 */ 831 */
838 __mem_cgroup_remove_exceeded(mz->memcg, mz, mctz); 832 __mem_cgroup_remove_exceeded(mz, mctz);
839 if (!res_counter_soft_limit_excess(&mz->memcg->res) || 833 if (!res_counter_soft_limit_excess(&mz->memcg->res) ||
840 !css_tryget(&mz->memcg->css)) 834 !css_tryget(&mz->memcg->css))
841 goto retry; 835 goto retry;
@@ -946,8 +940,7 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *memcg,
946 __this_cpu_add(memcg->stat->nr_page_events, nr_pages); 940 __this_cpu_add(memcg->stat->nr_page_events, nr_pages);
947} 941}
948 942
949unsigned long 943unsigned long mem_cgroup_get_lru_size(struct lruvec *lruvec, enum lru_list lru)
950mem_cgroup_get_lru_size(struct lruvec *lruvec, enum lru_list lru)
951{ 944{
952 struct mem_cgroup_per_zone *mz; 945 struct mem_cgroup_per_zone *mz;
953 946
@@ -955,46 +948,38 @@ mem_cgroup_get_lru_size(struct lruvec *lruvec, enum lru_list lru)
955 return mz->lru_size[lru]; 948 return mz->lru_size[lru];
956} 949}
957 950
958static unsigned long 951static unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg,
959mem_cgroup_zone_nr_lru_pages(struct mem_cgroup *memcg, int nid, int zid, 952 int nid,
960 unsigned int lru_mask) 953 unsigned int lru_mask)
961{ 954{
962 struct mem_cgroup_per_zone *mz; 955 unsigned long nr = 0;
963 enum lru_list lru;
964 unsigned long ret = 0;
965
966 mz = mem_cgroup_zoneinfo(memcg, nid, zid);
967
968 for_each_lru(lru) {
969 if (BIT(lru) & lru_mask)
970 ret += mz->lru_size[lru];
971 }
972 return ret;
973}
974
975static unsigned long
976mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg,
977 int nid, unsigned int lru_mask)
978{
979 u64 total = 0;
980 int zid; 956 int zid;
981 957
982 for (zid = 0; zid < MAX_NR_ZONES; zid++) 958 VM_BUG_ON((unsigned)nid >= nr_node_ids);
983 total += mem_cgroup_zone_nr_lru_pages(memcg,
984 nid, zid, lru_mask);
985 959
986 return total; 960 for (zid = 0; zid < MAX_NR_ZONES; zid++) {
961 struct mem_cgroup_per_zone *mz;
962 enum lru_list lru;
963
964 for_each_lru(lru) {
965 if (!(BIT(lru) & lru_mask))
966 continue;
967 mz = &memcg->nodeinfo[nid]->zoneinfo[zid];
968 nr += mz->lru_size[lru];
969 }
970 }
971 return nr;
987} 972}
988 973
989static unsigned long mem_cgroup_nr_lru_pages(struct mem_cgroup *memcg, 974static unsigned long mem_cgroup_nr_lru_pages(struct mem_cgroup *memcg,
990 unsigned int lru_mask) 975 unsigned int lru_mask)
991{ 976{
977 unsigned long nr = 0;
992 int nid; 978 int nid;
993 u64 total = 0;
994 979
995 for_each_node_state(nid, N_MEMORY) 980 for_each_node_state(nid, N_MEMORY)
996 total += mem_cgroup_node_nr_lru_pages(memcg, nid, lru_mask); 981 nr += mem_cgroup_node_nr_lru_pages(memcg, nid, lru_mask);
997 return total; 982 return nr;
998} 983}
999 984
1000static bool mem_cgroup_event_ratelimit(struct mem_cgroup *memcg, 985static bool mem_cgroup_event_ratelimit(struct mem_cgroup *memcg,
@@ -1242,11 +1227,9 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
1242 int uninitialized_var(seq); 1227 int uninitialized_var(seq);
1243 1228
1244 if (reclaim) { 1229 if (reclaim) {
1245 int nid = zone_to_nid(reclaim->zone);
1246 int zid = zone_idx(reclaim->zone);
1247 struct mem_cgroup_per_zone *mz; 1230 struct mem_cgroup_per_zone *mz;
1248 1231
1249 mz = mem_cgroup_zoneinfo(root, nid, zid); 1232 mz = mem_cgroup_zone_zoneinfo(root, reclaim->zone);
1250 iter = &mz->reclaim_iter[reclaim->priority]; 1233 iter = &mz->reclaim_iter[reclaim->priority];
1251 if (prev && reclaim->generation != iter->generation) { 1234 if (prev && reclaim->generation != iter->generation) {
1252 iter->last_visited = NULL; 1235 iter->last_visited = NULL;
@@ -1353,7 +1336,7 @@ struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone,
1353 goto out; 1336 goto out;
1354 } 1337 }
1355 1338
1356 mz = mem_cgroup_zoneinfo(memcg, zone_to_nid(zone), zone_idx(zone)); 1339 mz = mem_cgroup_zone_zoneinfo(memcg, zone);
1357 lruvec = &mz->lruvec; 1340 lruvec = &mz->lruvec;
1358out: 1341out:
1359 /* 1342 /*
@@ -1412,7 +1395,7 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone)
1412 if (!PageLRU(page) && !PageCgroupUsed(pc) && memcg != root_mem_cgroup) 1395 if (!PageLRU(page) && !PageCgroupUsed(pc) && memcg != root_mem_cgroup)
1413 pc->mem_cgroup = memcg = root_mem_cgroup; 1396 pc->mem_cgroup = memcg = root_mem_cgroup;
1414 1397
1415 mz = page_cgroup_zoneinfo(memcg, page); 1398 mz = mem_cgroup_page_zoneinfo(memcg, page);
1416 lruvec = &mz->lruvec; 1399 lruvec = &mz->lruvec;
1417out: 1400out:
1418 /* 1401 /*
@@ -1550,7 +1533,7 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg)
1550int mem_cgroup_swappiness(struct mem_cgroup *memcg) 1533int mem_cgroup_swappiness(struct mem_cgroup *memcg)
1551{ 1534{
1552 /* root ? */ 1535 /* root ? */
1553 if (!css_parent(&memcg->css)) 1536 if (mem_cgroup_disabled() || !css_parent(&memcg->css))
1554 return vm_swappiness; 1537 return vm_swappiness;
1555 1538
1556 return memcg->swappiness; 1539 return memcg->swappiness;
@@ -4597,7 +4580,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
4597 break; 4580 break;
4598 } while (1); 4581 } while (1);
4599 } 4582 }
4600 __mem_cgroup_remove_exceeded(mz->memcg, mz, mctz); 4583 __mem_cgroup_remove_exceeded(mz, mctz);
4601 excess = res_counter_soft_limit_excess(&mz->memcg->res); 4584 excess = res_counter_soft_limit_excess(&mz->memcg->res);
4602 /* 4585 /*
4603 * One school of thought says that we should not add 4586 * One school of thought says that we should not add
@@ -4608,7 +4591,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
4608 * term TODO. 4591 * term TODO.
4609 */ 4592 */
4610 /* If excess == 0, no tree ops */ 4593 /* If excess == 0, no tree ops */
4611 __mem_cgroup_insert_exceeded(mz->memcg, mz, mctz, excess); 4594 __mem_cgroup_insert_exceeded(mz, mctz, excess);
4612 spin_unlock(&mctz->lock); 4595 spin_unlock(&mctz->lock);
4613 css_put(&mz->memcg->css); 4596 css_put(&mz->memcg->css);
4614 loop++; 4597 loop++;
@@ -5305,7 +5288,7 @@ static int memcg_stat_show(struct seq_file *m, void *v)
5305 5288
5306 for_each_online_node(nid) 5289 for_each_online_node(nid)
5307 for (zid = 0; zid < MAX_NR_ZONES; zid++) { 5290 for (zid = 0; zid < MAX_NR_ZONES; zid++) {
5308 mz = mem_cgroup_zoneinfo(memcg, nid, zid); 5291 mz = &memcg->nodeinfo[nid]->zoneinfo[zid];
5309 rstat = &mz->lruvec.reclaim_stat; 5292 rstat = &mz->lruvec.reclaim_stat;
5310 5293
5311 recent_rotated[0] += rstat->recent_rotated[0]; 5294 recent_rotated[0] += rstat->recent_rotated[0];