diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 922a7f600465..1b343b268359 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -92,6 +92,13 @@ struct lruvec_stat {
 	long count[NR_VM_NODE_STAT_ITEMS];
 };
 
+
+/* Shrinker::id indexed nr_deferred of memcg-aware shrinkers. */
+struct memcg_shrinker_deferred {
+	struct rcu_head rcu;
+	atomic_long_t nr_deferred[];
+};
+
 /*
  * Bitmap of shrinker::id corresponding to memcg-aware shrinkers,
  * which have elements charged to this memcg.
@@ -119,6 +126,7 @@ struct mem_cgroup_per_node {
 	struct mem_cgroup_reclaim_iter	iter;
 
 	struct memcg_shrinker_map __rcu	*shrinker_map;
+	struct memcg_shrinker_deferred __rcu	*shrinker_deferred;
 
 	struct rb_node		tree_node;	/* RB tree node */
 	unsigned long		usage_in_excess;/* Set to the value by which */
@@ -1489,6 +1497,7 @@ static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg)
 }
 
 extern int memcg_expand_shrinker_maps(int new_id);
+extern int memcg_expand_shrinker_deferred(int new_id);
 
 extern void memcg_set_shrinker_bit(struct mem_cgroup *memcg,
 				   int nid, int shrinker_id);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 19e41684c96b..d3d5c88db179 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -395,6 +395,8 @@ EXPORT_SYMBOL(memcg_kmem_enabled_key);
 #endif
 
 static int memcg_shrinker_map_size;
+static int memcg_shrinker_deferred_size;
+
 static DEFINE_MUTEX(memcg_shrinker_mutex);
 
 static void memcg_free_shrinker_map_rcu(struct rcu_head *head)
@@ -402,6 +404,11 @@ static void memcg_free_shrinker_map_rcu(struct rcu_head *head)
 	kvfree(container_of(head, struct memcg_shrinker_map, rcu));
 }
 
+static void memcg_free_shrinker_deferred_rcu(struct rcu_head *head)
+{
+	kvfree(container_of(head, struct memcg_shrinker_deferred, rcu));
+}
+
 static int memcg_expand_one_shrinker_map(struct mem_cgroup *memcg,
 					 int size, int old_size)
 {
@@ -432,6 +439,36 @@ static int memcg_expand_one_shrinker_map(struct mem_cgroup *memcg,
 	return 0;
 }
 
+static int memcg_expand_one_shrinker_deferred(struct mem_cgroup *memcg,
+					      int size, int old_size)
+{
+	struct memcg_shrinker_deferred *new, *old;
+	int nid;
+
+	lockdep_assert_held(&memcg_shrinker_mutex);
+
+	for_each_node(nid) {
+		old = rcu_dereference_protected(
+			mem_cgroup_nodeinfo(memcg, nid)->shrinker_deferred, true);
+		/* Not yet online memcg */
+		if (!old)
+			return 0;
+
+		new = kvmalloc_node(sizeof(*new) + size, GFP_KERNEL, nid);
+		if (!new)
+			return -ENOMEM;
+
+		/* Copy all old values, and clear all new ones */
+		memcpy((void *)new->nr_deferred, (void *)old->nr_deferred, old_size);
+		memset((void *)new->nr_deferred + old_size, 0, size - old_size);
+
+		rcu_assign_pointer(memcg->nodeinfo[nid]->shrinker_deferred, new);
+		call_rcu(&old->rcu, memcg_free_shrinker_deferred_rcu);
+	}
+
+	return 0;
+}
+
 static void memcg_free_shrinker_maps(struct mem_cgroup *memcg)
 {
 	struct mem_cgroup_per_node *pn;
@@ -450,6 +487,21 @@ static void memcg_free_shrinker_maps(struct mem_cgroup *memcg)
 	}
 }
 
+static void memcg_free_shrinker_deferred(struct mem_cgroup *memcg)
+{
+	struct mem_cgroup_per_node *pn;
+	struct memcg_shrinker_deferred *deferred;
+	int nid;
+
+	for_each_node(nid) {
+		pn = mem_cgroup_nodeinfo(memcg, nid);
+		deferred = rcu_dereference_protected(pn->shrinker_deferred, true);
+		if (deferred)
+			kvfree(deferred);
+		rcu_assign_pointer(pn->shrinker_deferred, NULL);
+	}
+}
+
 static int memcg_alloc_shrinker_maps(struct mem_cgroup *memcg)
 {
 	struct memcg_shrinker_map *map;
@@ -474,6 +526,27 @@ static int memcg_alloc_shrinker_maps(struct mem_cgroup *memcg)
 	return ret;
 }
 
