mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
slab: embed memcg_cache_params to kmem_cache
Currently, kmem_cache stores a pointer to struct memcg_cache_params
instead of embedding it. The rationale is to save memory when kmem
accounting is disabled. However, the memcg_cache_params has shrivelled
drastically since it was first introduced:
* Initially:
struct memcg_cache_params {
bool is_root_cache;
union {
struct kmem_cache *memcg_caches[0];
struct {
struct mem_cgroup *memcg;
struct list_head list;
struct kmem_cache *root_cache;
bool dead;
atomic_t nr_pages;
struct work_struct destroy;
};
};
};
* Now:
struct memcg_cache_params {
bool is_root_cache;
union {
struct {
struct rcu_head rcu_head;
struct kmem_cache *memcg_caches[0];
};
struct {
struct mem_cgroup *memcg;
struct kmem_cache *root_cache;
};
};
};
So the memory saving does not seem to be a clear win anymore.
OTOH, keeping a pointer to memcg_cache_params struct instead of embedding
it results in touching one more cache line on kmem alloc/free hot paths.
Besides, it makes linking kmem caches in a list chained by a field of
struct memcg_cache_params really painful due to a level of indirection,
while I want to make them linked in the following patch. That said, let
us embed it.
Signed-off-by: Vladimir Davydov <[email protected]>
Cc: Johannes Weiner <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Tejun Heo <[email protected]>
Cc: Christoph Lameter <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Dan Carpenter <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
49e7e7ff8d
commit
f7ce3190c4
7 changed files with 111 additions and 103 deletions
48
mm/slab.h
48
mm/slab.h
|
|
@ -86,8 +86,6 @@ extern struct kmem_cache *create_kmalloc_cache(const char *name, size_t size,
|
|||
extern void create_boot_cache(struct kmem_cache *, const char *name,
|
||||
size_t size, unsigned long flags);
|
||||
|
||||
struct mem_cgroup;
|
||||
|
||||
int slab_unmergeable(struct kmem_cache *s);
|
||||
struct kmem_cache *find_mergeable(size_t size, size_t align,
|
||||
unsigned long flags, const char *name, void (*ctor)(void *));
|
||||
|
|
@ -167,14 +165,13 @@ ssize_t slabinfo_write(struct file *file, const char __user *buffer,
|
|||
#ifdef CONFIG_MEMCG_KMEM
|
||||
static inline bool is_root_cache(struct kmem_cache *s)
|
||||
{
|
||||
return !s->memcg_params || s->memcg_params->is_root_cache;
|
||||
return s->memcg_params.is_root_cache;
|
||||
}
|
||||
|
||||
static inline bool slab_equal_or_root(struct kmem_cache *s,
|
||||
struct kmem_cache *p)
|
||||
struct kmem_cache *p)
|
||||
{
|
||||
return (p == s) ||
|
||||
(s->memcg_params && (p == s->memcg_params->root_cache));
|
||||
return p == s || p == s->memcg_params.root_cache;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -185,37 +182,30 @@ static inline bool slab_equal_or_root(struct kmem_cache *s,
|
|||
static inline const char *cache_name(struct kmem_cache *s)
|
||||
{
|
||||
if (!is_root_cache(s))
|
||||
return s->memcg_params->root_cache->name;
|
||||
s = s->memcg_params.root_cache;
|
||||
return s->name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note, we protect with RCU only the memcg_caches array, not per-memcg caches.
|
||||
* That said the caller must assure the memcg's cache won't go away. Since once
|
||||
* created a memcg's cache is destroyed only along with the root cache, it is
|
||||
* true if we are going to allocate from the cache or hold a reference to the
|
||||
* root cache by other means. Otherwise, we should hold either the slab_mutex
|
||||
* or the memcg's slab_caches_mutex while calling this function and accessing
|
||||
* the returned value.
|
||||
* That said the caller must assure the memcg's cache won't go away by either
|
||||
* taking a css reference to the owner cgroup, or holding the slab_mutex.
|
||||
*/
|
||||
static inline struct kmem_cache *
|
||||
cache_from_memcg_idx(struct kmem_cache *s, int idx)
|
||||
{
|
||||
struct kmem_cache *cachep;
|
||||
struct memcg_cache_params *params;
|
||||
|
||||
if (!s->memcg_params)
|
||||
return NULL;
|
||||
struct memcg_cache_array *arr;
|
||||
|
||||
rcu_read_lock();
|
||||
params = rcu_dereference(s->memcg_params);
|
||||
arr = rcu_dereference(s->memcg_params.memcg_caches);
|
||||
|
||||
/*
|
||||
* Make sure we will access the up-to-date value. The code updating
|
||||
* memcg_caches issues a write barrier to match this (see
|
||||
* memcg_register_cache()).
|
||||
* memcg_create_kmem_cache()).
|
||||
*/
|
||||
cachep = lockless_dereference(params->memcg_caches[idx]);
|
||||
cachep = lockless_dereference(arr->entries[idx]);
|
||||
rcu_read_unlock();
|
||||
|
||||
return cachep;
|
||||
|
|
@ -225,7 +215,7 @@ static inline struct kmem_cache *memcg_root_cache(struct kmem_cache *s)
|
|||
{
|
||||
if (is_root_cache(s))
|
||||
return s;
|
||||
return s->memcg_params->root_cache;
|
||||
return s->memcg_params.root_cache;
|
||||
}
|
||||
|
||||
static __always_inline int memcg_charge_slab(struct kmem_cache *s,
|
||||
|
|
@ -235,7 +225,7 @@ static __always_inline int memcg_charge_slab(struct kmem_cache *s,
|
|||
return 0;
|
||||
if (is_root_cache(s))
|
||||
return 0;
|
||||
return memcg_charge_kmem(s->memcg_params->memcg, gfp, 1 << order);
|
||||
return memcg_charge_kmem(s->memcg_params.memcg, gfp, 1 << order);
|
||||
}
|
||||
|
||||
static __always_inline void memcg_uncharge_slab(struct kmem_cache *s, int order)
|
||||
|
|
@ -244,9 +234,13 @@ static __always_inline void memcg_uncharge_slab(struct kmem_cache *s, int order)
|
|||
return;
|
||||
if (is_root_cache(s))
|
||||
return;
|
||||
memcg_uncharge_kmem(s->memcg_params->memcg, 1 << order);
|
||||
memcg_uncharge_kmem(s->memcg_params.memcg, 1 << order);
|
||||
}
|
||||
#else
|
||||
|
||||
extern void slab_init_memcg_params(struct kmem_cache *);
|
||||
|
||||
#else /* !CONFIG_MEMCG_KMEM */
|
||||
|
||||
static inline bool is_root_cache(struct kmem_cache *s)
|
||||
{
|
||||
return true;
|
||||
|
|
@ -282,7 +276,11 @@ static inline int memcg_charge_slab(struct kmem_cache *s, gfp_t gfp, int order)
|
|||
static inline void memcg_uncharge_slab(struct kmem_cache *s, int order)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void slab_init_memcg_params(struct kmem_cache *s)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_MEMCG_KMEM */
|
||||
|
||||
static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue