b43: move under broadcom vendor directory
[cascardo/linux.git] / mm / memcontrol.c
index 9575cff..9acfb16 100644 (file)
@@ -435,7 +435,7 @@ struct cgroup_subsys_state *mem_cgroup_css_from_page(struct page *page)
 
        memcg = page->mem_cgroup;
 
-       if (!memcg || !cgroup_on_dfl(memcg->css.cgroup))
+       if (!memcg || !cgroup_subsys_on_dfl(memory_cgrp_subsys))
                memcg = root_mem_cgroup;
 
        rcu_read_unlock();
@@ -2016,8 +2016,8 @@ retry:
                return 0;
 
        if (!do_swap_account ||
-           !page_counter_try_charge(&memcg->memsw, batch, &counter)) {
-               if (!page_counter_try_charge(&memcg->memory, batch, &counter))
+           page_counter_try_charge(&memcg->memsw, batch, &counter)) {
+               if (page_counter_try_charge(&memcg->memory, batch, &counter))
                        goto done_restock;
                if (do_swap_account)
                        page_counter_uncharge(&memcg->memsw, batch);
@@ -2046,7 +2046,7 @@ retry:
        if (unlikely(task_in_memcg_oom(current)))
                goto nomem;
 
-       if (!(gfp_mask & __GFP_WAIT))
+       if (!gfpflags_allow_blocking(gfp_mask))
                goto nomem;
 
        mem_cgroup_events(mem_over_limit, MEMCG_MAX, 1);
@@ -2120,7 +2120,7 @@ done_restock:
        /*
         * If the hierarchy is above the normal consumption range, schedule
         * reclaim on returning to userland.  We can perform reclaim here
-        * if __GFP_WAIT but let's always punt for simplicity and so that
+        * if __GFP_RECLAIM but let's always punt for simplicity and so that
         * GFP_KERNEL can consistently be used during reclaim.  @memcg is
         * not recorded as it most likely matches current's and won't
         * change in the meantime.  As high limit is checked again before
@@ -2381,14 +2381,13 @@ int __memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order,
 {
        unsigned int nr_pages = 1 << order;
        struct page_counter *counter;
-       int ret = 0;
+       int ret;
 
        if (!memcg_kmem_is_active(memcg))
                return 0;
 
-       ret = page_counter_try_charge(&memcg->kmem, nr_pages, &counter);
-       if (ret)
-               return ret;
+       if (!page_counter_try_charge(&memcg->kmem, nr_pages, &counter))
+               return -ENOMEM;
 
        ret = try_charge(memcg, gfp, nr_pages);
        if (ret) {
@@ -2430,24 +2429,6 @@ void __memcg_kmem_uncharge(struct page *page, int order)
        page->mem_cgroup = NULL;
        css_put_many(&memcg->css, nr_pages);
 }
-
-struct mem_cgroup *__mem_cgroup_from_kmem(void *ptr)
-{
-       struct mem_cgroup *memcg = NULL;
-       struct kmem_cache *cachep;
-       struct page *page;
-
-       page = virt_to_head_page(ptr);
-       if (PageSlab(page)) {
-               cachep = page->slab_cache;
-               if (!is_root_cache(cachep))
-                       memcg = cachep->memcg_params.memcg;
-       } else
-               /* page allocated by alloc_kmem_pages */
-               memcg = page->mem_cgroup;
-
-       return memcg;
-}
 #endif /* CONFIG_MEMCG_KMEM */
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -2820,9 +2801,9 @@ static unsigned long tree_stat(struct mem_cgroup *memcg,
        return val;
 }
 
