summaryrefslogtreecommitdiffstats
path: root/mm/slab.c
diff options
context:
space:
mode:
authorGlauber Costa <glommer@parallels.com>2012-12-18 17:23:03 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 18:02:14 -0500
commit943a451a87d229ca564a27274b58eaeae35fde5d (patch)
tree607a0bc1aba3911602dec1448be2ace190b5c1eb /mm/slab.c
parent749c54151a6e5b229e4ae067dbc651e54b161fbc (diff)
slab: propagate tunable values
SLAB allows us to tune a particular cache behavior with tunables. When creating a new memcg cache copy, we'd like to preserve any tunables the parent cache already had. This could be done by an explicit call to do_tune_cpucache() after the cache is created. But this is not very convenient now that the caches are created from common code, since this function is SLAB-specific. Another method of doing that is taking advantage of the fact that do_tune_cpucache() is always called from enable_cpucache(), which is called at cache initialization. We can just preset the values, and then things work as expected. It can also happen that a root cache has its tunables updated during normal system operation. In this case, we will propagate the change to all caches that are already active. This change will require us to move the assignment of root_cache in memcg_params a bit earlier. We need this to be already set - which memcg_kmem_register_cache will do - when we reach __kmem_cache_create() Signed-off-by: Glauber Costa <glommer@parallels.com> Cc: Christoph Lameter <cl@linux.com> Cc: David Rientjes <rientjes@google.com> Cc: Frederic Weisbecker <fweisbec@redhat.com> Cc: Greg Thelen <gthelen@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: JoonSoo Kim <js1304@gmail.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Michal Hocko <mhocko@suse.cz> Cc: Pekka Enberg <penberg@cs.helsinki.fi> Cc: Rik van Riel <riel@redhat.com> Cc: Suleiman Souhlal <suleiman@google.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 'mm/slab.c')
-rw-r--r--mm/slab.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/mm/slab.c b/mm/slab.c
index 7467343f9fe7..4dcbf96a77b4 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -4041,7 +4041,7 @@ static void do_ccupdate_local(void *info)
4041} 4041}
4042 4042
4043/* Always called with the slab_mutex held */ 4043/* Always called with the slab_mutex held */
4044static int do_tune_cpucache(struct kmem_cache *cachep, int limit, 4044static int __do_tune_cpucache(struct kmem_cache *cachep, int limit,
4045 int batchcount, int shared, gfp_t gfp) 4045 int batchcount, int shared, gfp_t gfp)
4046{ 4046{
4047 struct ccupdate_struct *new; 4047 struct ccupdate_struct *new;
@@ -4084,12 +4084,48 @@ static int do_tune_cpucache(struct kmem_cache *cachep, int limit,
4084 return alloc_kmemlist(cachep, gfp); 4084 return alloc_kmemlist(cachep, gfp);
4085} 4085}
4086 4086
4087static int do_tune_cpucache(struct kmem_cache *cachep, int limit,
4088 int batchcount, int shared, gfp_t gfp)
4089{
4090 int ret;
4091 struct kmem_cache *c = NULL;
4092 int i = 0;
4093
4094 ret = __do_tune_cpucache(cachep, limit, batchcount, shared, gfp);
4095
4096 if (slab_state < FULL)
4097 return ret;
4098
4099 if ((ret < 0) || !is_root_cache(cachep))
4100 return ret;
4101
4102 for_each_memcg_cache_index(i) {
4103 c = cache_from_memcg(cachep, i);
4104 if (c)
4105 /* return value determined by the parent cache only */
4106 __do_tune_cpucache(c, limit, batchcount, shared, gfp);
4107 }
4108
4109 return ret;
4110}
4111
4087/* Called with slab_mutex held always */ 4112/* Called with slab_mutex held always */
4088static int enable_cpucache(struct kmem_cache *cachep, gfp_t gfp) 4113static int enable_cpucache(struct kmem_cache *cachep, gfp_t gfp)
4089{ 4114{
4090 int err; 4115 int err;
4091 int limit, shared; 4116 int limit = 0;
4117 int shared = 0;
4118 int batchcount = 0;
4119
4120 if (!is_root_cache(cachep)) {
4121 struct kmem_cache *root = memcg_root_cache(cachep);
4122 limit = root->limit;
4123 shared = root->shared;
4124 batchcount = root->batchcount;
4125 }
4092 4126
4127 if (limit && shared && batchcount)
4128 goto skip_setup;
4093 /* 4129 /*
4094 * The head array serves three purposes: 4130 * The head array serves three purposes:
4095 * - create a LIFO ordering, i.e. return objects that are cache-warm 4131 * - create a LIFO ordering, i.e. return objects that are cache-warm
@@ -4131,7 +4167,9 @@ static int enable_cpucache(struct kmem_cache *cachep, gfp_t gfp)
4131 if (limit > 32) 4167 if (limit > 32)
4132 limit = 32; 4168 limit = 32;
4133#endif 4169#endif
4134 err = do_tune_cpucache(cachep, limit, (limit + 1) / 2, shared, gfp); 4170 batchcount = (limit + 1) / 2;
4171skip_setup:
4172 err = do_tune_cpucache(cachep, limit, batchcount, shared, gfp);
4135 if (err) 4173 if (err)
4136 printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n", 4174 printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",
4137 cachep->name, -err); 4175 cachep->name, -err);