diff options
author | Andrew Morton <akpm@linux-foundation.org> | 2013-09-24 18:27:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-24 20:00:26 -0400 |
commit | 694fbc0fe78518d06efa63910bf4ecee660e7852 (patch) | |
tree | 895244c4cc010759ce5c29333bee3cddc8c852d2 /mm/memcontrol.c | |
parent | 30361e51cae7a4df3fec89f935a450a6fe6f16fa (diff) |
revert "memcg: enhance memcg iterator to support predicates"
Revert commit de57780dc659 ("memcg: enhance memcg iterator to support
predicates")
I merged this prematurely - Michal and Johannes still disagree about the
overall design direction and the future remains unclear.
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 70 |
1 files changed, 15 insertions, 55 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 916892c2b8e0..65e7bec4b0f0 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -862,15 +862,6 @@ struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm) | |||
862 | return memcg; | 862 | return memcg; |
863 | } | 863 | } |
864 | 864 | ||
865 | static enum mem_cgroup_filter_t | ||
866 | mem_cgroup_filter(struct mem_cgroup *memcg, struct mem_cgroup *root, | ||
867 | mem_cgroup_iter_filter cond) | ||
868 | { | ||
869 | if (!cond) | ||
870 | return VISIT; | ||
871 | return cond(memcg, root); | ||
872 | } | ||
873 | |||
874 | /* | 865 | /* |
875 | * Returns a next (in a pre-order walk) alive memcg (with elevated css | 866 | * Returns a next (in a pre-order walk) alive memcg (with elevated css |
876 | * ref. count) or NULL if the whole root's subtree has been visited. | 867 | * ref. count) or NULL if the whole root's subtree has been visited. |
@@ -878,7 +869,7 @@ mem_cgroup_filter(struct mem_cgroup *memcg, struct mem_cgroup *root, | |||
878 | * helper function to be used by mem_cgroup_iter | 869 | * helper function to be used by mem_cgroup_iter |
879 | */ | 870 | */ |
880 | static struct mem_cgroup *__mem_cgroup_iter_next(struct mem_cgroup *root, | 871 | static struct mem_cgroup *__mem_cgroup_iter_next(struct mem_cgroup *root, |
881 | struct mem_cgroup *last_visited, mem_cgroup_iter_filter cond) | 872 | struct mem_cgroup *last_visited) |
882 | { | 873 | { |
883 | struct cgroup_subsys_state *prev_css, *next_css; | 874 | struct cgroup_subsys_state *prev_css, *next_css; |
884 | 875 | ||
@@ -896,31 +887,11 @@ skip_node: | |||
896 | if (next_css) { | 887 | if (next_css) { |
897 | struct mem_cgroup *mem = mem_cgroup_from_css(next_css); | 888 | struct mem_cgroup *mem = mem_cgroup_from_css(next_css); |
898 | 889 | ||
899 | switch (mem_cgroup_filter(mem, root, cond)) { | 890 | if (css_tryget(&mem->css)) |
900 | case SKIP: | 891 | return mem; |
892 | else { | ||
901 | prev_css = next_css; | 893 | prev_css = next_css; |
902 | goto skip_node; | 894 | goto skip_node; |
903 | case SKIP_TREE: | ||
904 | if (mem == root) | ||
905 | return NULL; | ||
906 | /* | ||
907 | * css_rightmost_descendant is not an optimal way to | ||
908 | * skip through a subtree (especially for imbalanced | ||
909 | * trees leaning to right) but that's what we have right | ||
910 | * now. More effective solution would be traversing | ||
911 | * right-up for first non-NULL without calling | ||
912 | * css_next_descendant_pre afterwards. | ||
913 | */ | ||
914 | prev_css = css_rightmost_descendant(next_css); | ||
915 | goto skip_node; | ||
916 | case VISIT: | ||
917 | if (css_tryget(&mem->css)) | ||
918 | return mem; | ||
919 | else { | ||
920 | prev_css = next_css; | ||
921 | goto skip_node; | ||
922 | } | ||
923 | break; | ||
924 | } | 895 | } |
925 | } | 896 | } |
926 | 897 | ||
@@ -984,7 +955,6 @@ static void mem_cgroup_iter_update(struct mem_cgroup_reclaim_iter *iter, | |||
984 | * @root: hierarchy root | 955 | * @root: hierarchy root |
985 | * @prev: previously returned memcg, NULL on first invocation | 956 | * @prev: previously returned memcg, NULL on first invocation |
986 | * @reclaim: cookie for shared reclaim walks, NULL for full walks | 957 | * @reclaim: cookie for shared reclaim walks, NULL for full walks |
987 | * @cond: filter for visited nodes, NULL for no filter | ||
988 | * | 958 | * |
989 | * Returns references to children of the hierarchy below @root, or | 959 | * Returns references to children of the hierarchy below @root, or |
990 | * @root itself, or %NULL after a full round-trip. | 960 | * @root itself, or %NULL after a full round-trip. |
@@ -997,18 +967,15 @@ static void mem_cgroup_iter_update(struct mem_cgroup_reclaim_iter *iter, | |||
997 | * divide up the memcgs in the hierarchy among all concurrent | 967 | * divide up the memcgs in the hierarchy among all concurrent |
998 | * reclaimers operating on the same zone and priority. | 968 | * reclaimers operating on the same zone and priority. |
999 | */ | 969 | */ |
1000 | struct mem_cgroup *mem_cgroup_iter_cond(struct mem_cgroup *root, | 970 | struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root, |
1001 | struct mem_cgroup *prev, | 971 | struct mem_cgroup *prev, |
1002 | struct mem_cgroup_reclaim_cookie *reclaim, | 972 | struct mem_cgroup_reclaim_cookie *reclaim) |
1003 | mem_cgroup_iter_filter cond) | ||
1004 | { | 973 | { |
1005 | struct mem_cgroup *memcg = NULL; | 974 | struct mem_cgroup *memcg = NULL; |
1006 | struct mem_cgroup *last_visited = NULL; | 975 | struct mem_cgroup *last_visited = NULL; |
1007 | 976 | ||
1008 | if (mem_cgroup_disabled()) { | 977 | if (mem_cgroup_disabled()) |
1009 | /* first call must return non-NULL, second return NULL */ | 978 | return NULL; |
1010 | return (struct mem_cgroup *)(unsigned long)!prev; | ||
1011 | } | ||
1012 | 979 | ||
1013 | if (!root) | 980 | if (!root) |
1014 | root = root_mem_cgroup; | 981 | root = root_mem_cgroup; |
@@ -1019,9 +986,7 @@ struct mem_cgroup *mem_cgroup_iter_cond(struct mem_cgroup *root, | |||
1019 | if (!root->use_hierarchy && root != root_mem_cgroup) { | 986 | if (!root->use_hierarchy && root != root_mem_cgroup) { |
1020 | if (prev) | 987 | if (prev) |
1021 | goto out_css_put; | 988 | goto out_css_put; |
1022 | if (mem_cgroup_filter(root, root, cond) == VISIT) | 989 | return root; |
1023 | return root; | ||
1024 | return NULL; | ||
1025 | } | 990 | } |
1026 | 991 | ||
1027 | rcu_read_lock(); | 992 | rcu_read_lock(); |
@@ -1044,7 +1009,7 @@ struct mem_cgroup *mem_cgroup_iter_cond(struct mem_cgroup *root, | |||
1044 | last_visited = mem_cgroup_iter_load(iter, root, &seq); | 1009 | last_visited = mem_cgroup_iter_load(iter, root, &seq); |
1045 | } | 1010 | } |
1046 | 1011 | ||
1047 | memcg = __mem_cgroup_iter_next(root, last_visited, cond); | 1012 | memcg = __mem_cgroup_iter_next(root, last_visited); |
1048 | 1013 | ||
1049 | if (reclaim) { | 1014 | if (reclaim) { |
1050 | mem_cgroup_iter_update(iter, last_visited, memcg, seq); | 1015 | mem_cgroup_iter_update(iter, last_visited, memcg, seq); |
@@ -1055,11 +1020,7 @@ struct mem_cgroup *mem_cgroup_iter_cond(struct mem_cgroup *root, | |||
1055 | reclaim->generation = iter->generation; | 1020 | reclaim->generation = iter->generation; |
1056 | } | 1021 | } |
1057 | 1022 | ||
1058 | /* | 1023 | if (prev && !memcg) |
1059 | * We have finished the whole tree walk or no group has been | ||
1060 | * visited because filter told us to skip the root node. | ||
1061 | */ | ||
1062 | if (!memcg && (prev || (cond && !last_visited))) | ||
1063 | goto out_unlock; | 1024 | goto out_unlock; |
1064 | } | 1025 | } |
1065 | out_unlock: | 1026 | out_unlock: |
@@ -1804,14 +1765,13 @@ int mem_cgroup_select_victim_node(struct mem_cgroup *memcg) | |||
1804 | * a) it is over its soft limit | 1765 | * a) it is over its soft limit |
1805 | * b) any parent up the hierarchy is over its soft limit | 1766 | * b) any parent up the hierarchy is over its soft limit |
1806 | */ | 1767 | */ |
1807 | enum mem_cgroup_filter_t | 1768 | bool mem_cgroup_soft_reclaim_eligible(struct mem_cgroup *memcg, |
1808 | mem_cgroup_soft_reclaim_eligible(struct mem_cgroup *memcg, | ||
1809 | struct mem_cgroup *root) | 1769 | struct mem_cgroup *root) |
1810 | { | 1770 | { |
1811 | struct mem_cgroup *parent = memcg; | 1771 | struct mem_cgroup *parent = memcg; |
1812 | 1772 | ||
1813 | if (res_counter_soft_limit_excess(&memcg->res)) | 1773 | if (res_counter_soft_limit_excess(&memcg->res)) |
1814 | return VISIT; | 1774 | return true; |
1815 | 1775 | ||
1816 | /* | 1776 | /* |
1817 | * If any parent up to the root in the hierarchy is over its soft limit | 1777 | * If any parent up to the root in the hierarchy is over its soft limit |
@@ -1819,12 +1779,12 @@ mem_cgroup_soft_reclaim_eligible(struct mem_cgroup *memcg, | |||
1819 | */ | 1779 | */ |
1820 | while ((parent = parent_mem_cgroup(parent))) { | 1780 | while ((parent = parent_mem_cgroup(parent))) { |
1821 | if (res_counter_soft_limit_excess(&parent->res)) | 1781 | if (res_counter_soft_limit_excess(&parent->res)) |
1822 | return VISIT; | 1782 | return true; |
1823 | if (parent == root) | 1783 | if (parent == root) |
1824 | break; | 1784 | break; |
1825 | } | 1785 | } |
1826 | 1786 | ||
1827 | return SKIP; | 1787 | return false; |
1828 | } | 1788 | } |
1829 | 1789 | ||
1830 | static DEFINE_SPINLOCK(memcg_oom_lock); | 1790 | static DEFINE_SPINLOCK(memcg_oom_lock); |