diff options
author | Vladimir Davydov <vdavydov@parallels.com> | 2015-02-12 17:59:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-12 21:54:09 -0500 |
commit | 05257a1a3dcc196c197714b5c9a8dd35b7f6aefc (patch) | |
tree | 063e4bafec04171990ce3f95f649a9e3c6dcd6a8 /include/linux/memcontrol.h | |
parent | dbcf73e26cd0b3d66e6db65ab595e664a55e58ff (diff) |
memcg: add rwsem to synchronize against memcg_caches arrays relocation
We need a stable value of memcg_nr_cache_ids in kmem_cache_create()
(memcg_alloc_cache_params() wants it for root caches), where we only
hold the slab_mutex and no memcg-related locks. As a result, we have to
update memcg_nr_cache_ids under the slab_mutex, which we can only take
on the slab's side (see memcg_update_array_size). This looks awkward
and will become even worse when per-memcg list_lru is introduced, which
also wants stable access to memcg_nr_cache_ids.
To get rid of this dependency between the memcg_nr_cache_ids and the
slab_mutex, this patch introduces a special rwsem. The rwsem is held
for writing during memcg_caches arrays relocation and memcg_nr_cache_ids
updates. Therefore one can take it for reading to get a stable access
to memcg_caches arrays and/or memcg_nr_cache_ids.
Currently the semaphore is taken for reading only from
kmem_cache_create, right before taking the slab_mutex, so right now
there's no much point in using rwsem instead of mutex. However, once
list_lru is made per-memcg it will allow list_lru initializations to
proceed concurrently.
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Greg Thelen <gthelen@google.com>
Cc: Glauber Costa <glommer@gmail.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/memcontrol.h')
-rw-r--r-- | include/linux/memcontrol.h | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 2607c91230af..dbc4baa3619c 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
@@ -399,6 +399,8 @@ static inline void sock_release_memcg(struct sock *sk) | |||
399 | extern struct static_key memcg_kmem_enabled_key; | 399 | extern struct static_key memcg_kmem_enabled_key; |
400 | 400 | ||
401 | extern int memcg_nr_cache_ids; | 401 | extern int memcg_nr_cache_ids; |
402 | extern void memcg_get_cache_ids(void); | ||
403 | extern void memcg_put_cache_ids(void); | ||
402 | 404 | ||
403 | /* | 405 | /* |
404 | * Helper macro to loop through all memcg-specific caches. Callers must still | 406 | * Helper macro to loop through all memcg-specific caches. Callers must still |
@@ -434,8 +436,6 @@ void __memcg_kmem_uncharge_pages(struct page *page, int order); | |||
434 | 436 | ||
435 | int memcg_cache_id(struct mem_cgroup *memcg); | 437 | int memcg_cache_id(struct mem_cgroup *memcg); |
436 | 438 | ||
437 | void memcg_update_array_size(int num_groups); | ||
438 | |||
439 | struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep); | 439 | struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep); |
440 | void __memcg_kmem_put_cache(struct kmem_cache *cachep); | 440 | void __memcg_kmem_put_cache(struct kmem_cache *cachep); |
441 | 441 | ||
@@ -569,6 +569,14 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg) | |||
569 | return -1; | 569 | return -1; |
570 | } | 570 | } |
571 | 571 | ||
572 | static inline void memcg_get_cache_ids(void) | ||
573 | { | ||
574 | } | ||
575 | |||
576 | static inline void memcg_put_cache_ids(void) | ||
577 | { | ||
578 | } | ||
579 | |||
572 | static inline struct kmem_cache * | 580 | static inline struct kmem_cache * |
573 | memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp) | 581 | memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp) |
574 | { | 582 | { |