cgroup: remove css_parent()
[linux-2.6-block.git] / mm / memcontrol.c
index 5b6b0039f725032de5d63376aa0388e49bd3192d..a5e0417b4f9aa34f2d60eacc2201d5621163bce1 100644 (file)
@@ -66,8 +66,8 @@
 
 #include <trace/events/vmscan.h>
 
-struct cgroup_subsys mem_cgroup_subsys __read_mostly;
-EXPORT_SYMBOL(mem_cgroup_subsys);
+struct cgroup_subsys memory_cgrp_subsys __read_mostly;
+EXPORT_SYMBOL(memory_cgrp_subsys);
 
 #define MEM_CGROUP_RECLAIM_RETRIES     5
 static struct mem_cgroup *root_mem_cgroup __read_mostly;
@@ -527,18 +527,14 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
 
 static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
 {
-       /*
-        * The ID of the root cgroup is 0, but memcg treat 0 as an
-        * invalid ID, so we return (cgroup_id + 1).
-        */
-       return memcg->css.cgroup->id + 1;
+       return memcg->css.id;
 }
 
 static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
 {
        struct cgroup_subsys_state *css;
 
-       css = css_from_id(id - 1, &mem_cgroup_subsys);
+       css = css_from_id(id, &memory_cgrp_subsys);
        return mem_cgroup_from_css(css);
 }
 
@@ -571,7 +567,8 @@ void sock_update_memcg(struct sock *sk)
                memcg = mem_cgroup_from_task(current);
                cg_proto = sk->sk_prot->proto_cgroup(memcg);
                if (!mem_cgroup_is_root(memcg) &&
-                   memcg_proto_active(cg_proto) && css_tryget(&memcg->css)) {
+                   memcg_proto_active(cg_proto) &&
+                   css_tryget_online(&memcg->css)) {
                        sk->sk_cgrp = cg_proto;
                }
                rcu_read_unlock();
@@ -838,7 +835,7 @@ retry:
         */
        __mem_cgroup_remove_exceeded(mz->memcg, mz, mctz);
        if (!res_counter_soft_limit_excess(&mz->memcg->res) ||
-               !css_tryget(&mz->memcg->css))
+           !css_tryget_online(&mz->memcg->css))
                goto retry;
 done:
        return mz;
@@ -921,8 +918,6 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *memcg,
                                         struct page *page,
                                         bool anon, int nr_pages)
 {
-       preempt_disable();
-
        /*
         * Here, RSS means 'mapped anon' and anon's SwapCache. Shmem/tmpfs is
         * counted as CACHE even if it's on ANON LRU.
@@ -947,8 +942,6 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *memcg,
        }
 
        __this_cpu_add(memcg->stat->nr_page_events, nr_pages);
-
-       preempt_enable();
 }
 
 unsigned long
@@ -1072,26 +1065,19 @@ struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
        if (unlikely(!p))
                return NULL;
 
-       return mem_cgroup_from_css(task_css(p, mem_cgroup_subsys_id));
+       return mem_cgroup_from_css(task_css(p, memory_cgrp_id));
 }
 
-struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm)
+static struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm)
 {
        struct mem_cgroup *memcg = NULL;
 
-       if (!mm)
-               return NULL;
-       /*
-        * Because we have no locks, mm->owner's may be being moved to other
-        * cgroup. We use css_tryget() here even if this looks
-        * pessimistic (rather than adding locks here).
-        */
        rcu_read_lock();
        do {
                memcg = mem_cgroup_from_task(rcu_dereference(mm->owner));
                if (unlikely(!memcg))
-                       break;
-       } while (!css_tryget(&memcg->css));
+                       memcg = root_mem_cgroup;
+       } while (!css_tryget_online(&memcg->css));
        rcu_read_unlock();
        return memcg;
 }
@@ -1128,7 +1114,8 @@ skip_node:
         */
        if (next_css) {
                if ((next_css == &root->css) ||
-                   ((next_css->flags & CSS_ONLINE) && css_tryget(next_css)))
+                   ((next_css->flags & CSS_ONLINE) &&
+                    css_tryget_online(next_css)))
                        return mem_cgroup_from_css(next_css);
 
                prev_css = next_css;
@@ -1174,7 +1161,7 @@ mem_cgroup_iter_load(struct mem_cgroup_reclaim_iter *iter,
                 * would be returned all the time.
                 */
                if (position && position != root &&
-                               !css_tryget(&position->css))
+                   !css_tryget_online(&position->css))
                        position = NULL;
        }
        return position;
