*/
 static int need_forkexit_callback __read_mostly;
 
+static void cgroup_offline_fn(struct work_struct *work);
 static int cgroup_destroy_locked(struct cgroup *cgrp);
 static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys,
                              struct cftype cfts[], bool is_add);
 
 static void cgroup_free_fn(struct work_struct *work)
 {
-       struct cgroup *cgrp = container_of(work, struct cgroup, free_work);
+       struct cgroup *cgrp = container_of(work, struct cgroup, destroy_work);
        struct cgroup_subsys *ss;
 
        mutex_lock(&cgroup_mutex);
 {
        struct cgroup *cgrp = container_of(head, struct cgroup, rcu_head);
 
-       schedule_work(&cgrp->free_work);
+       INIT_WORK(&cgrp->destroy_work, cgroup_free_fn);
+       schedule_work(&cgrp->destroy_work);
 }
 
 static void cgroup_diput(struct dentry *dentry, struct inode *inode)
        INIT_LIST_HEAD(&cgrp->allcg_node);
        INIT_LIST_HEAD(&cgrp->release_list);
        INIT_LIST_HEAD(&cgrp->pidlists);
-       INIT_WORK(&cgrp->free_work, cgroup_free_fn);
        mutex_init(&cgrp->pidlist_mutex);
        INIT_LIST_HEAD(&cgrp->event_list);
        spin_lock_init(&cgrp->event_list_lock);
        /*
         * @pos could already have been removed.  Once a cgroup is removed,
         * its ->sibling.next is no longer updated when its next sibling
-        * changes.  As CGRP_DEAD is set on removal which is fully
-        * serialized, if we see it unasserted, it's guaranteed that the
-        * next sibling hasn't finished its grace period even if it's
-        * already removed, and thus safe to dereference from this RCU
-        * critical section.  If ->sibling.next is inaccessible,
-        * cgroup_is_dead() is guaranteed to be visible as %true here.
+        * changes.  As CGRP_DEAD assertion is serialized and happens
+        * before the cgroup is taken off the ->sibling list, if we see it
+        * unasserted, it's guaranteed that the next sibling hasn't
+        * finished its grace period even if it's already removed, and thus
+        * safe to dereference from this RCU critical section.  If
+        * ->sibling.next is inaccessible, cgroup_is_dead() is guaranteed
+        * to be visible as %true here.
         */
        if (likely(!cgroup_is_dead(pos))) {
                next = list_entry_rcu(pos->sibling.next, struct cgroup, sibling);
        __releases(&cgroup_mutex) __acquires(&cgroup_mutex)
 {
        struct dentry *d = cgrp->dentry;
-       struct cgroup *parent = cgrp->parent;
        struct cgroup_event *event, *tmp;
        struct cgroup_subsys *ss;
        bool empty;
        }
        spin_unlock(&cgrp->event_list_lock);
 
+       INIT_WORK(&cgrp->destroy_work, cgroup_offline_fn);
+       schedule_work(&cgrp->destroy_work);
+
+       return 0;
+};
+
+static void cgroup_offline_fn(struct work_struct *work)
+{
+       struct cgroup *cgrp = container_of(work, struct cgroup, destroy_work);
+       struct cgroup *parent = cgrp->parent;
+       struct dentry *d = cgrp->dentry;
+       struct cgroup_subsys *ss;
+
+       mutex_lock(&cgroup_mutex);
+
        /* tell subsystems to initate destruction */
        for_each_subsys(cgrp->root, ss)
                offline_css(ss, cgrp);
        set_bit(CGRP_RELEASABLE, &parent->flags);
        check_for_release(parent);
 
-       return 0;
+       mutex_unlock(&cgroup_mutex);
 }
 
 static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)