|
@@ -3025,6 +3025,37 @@ out:
|
|
|
kfree(s->memcg_params);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * During the creation a new cache, we need to disable our accounting mechanism
|
|
|
+ * altogether. This is true even if we are not creating, but rather just
|
|
|
+ * enqueing new caches to be created.
|
|
|
+ *
|
|
|
+ * This is because that process will trigger allocations; some visible, like
|
|
|
+ * explicit kmallocs to auxiliary data structures, name strings and internal
|
|
|
+ * cache structures; some well concealed, like INIT_WORK() that can allocate
|
|
|
+ * objects during debug.
|
|
|
+ *
|
|
|
+ * If any allocation happens during memcg_kmem_get_cache, we will recurse back
|
|
|
+ * to it. This may not be a bounded recursion: since the first cache creation
|
|
|
+ * failed to complete (waiting on the allocation), we'll just try to create the
|
|
|
+ * cache again, failing at the same point.
|
|
|
+ *
|
|
|
+ * memcg_kmem_get_cache is prepared to abort after seeing a positive count of
|
|
|
+ * memcg_kmem_skip_account. So we enclose anything that might allocate memory
|
|
|
+ * inside the following two functions.
|
|
|
+ */
|
|
|
+static inline void memcg_stop_kmem_account(void)
|
|
|
+{
|
|
|
+ VM_BUG_ON(!current->mm);
|
|
|
+ current->memcg_kmem_skip_account++;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void memcg_resume_kmem_account(void)
|
|
|
+{
|
|
|
+ VM_BUG_ON(!current->mm);
|
|
|
+ current->memcg_kmem_skip_account--;
|
|
|
+}
|
|
|
+
|
|
|
static char *memcg_cache_name(struct mem_cgroup *memcg, struct kmem_cache *s)
|
|
|
{
|
|
|
char *name;
|
|
@@ -3084,7 +3115,6 @@ static struct kmem_cache *memcg_create_kmem_cache(struct mem_cgroup *memcg,
|
|
|
goto out;
|
|
|
|
|
|
new_cachep = kmem_cache_dup(memcg, cachep);
|
|
|
-
|
|
|
if (new_cachep == NULL) {
|
|
|
new_cachep = cachep;
|
|
|
goto out;
|
|
@@ -3125,8 +3155,8 @@ static void memcg_create_cache_work_func(struct work_struct *w)
|
|
|
* Enqueue the creation of a per-memcg kmem_cache.
|
|
|
* Called with rcu_read_lock.
|
|
|
*/
|
|
|
-static void memcg_create_cache_enqueue(struct mem_cgroup *memcg,
|
|
|
- struct kmem_cache *cachep)
|
|
|
+static void __memcg_create_cache_enqueue(struct mem_cgroup *memcg,
|
|
|
+ struct kmem_cache *cachep)
|
|
|
{
|
|
|
struct create_work *cw;
|
|
|
|
|
@@ -3147,6 +3177,24 @@ static void memcg_create_cache_enqueue(struct mem_cgroup *memcg,
|
|
|
schedule_work(&cw->work);
|
|
|
}
|
|
|
|
|
|
+static void memcg_create_cache_enqueue(struct mem_cgroup *memcg,
|
|
|
+ struct kmem_cache *cachep)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * We need to stop accounting when we kmalloc, because if the
|
|
|
+ * corresponding kmalloc cache is not yet created, the first allocation
|
|
|
+ * in __memcg_create_cache_enqueue will recurse.
|
|
|
+ *
|
|
|
+ * However, it is better to enclose the whole function. Depending on
|
|
|
+ * the debugging options enabled, INIT_WORK(), for instance, can
|
|
|
+ * trigger an allocation. This too, will make us recurse. Because at
|
|
|
+ * this point we can't allow ourselves back into memcg_kmem_get_cache,
|
|
|
+ * the safest choice is to do it like this, wrapping the whole function.
|
|
|
+ */
|
|
|
+ memcg_stop_kmem_account();
|
|
|
+ __memcg_create_cache_enqueue(memcg, cachep);
|
|
|
+ memcg_resume_kmem_account();
|
|
|
+}
|
|
|
/*
|
|
|
* Return the kmem_cache we're supposed to use for a slab allocation.
|
|
|
* We try to use the current memcg's version of the cache.
|
|
@@ -3169,6 +3217,9 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep,
|
|
|
VM_BUG_ON(!cachep->memcg_params);
|
|
|
VM_BUG_ON(!cachep->memcg_params->is_root_cache);
|
|
|
|
|
|
+ if (!current->mm || current->memcg_kmem_skip_account)
|
|
|
+ return cachep;
|
|
|
+
|
|
|
rcu_read_lock();
|
|
|
memcg = mem_cgroup_from_task(rcu_dereference(current->mm->owner));
|
|
|
rcu_read_unlock();
|