-static inline u64 mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
+static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
 {
-       u64 val;
+       unsigned long val;
 
        if (mem_cgroup_is_root(memcg)) {
                val = tree_stat(memcg, MEM_CGROUP_STAT_CACHE);
@@ -2835,7 +2816,7 @@ static inline u64 mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
                else
                        val = page_counter_read(&memcg->memsw);
        }
-       return val << PAGE_SHIFT;
+       return val;
 }
 
 enum {
@@ -2869,9 +2850,9 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
        switch (MEMFILE_ATTR(cft->private)) {
        case RES_USAGE:
                if (counter == &memcg->memory)
-                       return mem_cgroup_usage(memcg, false);
+                       return (u64)mem_cgroup_usage(memcg, false) * PAGE_SIZE;
                if (counter == &memcg->memsw)
-                       return mem_cgroup_usage(memcg, true);
+                       return (u64)mem_cgroup_usage(memcg, true) * PAGE_SIZE;
                return (u64)page_counter_read(counter) * PAGE_SIZE;
        case RES_LIMIT:
                return (u64)counter->limit * PAGE_SIZE;
@@ -2910,7 +2891,7 @@ static int memcg_activate_kmem(struct mem_cgroup *memcg,
         * of course permitted.
         */
        mutex_lock(&memcg_create_mutex);
-       if (cgroup_has_tasks(memcg->css.cgroup) ||
+       if (cgroup_is_populated(memcg->css.cgroup) ||
            (memcg->use_hierarchy && memcg_has_children(memcg)))
                err = -EBUSY;
        mutex_unlock(&memcg_create_mutex);
@@ -3371,7 +3352,6 @@ static int __mem_cgroup_usage_register_event(struct mem_cgroup *memcg,
        ret = page_counter_memparse(args, "-1", &threshold);
        if (ret)
                return ret;
-       threshold <<= PAGE_SHIFT;
 
        mutex_lock(&memcg->thresholds_lock);
 
@@ -4050,8 +4030,7 @@ static struct cftype mem_cgroup_legacy_files[] = {
        {
                .name = "cgroup.event_control",         /* XXX: for compat */
                .write = memcg_write_event_control,
-               .flags = CFTYPE_NO_PREFIX,
-               .mode = S_IWUGO,
+               .flags = CFTYPE_NO_PREFIX | CFTYPE_WORLD_WRITABLE,
        },
        {
                .name = "swappiness",
@@ -4385,8 +4364,8 @@ static int mem_cgroup_do_precharge(unsigned long count)
 {
        int ret;
 
-       /* Try a single bulk charge without reclaim first */
-       ret = try_charge(mc.to, GFP_KERNEL & ~__GFP_WAIT, count);
+       /* Try a single bulk charge without reclaim first, kswapd may wake */
+       ret = try_charge(mc.to, GFP_KERNEL & ~__GFP_DIRECT_RECLAIM, count);
        if (!ret) {
                mc.precharge += count;
                return ret;
@@ -4549,9 +4528,8 @@ static int mem_cgroup_move_account(struct page *page,
                goto out;
 
        /*
-        * Prevent mem_cgroup_migrate() from looking at page->mem_cgroup
-        * of its source page while we change it: page migration takes
-        * both pages off the LRU, but page cache replacement doesn't.
+        * Prevent mem_cgroup_replace_page() from looking at
+        * page->mem_cgroup of its source page while we change it.
         */
        if (!trylock_page(page))
                goto out;
@@ -4806,7 +4784,7 @@ static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
        struct mem_cgroup *from;
-       struct task_struct *p;
+       struct task_struct *leader, *p;
        struct mm_struct *mm;
        unsigned long move_flags;
        int ret = 0;
@@ -4820,7 +4798,20 @@ static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
        if (!move_flags)
                return 0;
 
-       p = cgroup_taskset_first(tset);
+       /*
+        * Multi-process migrations only happen on the default hierarchy
+        * where charge immigration is not used.  Perform charge
+        * immigration if @tset contains a leader and whine if there are
+        * multiple.
+        */
+       p = NULL;
+       cgroup_taskset_for_each_leader(leader, tset) {
+               WARN_ON_ONCE(p);
+               p = leader;
+       }
+       if (!p)
+               return 0;
+
        from = mem_cgroup_from_task(p);
 
        VM_BUG_ON(from == memcg);
@@ -5036,7 +5027,7 @@ static void mem_cgroup_bind(struct cgroup_subsys_state *root_css)
         * guarantees that @root doesn't have any children, so turning it
         * on for the root memcg is enough.
         */
-       if (cgroup_on_dfl(root_css->cgroup))
+       if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
                root_mem_cgroup->use_hierarchy = true;
        else
                root_mem_cgroup->use_hierarchy = false;
@@ -5045,7 +5036,9 @@ static void mem_cgroup_bind(struct cgroup_subsys_state *root_css)
 static u64 memory_current_read(struct cgroup_subsys_state *css,
                               struct cftype *cft)
 {
-       return mem_cgroup_usage(mem_cgroup_from_css(css), false);
+       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+
+       return (u64)page_counter_read(&memcg->memory) * PAGE_SIZE;
 }
 
 static int memory_low_show(struct seq_file *m, void *v)
@@ -5157,6 +5150,7 @@ static int memory_events_show(struct seq_file *m, void *v)
 static struct cftype memory_files[] = {
        {
                .name = "current",
+               .flags = CFTYPE_NOT_ON_ROOT,
                .read_u64 = memory_current_read,
        },
        {
@@ -5180,6 +5174,7 @@ static struct cftype memory_files[] = {
        {
                .name = "events",
                .flags = CFTYPE_NOT_ON_ROOT,
+               .file_offset = offsetof(struct mem_cgroup, events_file),
                .seq_show = memory_events_show,
        },
        { }     /* terminate */
@@ -5513,7 +5508,7 @@ void mem_cgroup_uncharge_list(struct list_head *page_list)
 }
 
 /**
- * mem_cgroup_migrate - migrate a charge to another page
+ * mem_cgroup_replace_page - migrate a charge to another page
  * @oldpage: currently charged page
  * @newpage: page to transfer the charge to
  * @lrucare: either or both pages might be on the LRU already
@@ -5522,16 +5517,13 @@ void mem_cgroup_uncharge_list(struct list_head *page_list)
  *
  * Both pages must be locked, @newpage->mapping must be set up.
  */
-void mem_cgroup_migrate(struct page *oldpage, struct page *newpage,
-                       bool lrucare)
+void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage)
 {
        struct mem_cgroup *memcg;
        int isolated;
 
        VM_BUG_ON_PAGE(!PageLocked(oldpage), oldpage);
        VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
-       VM_BUG_ON_PAGE(!lrucare && PageLRU(oldpage), oldpage);
-       VM_BUG_ON_PAGE(!lrucare && PageLRU(newpage), newpage);
        VM_BUG_ON_PAGE(PageAnon(oldpage) != PageAnon(newpage), newpage);
        VM_BUG_ON_PAGE(PageTransHuge(oldpage) != PageTransHuge(newpage),
                       newpage);
@@ -5543,25 +5535,16 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage,
        if (newpage->mem_cgroup)
                return;
 
-       /*
-        * Swapcache readahead pages can get migrated before being
-        * charged, and migration from compaction can happen to an
-        * uncharged page when the PFN walker finds a page that
-        * reclaim just put back on the LRU but has not released yet.
-        */
+       /* Swapcache readahead pages can get replaced before being charged */
        memcg = oldpage->mem_cgroup;
        if (!memcg)
                return;
 
-       if (lrucare)
-               lock_page_lru(oldpage, &isolated);
-
+       lock_page_lru(oldpage, &isolated);
        oldpage->mem_cgroup = NULL;
+       unlock_page_lru(oldpage, isolated);
 
-       if (lrucare)
-               unlock_page_lru(oldpage, isolated);
-
-       commit_charge(newpage, memcg, lrucare);
+       commit_charge(newpage, memcg, true);
 }
 
 /*