+static int memcg_alloc_shrinker_deferred(struct mem_cgroup *memcg)
+{
+	struct memcg_shrinker_deferred *deferred;
+	int nid, size, ret = 0;
+
+	mutex_lock(&memcg_shrinker_mutex);
+	size = memcg_shrinker_deferred_size;
+	for_each_node(nid) {
+		deferred = kvzalloc_node(sizeof(*deferred) + size, GFP_KERNEL, nid);
+		if (!deferred) {
+			memcg_free_shrinker_deferred(memcg);
+			ret = -ENOMEM;
+			break;
+		}
+		rcu_assign_pointer(memcg->nodeinfo[nid]->shrinker_deferred, deferred);
+	}
+	mutex_unlock(&memcg_shrinker_mutex);
+
+	return ret;
+}
+
 int memcg_expand_shrinker_maps(int new_id)
 {
 	int size, old_size, ret = 0;
@@ -504,6 +577,34 @@ int memcg_expand_shrinker_maps(int new_id)
 	return ret;
 }
 
+int memcg_expand_shrinker_deferred(int new_id)
+{
+	int size, old_size, ret = 0;
+	struct mem_cgroup *memcg;
+
+	size = (new_id + 1) * sizeof(atomic_long_t);
+	old_size = memcg_shrinker_deferred_size;
+	if (size <= old_size)
+		return 0;
+
+	mutex_lock(&memcg_shrinker_mutex);
+	if (!root_mem_cgroup)
+		goto unlock;
+
+	for_each_mem_cgroup(memcg) {
+		ret = memcg_expand_one_shrinker_deferred(memcg, size, old_size);
+		if (ret) {
+			mem_cgroup_iter_break(NULL, memcg);
+			goto unlock;
+		}
+	}
+unlock:
+	if (!ret)
+		memcg_shrinker_deferred_size = size;
+	mutex_unlock(&memcg_shrinker_mutex);
+	return ret;
+}
+
 void memcg_set_shrinker_bit(struct mem_cgroup *memcg, int nid, int shrinker_id)
 {
 	if (shrinker_id >= 0 && memcg && !mem_cgroup_is_root(memcg)) {
@@ -5400,8 +5501,8 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css)
 	struct mem_cgroup *memcg = mem_cgroup_from_css(css);
 
 	/*
-	 * A memcg must be visible for memcg_expand_shrinker_maps()
-	 * by the time the maps are allocated. So, we allocate maps
+	 * A memcg must be visible for memcg_expand_shrinker_{maps|deferred}()
+	 * by the time the maps are allocated. So, we allocate maps and deferred
 	 * here, when for_each_mem_cgroup() can't skip it.
 	 */
 	if (memcg_alloc_shrinker_maps(memcg)) {
@@ -5409,6 +5510,12 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css)
 		return -ENOMEM;
 	}
 
+	if (memcg_alloc_shrinker_deferred(memcg)) {
+		memcg_free_shrinker_maps(memcg);
+		mem_cgroup_id_remove(memcg);
+		return -ENOMEM;
+	}
+
 	/* Online state pins memcg ID, memcg ID pins CSS */
 	refcount_set(&memcg->id.ref, 1);
 	css_get(css);
@@ -5469,6 +5576,7 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
 	cancel_work_sync(&memcg->high_work);
 	mem_cgroup_remove_from_trees(memcg);
 	memcg_free_shrinker_maps(memcg);
+	memcg_free_shrinker_deferred(memcg);
 	memcg_free_kmem(memcg);
 	mem_cgroup_free(memcg);
 }
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 0d628299e55c..cba0bc8d4661 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -219,6 +219,10 @@ static int prealloc_memcg_shrinker(struct shrinker *shrinker)
 			goto unlock;
 		}
 
+		if (memcg_expand_shrinker_deferred(id)) {
+			idr_remove(&shrinker_idr, id);
+			goto unlock;
+		}
 		shrinker_nr_max = id + 1;
 	}
 	shrinker->id = id;
