diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-10-31 19:58:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-10-31 19:58:23 -0400 |
commit | 4f794ee8c40119366e0be45f9d49e7ff1a89b79b (patch) | |
tree | 137eccc7d99cb71f4ae11568df0eaa909cbb7529 | |
parent | 358eec18243ac025b2eb0317ab52bd247e1b03c6 (diff) | |
parent | 3d77b50c5874b7e923be946ba793644f82336b75 (diff) |
Merge branch 'akpm' (fixes from Andrew Morton)
Merge four more fixes from Andrew Morton.
* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
lib/scatterlist.c: don't flush_kernel_dcache_page on slab page
mm: memcg: fix test for child groups
mm: memcg: lockdep annotation for memcg OOM lock
mm: memcg: use proper memcg in limit bypass
-rw-r--r-- | lib/scatterlist.c | 3 | ||||
-rw-r--r-- | mm/memcontrol.c | 54 |
2 files changed, 27 insertions, 30 deletions
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index a685c8a79578..d16fa295ae1d 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c | |||
@@ -577,7 +577,8 @@ void sg_miter_stop(struct sg_mapping_iter *miter) | |||
577 | miter->__offset += miter->consumed; | 577 | miter->__offset += miter->consumed; |
578 | miter->__remaining -= miter->consumed; | 578 | miter->__remaining -= miter->consumed; |
579 | 579 | ||
580 | if (miter->__flags & SG_MITER_TO_SG) | 580 | if ((miter->__flags & SG_MITER_TO_SG) && |
581 | !PageSlab(miter->page)) | ||
581 | flush_kernel_dcache_page(miter->page); | 582 | flush_kernel_dcache_page(miter->page); |
582 | 583 | ||
583 | if (miter->__flags & SG_MITER_ATOMIC) { | 584 | if (miter->__flags & SG_MITER_ATOMIC) { |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 497ec33ff22d..e63278222be5 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/page_cgroup.h> | 54 | #include <linux/page_cgroup.h> |
55 | #include <linux/cpu.h> | 55 | #include <linux/cpu.h> |
56 | #include <linux/oom.h> | 56 | #include <linux/oom.h> |
57 | #include <linux/lockdep.h> | ||
57 | #include "internal.h" | 58 | #include "internal.h" |
58 | #include <net/sock.h> | 59 | #include <net/sock.h> |
59 | #include <net/ip.h> | 60 | #include <net/ip.h> |
@@ -2046,6 +2047,12 @@ static int mem_cgroup_soft_reclaim(struct mem_cgroup *root_memcg, | |||
2046 | return total; | 2047 | return total; |
2047 | } | 2048 | } |
2048 | 2049 | ||
2050 | #ifdef CONFIG_LOCKDEP | ||
2051 | static struct lockdep_map memcg_oom_lock_dep_map = { | ||
2052 | .name = "memcg_oom_lock", | ||
2053 | }; | ||
2054 | #endif | ||
2055 | |||
2049 | static DEFINE_SPINLOCK(memcg_oom_lock); | 2056 | static DEFINE_SPINLOCK(memcg_oom_lock); |
2050 | 2057 | ||
2051 | /* | 2058 | /* |
@@ -2083,7 +2090,8 @@ static bool mem_cgroup_oom_trylock(struct mem_cgroup *memcg) | |||
2083 | } | 2090 | } |
2084 | iter->oom_lock = false; | 2091 | iter->oom_lock = false; |
2085 | } | 2092 | } |
2086 | } | 2093 | } else |
2094 | mutex_acquire(&memcg_oom_lock_dep_map, 0, 1, _RET_IP_); | ||
2087 | 2095 | ||
2088 | spin_unlock(&memcg_oom_lock); | 2096 | spin_unlock(&memcg_oom_lock); |
2089 | 2097 | ||
@@ -2095,6 +2103,7 @@ static void mem_cgroup_oom_unlock(struct mem_cgroup *memcg) | |||
2095 | struct mem_cgroup *iter; | 2103 | struct mem_cgroup *iter; |
2096 | 2104 | ||
2097 | spin_lock(&memcg_oom_lock); | 2105 | spin_lock(&memcg_oom_lock); |
2106 | mutex_release(&memcg_oom_lock_dep_map, 1, _RET_IP_); | ||
2098 | for_each_mem_cgroup_tree(iter, memcg) | 2107 | for_each_mem_cgroup_tree(iter, memcg) |
2099 | iter->oom_lock = false; | 2108 | iter->oom_lock = false; |
2100 | spin_unlock(&memcg_oom_lock); | 2109 | spin_unlock(&memcg_oom_lock); |
@@ -2765,10 +2774,10 @@ done: | |||
2765 | *ptr = memcg; | 2774 | *ptr = memcg; |
2766 | return 0; | 2775 | return 0; |
2767 | nomem: | 2776 | nomem: |
2768 | *ptr = NULL; | 2777 | if (!(gfp_mask & __GFP_NOFAIL)) { |
2769 | if (gfp_mask & __GFP_NOFAIL) | 2778 | *ptr = NULL; |
2770 | return 0; | 2779 | return -ENOMEM; |
2771 | return -ENOMEM; | 2780 | } |
2772 | bypass: | 2781 | bypass: |
2773 | *ptr = root_mem_cgroup; | 2782 | *ptr = root_mem_cgroup; |
2774 | return -EINTR; | 2783 | return -EINTR; |
@@ -4950,31 +4959,18 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg) | |||
4950 | } while (usage > 0); | 4959 | } while (usage > 0); |
4951 | } | 4960 | } |
4952 | 4961 | ||
4953 | /* | ||
4954 | * This mainly exists for tests during the setting of set of use_hierarchy. | ||
4955 | * Since this is the very setting we are changing, the current hierarchy value | ||
4956 | * is meaningless | ||
4957 | */ | ||
4958 | static inline bool __memcg_has_children(struct mem_cgroup *memcg) | ||
4959 | { | ||
4960 | struct cgroup_subsys_state *pos; | ||
4961 | |||
4962 | /* bounce at first found */ | ||
4963 | css_for_each_child(pos, &memcg->css) | ||
4964 | return true; | ||
4965 | return false; | ||
4966 | } | ||
4967 | |||
4968 | /* | ||
4969 | * Must be called with memcg_create_mutex held, unless the cgroup is guaranteed | ||
4970 | * to be already dead (as in mem_cgroup_force_empty, for instance). This is | ||
4971 | * from mem_cgroup_count_children(), in the sense that we don't really care how | ||
4972 | * many children we have; we only need to know if we have any. It also counts | ||
4973 | * any memcg without hierarchy as infertile. | ||
4974 | */ | ||
4975 | static inline bool memcg_has_children(struct mem_cgroup *memcg) | 4962 | static inline bool memcg_has_children(struct mem_cgroup *memcg) |
4976 | { | 4963 | { |
4977 | return memcg->use_hierarchy && __memcg_has_children(memcg); | 4964 | lockdep_assert_held(&memcg_create_mutex); |
4965 | /* | ||
4966 | * The lock does not prevent addition or deletion to the list | ||
4967 | * of children, but it prevents a new child from being | ||
4968 | * initialized based on this parent in css_online(), so it's | ||
4969 | * enough to decide whether hierarchically inherited | ||
4970 | * attributes can still be changed or not. | ||
4971 | */ | ||
4972 | return memcg->use_hierarchy && | ||
4973 | !list_empty(&memcg->css.cgroup->children); | ||
4978 | } | 4974 | } |
4979 | 4975 | ||
4980 | /* | 4976 | /* |
@@ -5054,7 +5050,7 @@ static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css, | |||
5054 | */ | 5050 | */ |
5055 | if ((!parent_memcg || !parent_memcg->use_hierarchy) && | 5051 | if ((!parent_memcg || !parent_memcg->use_hierarchy) && |
5056 | (val == 1 || val == 0)) { | 5052 | (val == 1 || val == 0)) { |
5057 | if (!__memcg_has_children(memcg)) | 5053 | if (list_empty(&memcg->css.cgroup->children)) |
5058 | memcg->use_hierarchy = val; | 5054 | memcg->use_hierarchy = val; |
5059 | else | 5055 | else |
5060 | retval = -EBUSY; | 5056 | retval = -EBUSY; |