Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 347021
b: refs/heads/master
c: 0e9d92f
h: refs/heads/master
i:
  347019: 23b239e
v: v3
  • Loading branch information
Glauber Costa authored and Linus Torvalds committed Dec 18, 2012
1 parent 8c4640c commit 3c8508a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d7f25f8a2f81252d1ac134470ba1d0a287cf8fcd
refs/heads/master: 0e9d92f2d02d8c8320f0502307c688d07bdac2b3
1 change: 1 addition & 0 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -1597,6 +1597,7 @@ struct task_struct {
unsigned long nr_pages; /* uncharged usage */
unsigned long memsw_nr_pages; /* uncharged mem+swap usage */
} memcg_batch;
unsigned int memcg_kmem_skip_account;
#endif
#ifdef CONFIG_HAVE_HW_BREAKPOINT
atomic_t ptrace_bp_refcnt;
Expand Down
57 changes: 54 additions & 3 deletions trunk/mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -3025,6 +3025,37 @@ void memcg_release_cache(struct kmem_cache *s)
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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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.
Expand All @@ -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();
Expand Down

0 comments on commit 3c8508a

Please sign in to comment.