@@ -1486,7 +1473,7 @@ bool task_in_mem_cgroup(struct task_struct *task,
 
        p = find_lock_task_mm(task);
        if (p) {
-               curr = try_get_mem_cgroup_from_mm(p->mm);
+               curr = get_mem_cgroup_from_mm(p->mm);
                task_unlock(p);
        } else {
                /*
@@ -1500,8 +1487,6 @@ bool task_in_mem_cgroup(struct task_struct *task,
                        css_get(&curr->css);
                rcu_read_unlock();
        }
-       if (!curr)
-               return false;
        /*
         * We should check use_hierarchy of "memcg" not "curr". Because checking
         * use_hierarchy of "curr" here make this function true if hierarchy is
@@ -1555,7 +1540,7 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg)
 int mem_cgroup_swappiness(struct mem_cgroup *memcg)
 {
        /* root ? */
-       if (!css_parent(&memcg->css))
+       if (!memcg->css.parent)
                return vm_swappiness;
 
        return memcg->swappiness;
@@ -1683,15 +1668,8 @@ static void move_unlock_mem_cgroup(struct mem_cgroup *memcg,
  */
 void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
 {
-       /*
-        * protects memcg_name and makes sure that parallel ooms do not
-        * interleave
-        */
+       /* oom_info_lock ensures that parallel ooms do not interleave */
        static DEFINE_MUTEX(oom_info_lock);
-       struct cgroup *task_cgrp;
-       struct cgroup *mem_cgrp;
-       static char memcg_name[PATH_MAX];
-       int ret;
        struct mem_cgroup *iter;
        unsigned int i;
 
@@ -1701,36 +1679,14 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
        mutex_lock(&oom_info_lock);
        rcu_read_lock();
 
-       mem_cgrp = memcg->css.cgroup;
-       task_cgrp = task_cgroup(p, mem_cgroup_subsys_id);
-
-       ret = cgroup_path(task_cgrp, memcg_name, PATH_MAX);
-       if (ret < 0) {
-               /*
-                * Unfortunately, we are unable to convert to a useful name
-                * But we'll still print out the usage information
-                */
-               rcu_read_unlock();
-               goto done;
-       }
-       rcu_read_unlock();
+       pr_info("Task in ");
+       pr_cont_cgroup_path(task_cgroup(p, memory_cgrp_id));
+       pr_info(" killed as a result of limit of ");
+       pr_cont_cgroup_path(memcg->css.cgroup);
+       pr_info("\n");
 
-       pr_info("Task in %s killed", memcg_name);
-
-       rcu_read_lock();
-       ret = cgroup_path(mem_cgrp, memcg_name, PATH_MAX);
-       if (ret < 0) {
-               rcu_read_unlock();
-               goto done;
-       }
        rcu_read_unlock();
 
-       /*
-        * Continues from above, so we don't need an KERN_ level
-        */
-       pr_cont(" as a result of limit of %s\n", memcg_name);
-done:
-
        pr_info("memory: usage %llukB, limit %llukB, failcnt %llu\n",
                res_counter_read_u64(&memcg->res, RES_USAGE) >> 10,
                res_counter_read_u64(&memcg->res, RES_LIMIT) >> 10,
@@ -1745,13 +1701,8 @@ done:
                res_counter_read_u64(&memcg->kmem, RES_FAILCNT));
 
        for_each_mem_cgroup_tree(iter, memcg) {
-               pr_info("Memory cgroup stats");
-
-               rcu_read_lock();
-               ret = cgroup_path(iter->css.cgroup, memcg_name, PATH_MAX);
-               if (!ret)
-                       pr_cont(" for %s", memcg_name);
-               rcu_read_unlock();
+               pr_info("Memory cgroup stats for ");
+               pr_cont_cgroup_path(iter->css.cgroup);
                pr_cont(":");
 
                for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) {
@@ -2622,7 +2573,7 @@ static int memcg_cpu_hotplug_callback(struct notifier_block *nb,
 }
 
 
-/* See __mem_cgroup_try_charge() for details */
+/* See mem_cgroup_try_charge() for details */
 enum {
        CHARGE_OK,              /* success */
        CHARGE_RETRY,           /* need to retry but retry is not bad */
@@ -2695,45 +2646,34 @@ static int mem_cgroup_do_charge(struct mem_cgroup *memcg, gfp_t gfp_mask,
        return CHARGE_NOMEM;
 }
 
-/*
- * __mem_cgroup_try_charge() does
- * 1. detect memcg to be charged against from passed *mm and *ptr,
- * 2. update res_counter
- * 3. call memory reclaim if necessary.
- *
- * In some special case, if the task is fatal, fatal_signal_pending() or
- * has TIF_MEMDIE, this function returns -EINTR while writing root_mem_cgroup
- * to *ptr. There are two reasons for this. 1: fatal threads should quit as soon
- * as possible without any hazards. 2: all pages should have a valid
- * pc->mem_cgroup. If mm is NULL and the caller doesn't pass a valid memcg
- * pointer, that is treated as a charge to root_mem_cgroup.
- *
- * So __mem_cgroup_try_charge() will return
- *  0       ...  on success, filling *ptr with a valid memcg pointer.
- *  -ENOMEM ...  charge failure because of resource limits.
- *  -EINTR  ...  if thread is fatal. *ptr is filled with root_mem_cgroup.
+/**
+ * mem_cgroup_try_charge - try charging a memcg
+ * @memcg: memcg to charge
+ * @nr_pages: number of pages to charge
+ * @oom: trigger OOM if reclaim fails
  *
- * Unlike the exported interface, an "oom" parameter is added. if oom==true,
- * the oom-killer can be invoked.
+ * Returns 0 if @memcg was charged successfully, -EINTR if the charge
+ * was bypassed to root_mem_cgroup, and -ENOMEM if the charge failed.
  */
-static int __mem_cgroup_try_charge(struct mm_struct *mm,
-                                  gfp_t gfp_mask,
-                                  unsigned int nr_pages,
-                                  struct mem_cgroup **ptr,
-                                  bool oom)
+static int mem_cgroup_try_charge(struct mem_cgroup *memcg,
+                                gfp_t gfp_mask,
+                                unsigned int nr_pages,
+                                bool oom)
 {
        unsigned int batch = max(CHARGE_BATCH, nr_pages);
        int nr_oom_retries = MEM_CGROUP_RECLAIM_RETRIES;
-       struct mem_cgroup *memcg = NULL;
        int ret;
 
+       if (mem_cgroup_is_root(memcg))
+               goto done;
        /*
-        * Unlike gloval-vm's OOM-kill, we're not in memory shortage
-        * in system level. So, allow to go ahead dying process in addition to
-        * MEMDIE process.
+        * Unlike in global OOM situations, memcg is not in a physical
+        * memory shortage.  Allow dying and OOM-killed tasks to
+        * bypass the last charges so that they can exit quickly and
+        * free their memory.
         */
-       if (unlikely(test_thread_flag(TIF_MEMDIE)
-                    || fatal_signal_pending(current)))
+       if (unlikely(test_thread_flag(TIF_MEMDIE) ||
+                    fatal_signal_pending(current)))
                goto bypass;
 
        if (unlikely(task_in_memcg_oom(current)))
@@ -2741,73 +2681,16 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
 
        if (gfp_mask & __GFP_NOFAIL)
                oom = false;
-
-       /*
-        * We always charge the cgroup the mm_struct belongs to.
-        * The mm_struct's mem_cgroup changes on task migration if the
-        * thread group leader migrates. It's possible that mm is not
-        * set, if so charge the root memcg (happens for pagecache usage).
-        */
-       if (!*ptr && !mm)
-               *ptr = root_mem_cgroup;
 again:
-       if (*ptr) { /* css should be a valid one */
-               memcg = *ptr;
-               if (mem_cgroup_is_root(memcg))
-                       goto done;
-               if (consume_stock(memcg, nr_pages))
-                       goto done;
-               css_get(&memcg->css);
-       } else {
-               struct task_struct *p;
-
-               rcu_read_lock();
-               p = rcu_dereference(mm->owner);
-               /*
-                * Because we don't have task_lock(), "p" can exit.
-                * In that case, "memcg" can point to root or p can be NULL with
-                * race with swapoff. Then, we have small risk of mis-accouning.
-                * But such kind of mis-account by race always happens because
-                * we don't have cgroup_mutex(). It's overkill and we allo that
-                * small race, here.
-                * (*) swapoff at el will charge against mm-struct not against
-                * task-struct. So, mm->owner can be NULL.
-                */
-               memcg = mem_cgroup_from_task(p);
-               if (!memcg)
-                       memcg = root_mem_cgroup;
-               if (mem_cgroup_is_root(memcg)) {
-                       rcu_read_unlock();
-                       goto done;
-               }
-               if (consume_stock(memcg, nr_pages)) {
-                       /*
-                        * It seems dagerous to access memcg without css_get().
-                        * But considering how consume_stok works, it's not
-                        * necessary. If consume_stock success, some charges
-                        * from this memcg are cached on this cpu. So, we
-                        * don't need to call css_get()/css_tryget() before
-                        * calling consume_stock().
-                        */
-                       rcu_read_unlock();
-                       goto done;
-               }
-               /* after here, we may be blocked. we need to get refcnt */
-               if (!css_tryget(&memcg->css)) {
-                       rcu_read_unlock();
-                       goto again;
-               }
-               rcu_read_unlock();
-       }
+       if (consume_stock(memcg, nr_pages))
+               goto done;
 
        do {
                bool invoke_oom = oom && !nr_oom_retries;
 
                /* If killed, bypass charge */
-               if (fatal_signal_pending(current)) {
-                       css_put(&memcg->css);
+               if (fatal_signal_pending(current))
                        goto bypass;
-               }
 
                ret = mem_cgroup_do_charge(memcg, gfp_mask, batch,
                                           nr_pages, invoke_oom);
@@ -2816,17 +2699,12 @@ again:
                        break;
                case CHARGE_RETRY: /* not in OOM situation but retry */
                        batch = nr_pages;
-                       css_put(&memcg->css);
-                       memcg = NULL;
                        goto again;
                case CHARGE_WOULDBLOCK: /* !__GFP_WAIT */
-                       css_put(&memcg->css);
                        goto nomem;
                case CHARGE_NOMEM: /* OOM routine works */
-                       if (!oom || invoke_oom) {
-                               css_put(&memcg->css);
+                       if (!oom || invoke_oom)
                                goto nomem;
-                       }
                        nr_oom_retries--;
                        break;
                }
@@ -2834,20 +2712,44 @@ again:
 
        if (batch > nr_pages)
                refill_stock(memcg, batch - nr_pages);
-       css_put(&memcg->css);
 done:
-       *ptr = memcg;
        return 0;
 nomem:
-       if (!(gfp_mask & __GFP_NOFAIL)) {
-               *ptr = NULL;
+       if (!(gfp_mask & __GFP_NOFAIL))
                return -ENOMEM;
-       }
 bypass:
-       *ptr = root_mem_cgroup;
        return -EINTR;
 }
 
+/**
+ * mem_cgroup_try_charge_mm - try charging a mm
+ * @mm: mm_struct to charge
+ * @nr_pages: number of pages to charge
+ * @oom: trigger OOM if reclaim fails
+ *
+ * Returns the charged mem_cgroup associated with the given mm_struct or
+ * NULL the charge failed.
+ */
+static struct mem_cgroup *mem_cgroup_try_charge_mm(struct mm_struct *mm,
+                                gfp_t gfp_mask,
+                                unsigned int nr_pages,
+                                bool oom)
+
+{
+       struct mem_cgroup *memcg;
+       int ret;
+
+       memcg = get_mem_cgroup_from_mm(mm);
+       ret = mem_cgroup_try_charge(memcg, gfp_mask, nr_pages, oom);
+       css_put(&memcg->css);
+       if (ret == -EINTR)
+               memcg = root_mem_cgroup;
+       else if (ret)
+               memcg = NULL;
+
+       return memcg;
+}
+
 /*
  * Somemtimes we have to undo a charge we got by try_charge().
  * This function is for that and do uncharge, put css's refcnt.
@@ -2885,9 +2787,9 @@ static void __mem_cgroup_cancel_local_charge(struct mem_cgroup *memcg,
 
 /*
  * A helper function to get mem_cgroup from ID. must be called under
- * rcu_read_lock().  The caller is responsible for calling css_tryget if
- * the mem_cgroup is used for charging. (dropping refcnt from swap can be
- * called against removed memcg.)
+ * rcu_read_lock().  The caller is responsible for calling
+ * css_tryget_online() if the mem_cgroup is used for charging. (dropping
+ * refcnt from swap can be called against removed memcg.)
  */
 static struct mem_cgroup *mem_cgroup_lookup(unsigned short id)
 {
@@ -2910,14 +2812,14 @@ struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
        lock_page_cgroup(pc);
        if (PageCgroupUsed(pc)) {
                memcg = pc->mem_cgroup;
-               if (memcg && !css_tryget(&memcg->css))
+               if (memcg && !css_tryget_online(&memcg->css))
                        memcg = NULL;
        } else if (PageSwapCache(page)) {
                ent.val = page_private(page);
                id = lookup_swap_cgroup_id(ent);
                rcu_read_lock();
                memcg = mem_cgroup_lookup(id);
-               if (memcg && !css_tryget(&memcg->css))
+               if (memcg && !css_tryget_online(&memcg->css))
                        memcg = NULL;
                rcu_read_unlock();
        }
@@ -3043,20 +2945,17 @@ static int mem_cgroup_slabinfo_read(struct seq_file *m, void *v)
 static int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size)
 {
        struct res_counter *fail_res;
-       struct mem_cgroup *_memcg;
        int ret = 0;
 
        ret = res_counter_charge(&memcg->kmem, size, &fail_res);
        if (ret)
                return ret;
 
-       _memcg = memcg;
-       ret = __mem_cgroup_try_charge(NULL, gfp, size >> PAGE_SHIFT,
-                                     &_memcg, oom_gfp_allowed(gfp));
-
+       ret = mem_cgroup_try_charge(memcg, gfp, size >> PAGE_SHIFT,
+                                   oom_gfp_allowed(gfp));
        if (ret == -EINTR)  {
                /*
-                * __mem_cgroup_try_charge() chosed to bypass to root due to
+                * mem_cgroup_try_charge() chosed to bypass to root due to
                 * OOM kill or fatal signal.  Since our only options are to
                 * either fail the allocation or charge it to this cgroup, do
                 * it as a temporary condition. But we can't fail. From a
@@ -3066,7 +2965,7 @@ static int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size)
                 *
                 * This condition will only trigger if the task entered
                 * memcg_charge_kmem in a sane state, but was OOM-killed during
-                * __mem_cgroup_try_charge() above. Tasks that were already
+                * mem_cgroup_try_charge() above. Tasks that were already
                 * dying when the allocation triggers should have been already
                 * directed to the root cgroup in memcontrol.h
                 */
@@ -3193,6 +3092,29 @@ int memcg_update_cache_size(struct kmem_cache *s, int num_groups)
        return 0;
 }
 
+char *memcg_create_cache_name(struct mem_cgroup *memcg,
+                             struct kmem_cache *root_cache)
+{
+       static char *buf = NULL;
+
+       /*
+        * We need a mutex here to protect the shared buffer. Since this is
+        * expected to be called only on cache creation, we can employ the
+        * slab_mutex for that purpose.
+        */
+       lockdep_assert_held(&slab_mutex);
+
+       if (!buf) {
+               buf = kmalloc(NAME_MAX + 1, GFP_KERNEL);
+               if (!buf)
+                       return NULL;
+       }
+
+       cgroup_name(memcg->css.cgroup, buf, NAME_MAX + 1);
+       return kasprintf(GFP_KERNEL, "%s(%d:%s)", root_cache->name,
+                        memcg_cache_id(memcg), buf);
+}
+
 int memcg_alloc_cache_params(struct mem_cgroup *memcg, struct kmem_cache *s,
                             struct kmem_cache *root_cache)
 {
@@ -3216,6 +3138,7 @@ int memcg_alloc_cache_params(struct mem_cgroup *memcg, struct kmem_cache *s,
                s->memcg_params->root_cache = root_cache;
                INIT_WORK(&s->memcg_params->destroy,
                                kmem_cache_destroy_work_func);
+               css_get(&memcg->css);
        } else
                s->memcg_params->is_root_cache = true;
 
@@ -3224,6 +3147,10 @@ int memcg_alloc_cache_params(struct mem_cgroup *memcg, struct kmem_cache *s,
 
 void memcg_free_cache_params(struct kmem_cache *s)
 {
+       if (!s->memcg_params)
+               return;
+       if (!s->memcg_params->is_root_cache)
+               css_put(&s->memcg_params->memcg->css);
        kfree(s->memcg_params);
 }
 
@@ -3246,9 +3173,6 @@ void memcg_register_cache(struct kmem_cache *s)
        memcg = s->memcg_params->memcg;
        id = memcg_cache_id(memcg);
 
-       css_get(&memcg->css);
-
-
        /*
         * Since readers won't lock (see cache_from_memcg_idx()), we need a
         * barrier here to ensure nobody will see the kmem_cache partially
@@ -3297,10 +3221,8 @@ void memcg_unregister_cache(struct kmem_cache *s)
         * after removing it from the memcg_slab_caches list, otherwise we can
         * fail to convert memcg_params_to_cache() while traversing the list.
         */
-       VM_BUG_ON(!root->memcg_params->memcg_caches[id]);
+       VM_BUG_ON(root->memcg_params->memcg_caches[id] != s);
        root->memcg_params->memcg_caches[id] = NULL;
-
-       css_put(&memcg->css);
 }
 
 /*
@@ -3397,53 +3319,10 @@ void mem_cgroup_destroy_cache(struct kmem_cache *cachep)
        schedule_work(&cachep->memcg_params->destroy);
 }
 
-static struct kmem_cache *memcg_create_kmem_cache(struct mem_cgroup *memcg,
-                                                 struct kmem_cache *s)
-{
-       struct kmem_cache *new = NULL;
-       static char *tmp_name = NULL;
-       static DEFINE_MUTEX(mutex);     /* protects tmp_name */
-
-       BUG_ON(!memcg_can_account_kmem(memcg));
-
-       mutex_lock(&mutex);
-       /*
-        * kmem_cache_create_memcg duplicates the given name and
-        * cgroup_name for this name requires RCU context.
-        * This static temporary buffer is used to prevent from
-        * pointless shortliving allocation.
-        */
-       if (!tmp_name) {
-               tmp_name = kmalloc(PATH_MAX, GFP_KERNEL);
-               if (!tmp_name)
-                       goto out;
-       }
-
-       rcu_read_lock();
-       snprintf(tmp_name, PATH_MAX, "%s(%d:%s)", s->name,
-                        memcg_cache_id(memcg), cgroup_name(memcg->css.cgroup));
-       rcu_read_unlock();
-
-       new = kmem_cache_create_memcg(memcg, tmp_name, s->object_size, s->align,
-                                     (s->flags & ~SLAB_PANIC), s->ctor, s);
-       if (new)
-               new->allocflags |= __GFP_KMEMCG;
-       else
-               new = s;
-out:
-       mutex_unlock(&mutex);
-       return new;
-}
-
-void kmem_cache_destroy_memcg_children(struct kmem_cache *s)
+int __kmem_cache_destroy_memcg_children(struct kmem_cache *s)
 {
        struct kmem_cache *c;
-       int i;
-
-       if (!s->memcg_params)
-               return;
-       if (!s->memcg_params->is_root_cache)
-               return;
+       int i, failed = 0;
 
        /*
         * If the cache is being destroyed, we trust that there is no one else
@@ -3477,16 +3356,14 @@ void kmem_cache_destroy_memcg_children(struct kmem_cache *s)
                c->memcg_params->dead = false;
                cancel_work_sync(&c->memcg_params->destroy);
                kmem_cache_destroy(c);
+
+               if (cache_from_memcg_idx(s, i))
+                       failed++;
        }
        mutex_unlock(&activate_kmem_mutex);
+       return failed;
 }
 
-struct create_work {
-       struct mem_cgroup *memcg;
-       struct kmem_cache *cachep;
-       struct work_struct work;
-};
-
 static void mem_cgroup_destroy_all_caches(struct mem_cgroup *memcg)
 {
        struct kmem_cache *cachep;
@@ -3504,13 +3381,20 @@ static void mem_cgroup_destroy_all_caches(struct mem_cgroup *memcg)
        mutex_unlock(&memcg->slab_caches_mutex);
 }
 
+struct create_work {
+       struct mem_cgroup *memcg;
+       struct kmem_cache *cachep;
+       struct work_struct work;
+};
+
 static void memcg_create_cache_work_func(struct work_struct *w)
 {
-       struct create_work *cw;
+       struct create_work *cw = container_of(w, struct create_work, work);
+       struct mem_cgroup *memcg = cw->memcg;
+       struct kmem_cache *cachep = cw->cachep;
 
-       cw = container_of(w, struct create_work, work);
-       memcg_create_kmem_cache(cw->memcg, cw->cachep);
-       css_put(&cw->memcg->css);
+       kmem_cache_create_memcg(memcg, cachep);
+       css_put(&memcg->css);
        kfree(cw);
 }
 
@@ -3591,7 +3475,7 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep,
        }
 
        /* The corresponding put will be done in the workqueue. */
-       if (!css_tryget(&memcg->css))
+       if (!css_tryget_online(&memcg->css))
                goto out;
        rcu_read_unlock();
 
@@ -3669,15 +3553,7 @@ __memcg_kmem_newpage_charge(gfp_t gfp, struct mem_cgroup **_memcg, int order)
        if (!current->mm || current->memcg_kmem_skip_account)
                return true;
 
-       memcg = try_get_mem_cgroup_from_mm(current->mm);
-
-       /*
-        * very rare case described in mem_cgroup_from_task. Unfortunately there
-        * isn't much we can do without complicating this too much, and it would
-        * be gfp-dependent anyway. Just let it go
-        */
-       if (unlikely(!memcg))
-               return true;
+       memcg = get_mem_cgroup_from_mm(current->mm);
 
        if (!memcg_can_account_kmem(memcg)) {
                css_put(&memcg->css);
@@ -3780,19 +3656,6 @@ void mem_cgroup_split_huge_fixup(struct page *head)
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
-static inline
-void mem_cgroup_move_account_page_stat(struct mem_cgroup *from,
-                                       struct mem_cgroup *to,
-                                       unsigned int nr_pages,
-                                       enum mem_cgroup_stat_index idx)
-{
-       /* Update stat data for mem_cgroup */
-       preempt_disable();
-       __this_cpu_sub(from->stat->count[idx], nr_pages);
-       __this_cpu_add(to->stat->count[idx], nr_pages);
-       preempt_enable();
-}
-
 /**
  * mem_cgroup_move_account - move account of the page
  * @page: the page
@@ -3838,13 +3701,19 @@ static int mem_cgroup_move_account(struct page *page,
 
        move_lock_mem_cgroup(from, &flags);
 
-       if (!anon && page_mapped(page))
-               mem_cgroup_move_account_page_stat(from, to, nr_pages,
-                       MEM_CGROUP_STAT_FILE_MAPPED);
+       if (!anon && page_mapped(page)) {
+               __this_cpu_sub(from->stat->count[MEM_CGROUP_STAT_FILE_MAPPED],
+                              nr_pages);
+               __this_cpu_add(to->stat->count[MEM_CGROUP_STAT_FILE_MAPPED],
+                              nr_pages);
+       }
 
-       if (PageWriteback(page))
-               mem_cgroup_move_account_page_stat(from, to, nr_pages,
-                       MEM_CGROUP_STAT_WRITEBACK);
+       if (PageWriteback(page)) {
+               __this_cpu_sub(from->stat->count[MEM_CGROUP_STAT_WRITEBACK],
+                              nr_pages);
+               __this_cpu_add(to->stat->count[MEM_CGROUP_STAT_WRITEBACK],
+                              nr_pages);
+       }
 
        mem_cgroup_charge_statistics(from, page, anon, -nr_pages);
 
@@ -3930,19 +3799,19 @@ out:
        return ret;
 }
 
-/*
- * Charge the memory controller for page usage.
- * Return
- * 0 if the charge was successful
- * < 0 if the cgroup is over its limit
- */
-static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
-                               gfp_t gfp_mask, enum charge_type ctype)
+int mem_cgroup_charge_anon(struct page *page,
+                             struct mm_struct *mm, gfp_t gfp_mask)
 {
-       struct mem_cgroup *memcg = NULL;
        unsigned int nr_pages = 1;
+       struct mem_cgroup *memcg;
        bool oom = true;
-       int ret;
+
+       if (mem_cgroup_disabled())
+               return 0;
+
+       VM_BUG_ON_PAGE(page_mapped(page), page);
+       VM_BUG_ON_PAGE(page->mapping && !PageAnon(page), page);
+       VM_BUG_ON(!mm);
 
        if (PageTransHuge(page)) {
                nr_pages <<= compound_order(page);
@@ -3954,25 +3823,14 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
                oom = false;
        }
 
-       ret = __mem_cgroup_try_charge(mm, gfp_mask, nr_pages, &memcg, oom);
-       if (ret == -ENOMEM)
-               return ret;
-       __mem_cgroup_commit_charge(memcg, page, nr_pages, ctype, false);
+       memcg = mem_cgroup_try_charge_mm(mm, gfp_mask, nr_pages, oom);
+       if (!memcg)
+               return -ENOMEM;
+       __mem_cgroup_commit_charge(memcg, page, nr_pages,
+                                  MEM_CGROUP_CHARGE_TYPE_ANON, false);
        return 0;
 }
 
-int mem_cgroup_newpage_charge(struct page *page,
-                             struct mm_struct *mm, gfp_t gfp_mask)
-{
-       if (mem_cgroup_disabled())
-               return 0;
-       VM_BUG_ON_PAGE(page_mapped(page), page);
-       VM_BUG_ON_PAGE(page->mapping && !PageAnon(page), page);
-       VM_BUG_ON(!mm);
-       return mem_cgroup_charge_common(page, mm, gfp_mask,
-                                       MEM_CGROUP_CHARGE_TYPE_ANON);
-}
-
 /*
  * While swap-in, try_charge -> commit or cancel, the page is locked.
  * And when try_charge() successfully returns, one refcnt to memcg without
@@ -3984,7 +3842,7 @@ static int __mem_cgroup_try_charge_swapin(struct mm_struct *mm,
                                          gfp_t mask,
                                          struct mem_cgroup **memcgp)
 {
-       struct mem_cgroup *memcg;
+       struct mem_cgroup *memcg = NULL;
        struct page_cgroup *pc;
        int ret;
 
@@ -3997,31 +3855,29 @@ static int __mem_cgroup_try_charge_swapin(struct mm_struct *mm,
         * in turn serializes uncharging.
         */
        if (PageCgroupUsed(pc))
-               return 0;
-       if (!do_swap_account)
-               goto charge_cur_mm;
-       memcg = try_get_mem_cgroup_from_page(page);
+               goto out;
+       if (do_swap_account)
+               memcg = try_get_mem_cgroup_from_page(page);
        if (!memcg)
-               goto charge_cur_mm;
-       *memcgp = memcg;
-       ret = __mem_cgroup_try_charge(NULL, mask, 1, memcgp, true);
+               memcg = get_mem_cgroup_from_mm(mm);
+       ret = mem_cgroup_try_charge(memcg, mask, 1, true);
        css_put(&memcg->css);
        if (ret == -EINTR)
-               ret = 0;
-       return ret;
-charge_cur_mm:
-       ret = __mem_cgroup_try_charge(mm, mask, 1, memcgp, true);
-       if (ret == -EINTR)
-               ret = 0;
-       return ret;
+               memcg = root_mem_cgroup;
+       else if (ret)
+               return ret;
+out:
+       *memcgp = memcg;
+       return 0;
 }
 
 int mem_cgroup_try_charge_swapin(struct mm_struct *mm, struct page *page,
                                 gfp_t gfp_mask, struct mem_cgroup **memcgp)
 {
-       *memcgp = NULL;
-       if (mem_cgroup_disabled())
+       if (mem_cgroup_disabled()) {
+               *memcgp = NULL;
                return 0;
+       }
        /*
         * A racing thread's fault, or swapoff, may have already
         * updated the pte, and even removed page from swap cache: in
@@ -4029,12 +3885,13 @@ int mem_cgroup_try_charge_swapin(struct mm_struct *mm, struct page *page,
         * there's also a KSM case which does need to charge the page.
         */
        if (!PageSwapCache(page)) {
-               int ret;
+               struct mem_cgroup *memcg;
 
-               ret = __mem_cgroup_try_charge(mm, gfp_mask, 1, memcgp, true);
-               if (ret == -EINTR)
-                       ret = 0;
-               return ret;
+               memcg = mem_cgroup_try_charge_mm(mm, gfp_mask, 1, true);
+               if (!memcg)
+                       return -ENOMEM;
+               *memcgp = memcg;
+               return 0;
        }
        return __mem_cgroup_try_charge_swapin(mm, page, gfp_mask, memcgp);
 }
@@ -4078,11 +3935,11 @@ void mem_cgroup_commit_charge_swapin(struct page *page,
                                          MEM_CGROUP_CHARGE_TYPE_ANON);
 }
 
-int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
+int mem_cgroup_charge_file(struct page *page, struct mm_struct *mm,
                                gfp_t gfp_mask)
 {
-       struct mem_cgroup *memcg = NULL;
        enum charge_type type = MEM_CGROUP_CHARGE_TYPE_CACHE;
+       struct mem_cgroup *memcg;
        int ret;
 
        if (mem_cgroup_disabled())
@@ -4090,15 +3947,28 @@ int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
        if (PageCompound(page))
                return 0;
 
-       if (!PageSwapCache(page))
-               ret = mem_cgroup_charge_common(page, mm, gfp_mask, type);
-       else { /* page is swapcache/shmem */
+       if (PageSwapCache(page)) { /* shmem */
                ret = __mem_cgroup_try_charge_swapin(mm, page,
                                                     gfp_mask, &memcg);
-               if (!ret)
-                       __mem_cgroup_commit_charge_swapin(page, memcg, type);
+               if (ret)
+                       return ret;
+               __mem_cgroup_commit_charge_swapin(page, memcg, type);
+               return 0;
        }
-       return ret;
+
+       /*
+        * Page cache insertions can happen without an actual mm
+        * context, e.g. during disk probing on boot.
+        */
+       if (unlikely(!mm))
+               memcg = root_mem_cgroup;
+       else {
+               memcg = mem_cgroup_try_charge_mm(mm, gfp_mask, 1, true);
+               if (!memcg)
+                       return -ENOMEM;
+       }
+       __mem_cgroup_commit_charge(memcg, page, 1, type, false);
+       return 0;
 }
 
 static void mem_cgroup_do_uncharge(struct mem_cgroup *memcg,
@@ -4378,8 +4248,8 @@ void mem_cgroup_uncharge_swap(swp_entry_t ent)
        memcg = mem_cgroup_lookup(id);
        if (memcg) {
                /*
-                * We uncharge this because swap is freed.
-                * This memcg can be obsolete one. We avoid calling css_tryget
+                * We uncharge this because swap is freed.  This memcg can
+                * be obsolete one. We avoid calling css_tryget_online().
                 */
                if (!mem_cgroup_is_root(memcg))
                        res_counter_uncharge(&memcg->memsw, PAGE_SIZE);
@@ -4990,7 +4860,7 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg)
        struct cgroup *cgrp = memcg->css.cgroup;
 
        /* returns EBUSY if there is a task or if we come here twice. */
-       if (cgroup_task_count(cgrp) || !list_empty(&cgrp->children))
+       if (cgroup_has_tasks(cgrp) || !list_empty(&cgrp->children))
                return -EBUSY;
 
        /* we call try-to-free pages for make this cgroup empty */
@@ -5017,14 +4887,15 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg)
        return 0;
 }
 
-static int mem_cgroup_force_empty_write(struct cgroup_subsys_state *css,
-                                       unsigned int event)
+static ssize_t mem_cgroup_force_empty_write(struct kernfs_open_file *of,
+                                           char *buf, size_t nbytes,
+                                           loff_t off)
 {
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+       struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
 
        if (mem_cgroup_is_root(memcg))
                return -EINVAL;
-       return mem_cgroup_force_empty(memcg);
+       return mem_cgroup_force_empty(memcg) ?: nbytes;
 }
 
 static u64 mem_cgroup_hierarchy_read(struct cgroup_subsys_state *css,
@@ -5038,7 +4909,7 @@ static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css,
 {
        int retval = 0;
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
-       struct mem_cgroup *parent_memcg = mem_cgroup_from_css(css_parent(&memcg->css));
+       struct mem_cgroup *parent_memcg = mem_cgroup_from_css(memcg->css.parent);
 
        mutex_lock(&memcg_create_mutex);
 
@@ -5172,7 +5043,7 @@ static int __memcg_activate_kmem(struct mem_cgroup *memcg,
         * of course permitted.
         */
        mutex_lock(&memcg_create_mutex);
-       if (cgroup_task_count(memcg->css.cgroup) || memcg_has_children(memcg))
+       if (cgroup_has_tasks(memcg->css.cgroup) || memcg_has_children(memcg))
                err = -EBUSY;
        mutex_unlock(&memcg_create_mutex);
        if (err)
@@ -5273,17 +5144,18 @@ static int memcg_update_kmem_limit(struct mem_cgroup *memcg,
  * The user of this function is...
  * RES_LIMIT.
  */
-static int mem_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
-                           const char *buffer)
+static ssize_t mem_cgroup_write(struct kernfs_open_file *of,
+                               char *buf, size_t nbytes, loff_t off)
 {
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+       struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
        enum res_type type;
        int name;
        unsigned long long val;
        int ret;
 
-       type = MEMFILE_TYPE(cft->private);
-       name = MEMFILE_ATTR(cft->private);
+       buf = strstrip(buf);
+       type = MEMFILE_TYPE(of_cft(of)->private);
+       name = MEMFILE_ATTR(of_cft(of)->private);
 
        switch (name) {
        case RES_LIMIT:
@@ -5292,7 +5164,7 @@ static int mem_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
                        break;
                }
                /* This function does all necessary parse...reuse it */
-               ret = res_counter_memparse_write_strategy(buffer, &val);
+               ret = res_counter_memparse_write_strategy(buf, &val);
                if (ret)
                        break;
                if (type == _MEM)
@@ -5305,7 +5177,7 @@ static int mem_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
                        return -EINVAL;
                break;
        case RES_SOFT_LIMIT:
-               ret = res_counter_memparse_write_strategy(buffer, &val);
+               ret = res_counter_memparse_write_strategy(buf, &val);
                if (ret)
                        break;
                /*
@@ -5322,7 +5194,7 @@ static int mem_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
                ret = -EINVAL; /* should be BUG() ? */
                break;
        }
-       return ret;
+       return ret ?: nbytes;
 }
 
 static void memcg_get_hierarchical_limit(struct mem_cgroup *memcg,
@@ -5335,8 +5207,8 @@ static void memcg_get_hierarchical_limit(struct mem_cgroup *memcg,
        if (!memcg->use_hierarchy)
                goto out;
 
-       while (css_parent(&memcg->css)) {
-               memcg = mem_cgroup_from_css(css_parent(&memcg->css));
+       while (memcg->css.parent) {
+               memcg = mem_cgroup_from_css(memcg->css.parent);
                if (!memcg->use_hierarchy)
                        break;
                tmp = res_counter_read_u64(&memcg->res, RES_LIMIT);
@@ -5349,14 +5221,15 @@ out:
        *memsw_limit = min_memsw_limit;
 }
 
-static int mem_cgroup_reset(struct cgroup_subsys_state *css, unsigned int event)
+static ssize_t mem_cgroup_reset(struct kernfs_open_file *of, char *buf,
+                               size_t nbytes, loff_t off)
 {
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+       struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
        int name;
        enum res_type type;
 
-       type = MEMFILE_TYPE(event);
-       name = MEMFILE_ATTR(event);
+       type = MEMFILE_TYPE(of_cft(of)->private);
+       name = MEMFILE_ATTR(of_cft(of)->private);
 
        switch (name) {
        case RES_MAX_USAGE:
@@ -5381,7 +5254,7 @@ static int mem_cgroup_reset(struct cgroup_subsys_state *css, unsigned int event)
                break;
        }
 
-       return 0;
+       return nbytes;
 }
 
 static u64 mem_cgroup_move_charge_read(struct cgroup_subsys_state *css,
@@ -5570,7 +5443,7 @@ static int mem_cgroup_swappiness_write(struct cgroup_subsys_state *css,
                                       struct cftype *cft, u64 val)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
-       struct mem_cgroup *parent = mem_cgroup_from_css(css_parent(&memcg->css));
+       struct mem_cgroup *parent = mem_cgroup_from_css(memcg->css.parent);
 
        if (val > 100 || !parent)
                return -EINVAL;
@@ -5917,7 +5790,7 @@ static int mem_cgroup_oom_control_write(struct cgroup_subsys_state *css,
        struct cftype *cft, u64 val)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
-       struct mem_cgroup *parent = mem_cgroup_from_css(css_parent(&memcg->css));
+       struct mem_cgroup *parent = mem_cgroup_from_css(memcg->css.parent);
 
        /* cannot set to root cgroup and only 0 and 1 are allowed */
        if (!parent || !((val == 0) || (val == 1)))
@@ -5972,10 +5845,10 @@ static void kmem_cgroup_css_offline(struct mem_cgroup *memcg)
         * which is then paired with css_put during uncharge resp. here.
         *
         * Although this might sound strange as this path is called from
-        * css_offline() when the referencemight have dropped down to 0
-        * and shouldn't be incremented anymore (css_tryget would fail)
-        * we do not have other options because of the kmem allocations
-        * lifetime.
+        * css_offline() when the referencemight have dropped down to 0 and
+        * shouldn't be incremented anymore (css_tryget_online() would
+        * fail) we do not have other options because of the kmem
+        * allocations lifetime.
         */
        css_get(&memcg->css);
 
@@ -6094,9 +5967,10 @@ static void memcg_event_ptable_queue_proc(struct file *file,
  * Input must be in format '<event_fd> <control_fd> <args>'.
  * Interpretation of args is defined by control file implementation.
  */
-static int memcg_write_event_control(struct cgroup_subsys_state *css,
-                                    struct cftype *cft, const char *buffer)
+static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
+                                        char *buf, size_t nbytes, loff_t off)
 {
+       struct cgroup_subsys_state *css = of_css(of);
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
        struct mem_cgroup_event *event;
        struct cgroup_subsys_state *cfile_css;
@@ -6107,15 +5981,17 @@ static int memcg_write_event_control(struct cgroup_subsys_state *css,
        char *endp;
        int ret;
 
-       efd = simple_strtoul(buffer, &endp, 10);
+       buf = strstrip(buf);
+
+       efd = simple_strtoul(buf, &endp, 10);
        if (*endp != ' ')
                return -EINVAL;
-       buffer = endp + 1;
+       buf = endp + 1;
 
-       cfd = simple_strtoul(buffer, &endp, 10);
+       cfd = simple_strtoul(buf, &endp, 10);
        if ((*endp != ' ') && (*endp != '\0'))
                return -EINVAL;
-       buffer = endp + 1;
+       buf = endp + 1;
 
        event = kzalloc(sizeof(*event), GFP_KERNEL);
        if (!event)
@@ -6183,19 +6059,17 @@ static int memcg_write_event_control(struct cgroup_subsys_state *css,
         * automatically removed on cgroup destruction but the removal is
         * asynchronous, so take an extra ref on @css.
         */
-       rcu_read_lock();
-
+       cfile_css = css_tryget_online_from_dir(cfile.file->f_dentry->d_parent,
+                                              &memory_cgrp_subsys);
        ret = -EINVAL;
-       cfile_css = css_from_dir(cfile.file->f_dentry->d_parent,
-                                &mem_cgroup_subsys);
-       if (cfile_css == css && css_tryget(css))
-               ret = 0;
-
-       rcu_read_unlock();
-       if (ret)
+       if (IS_ERR(cfile_css))
                goto out_put_cfile;
+       if (cfile_css != css) {
+               css_put(cfile_css);
+               goto out_put_cfile;
+       }
 
-       ret = event->register_event(memcg, event->eventfd, buffer);
+       ret = event->register_event(memcg, event->eventfd, buf);
        if (ret)
                goto out_put_css;
 
@@ -6208,7 +6082,7 @@ static int memcg_write_event_control(struct cgroup_subsys_state *css,
        fdput(cfile);
        fdput(efile);
 
-       return 0;
+       return nbytes;
 
 out_put_css:
        css_put(css);
@@ -6233,25 +6107,25 @@ static struct cftype mem_cgroup_files[] = {
        {
                .name = "max_usage_in_bytes",
                .private = MEMFILE_PRIVATE(_MEM, RES_MAX_USAGE),
-               .trigger = mem_cgroup_reset,
+               .write = mem_cgroup_reset,
                .read_u64 = mem_cgroup_read_u64,
        },
        {
                .name = "limit_in_bytes",
                .private = MEMFILE_PRIVATE(_MEM, RES_LIMIT),
-               .write_string = mem_cgroup_write,
+               .write = mem_cgroup_write,
                .read_u64 = mem_cgroup_read_u64,
        },
        {
                .name = "soft_limit_in_bytes",
                .private = MEMFILE_PRIVATE(_MEM, RES_SOFT_LIMIT),
-               .write_string = mem_cgroup_write,
+               .write = mem_cgroup_write,
                .read_u64 = mem_cgroup_read_u64,
        },
        {
                .name = "failcnt",
                .private = MEMFILE_PRIVATE(_MEM, RES_FAILCNT),
-               .trigger = mem_cgroup_reset,
+               .write = mem_cgroup_reset,
                .read_u64 = mem_cgroup_read_u64,
        },
        {
@@ -6260,7 +6134,7 @@ static struct cftype mem_cgroup_files[] = {
        },
        {
                .name = "force_empty",
-               .trigger = mem_cgroup_force_empty_write,
+               .write = mem_cgroup_force_empty_write,
        },
        {
                .name = "use_hierarchy",
@@ -6270,7 +6144,7 @@ static struct cftype mem_cgroup_files[] = {
        },
        {
                .name = "cgroup.event_control",         /* XXX: for compat */
-               .write_string = memcg_write_event_control,
+               .write = memcg_write_event_control,
                .flags = CFTYPE_NO_PREFIX,
                .mode = S_IWUGO,
        },
@@ -6303,7 +6177,7 @@ static struct cftype mem_cgroup_files[] = {
        {
                .name = "kmem.limit_in_bytes",
                .private = MEMFILE_PRIVATE(_KMEM, RES_LIMIT),
-               .write_string = mem_cgroup_write,
+               .write = mem_cgroup_write,
                .read_u64 = mem_cgroup_read_u64,
        },
        {
@@ -6314,13 +6188,13 @@ static struct cftype mem_cgroup_files[] = {
        {
                .name = "kmem.failcnt",
                .private = MEMFILE_PRIVATE(_KMEM, RES_FAILCNT),
-               .trigger = mem_cgroup_reset,
+               .write = mem_cgroup_reset,
                .read_u64 = mem_cgroup_read_u64,
        },
        {
                .name = "kmem.max_usage_in_bytes",
                .private = MEMFILE_PRIVATE(_KMEM, RES_MAX_USAGE),
-               .trigger = mem_cgroup_reset,
+               .write = mem_cgroup_reset,
                .read_u64 = mem_cgroup_read_u64,
        },
 #ifdef CONFIG_SLABINFO
@@ -6343,19 +6217,19 @@ static struct cftype memsw_cgroup_files[] = {
        {
                .name = "memsw.max_usage_in_bytes",
                .private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE),
-               .trigger = mem_cgroup_reset,
+               .write = mem_cgroup_reset,
                .read_u64 = mem_cgroup_read_u64,
        },
        {
                .name = "memsw.limit_in_bytes",
                .private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
-               .write_string = mem_cgroup_write,
+               .write = mem_cgroup_write,
                .read_u64 = mem_cgroup_read_u64,
        },
        {
                .name = "memsw.failcnt",
                .private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT),
-               .trigger = mem_cgroup_reset,
+               .write = mem_cgroup_reset,
                .read_u64 = mem_cgroup_read_u64,
        },
        { },    /* terminate */
@@ -6533,9 +6407,9 @@ static int
 mem_cgroup_css_online(struct cgroup_subsys_state *css)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
-       struct mem_cgroup *parent = mem_cgroup_from_css(css_parent(css));
+       struct mem_cgroup *parent = mem_cgroup_from_css(css->parent);
 
-       if (css->cgroup->id > MEM_CGROUP_ID_MAX)
+       if (css->id > MEM_CGROUP_ID_MAX)
                return -ENOSPC;
 
        if (!parent)
@@ -6566,11 +6440,11 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css)
                 * unfortunate state in our controller.
                 */
                if (parent != root_mem_cgroup)
-                       mem_cgroup_subsys.broken_hierarchy = true;
+                       memory_cgrp_subsys.broken_hierarchy = true;
        }
        mutex_unlock(&memcg_create_mutex);
 
-       return memcg_init_kmem(memcg, &mem_cgroup_subsys);
+       return memcg_init_kmem(memcg, &memory_cgrp_subsys);
 }
 
 /*
@@ -6630,7 +6504,7 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
        /*
         * XXX: css_offline() would be where we should reparent all
         * memory to prepare the cgroup for destruction.  However,
-        * memcg does not do css_tryget() and res_counter charging
+        * memcg does not do css_tryget_online() and res_counter charging
         * under the same RCU lock region, which means that charging
         * could race with offlining.  Offlining only happens to
         * cgroups with no tasks in them but charges can show up
@@ -6644,9 +6518,9 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
         *                           lookup_swap_cgroup_id()
         *                           rcu_read_lock()
         *                           mem_cgroup_lookup()
-        *                           css_tryget()
+        *                           css_tryget_online()
         *                           rcu_read_unlock()
-        * disable css_tryget()
+        * disable css_tryget_online()
         * call_rcu()
         *   offline_css()
         *     reparent_charges()
@@ -6712,8 +6586,7 @@ one_by_one:
                        batch_count = PRECHARGE_COUNT_AT_ONCE;
                        cond_resched();
                }
-               ret = __mem_cgroup_try_charge(NULL,
-                                       GFP_KERNEL, 1, &memcg, false);
+               ret = mem_cgroup_try_charge(memcg, GFP_KERNEL, 1, false);
                if (ret)
                        /* mem_cgroup_clear_mc() will do uncharge later */
                        return ret;
@@ -7272,9 +7145,7 @@ static void mem_cgroup_bind(struct cgroup_subsys_state *root_css)
                mem_cgroup_from_css(root_css)->use_hierarchy = true;
 }
 
-struct cgroup_subsys mem_cgroup_subsys = {
-       .name = "memory",
-       .subsys_id = mem_cgroup_subsys_id,
+struct cgroup_subsys memory_cgrp_subsys = {
        .css_alloc = mem_cgroup_css_alloc,
        .css_online = mem_cgroup_css_online,
        .css_offline = mem_cgroup_css_offline,
@@ -7300,7 +7171,7 @@ __setup("swapaccount=", enable_swap_account);
 
 static void __init memsw_file_init(void)
 {
-       WARN_ON(cgroup_add_cftypes(&mem_cgroup_subsys, memsw_cgroup_files));
+       WARN_ON(cgroup_add_cftypes(&memory_cgrp_subsys, memsw_cgroup_files));
 }
 
 static void __init enable_swap_cgroup(void)