mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-05 20:55:51 +00:00
slub: Make the order configurable for each slab cache
Makes /sys/kernel/slab/<slabname>/order writable. The allocation order of a slab cache can then be changed dynamically during runtime. This can be used to override the objects per slabs value establisheed with the slub_min_objects setting that was manually specified or calculated on bootup. The changes of the slab order can occur while allocate_slab() runs. Allocate slab needs the order and the number of slab objects that are both changed by the change of order. Both are put into a single word (struct kmem_cache_order_objects). They can then be atomically updated and retrieved. Signed-off-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
This commit is contained in:
parent
319d1e2406
commit
06b285dc3d
29
mm/slub.c
29
mm/slub.c
@ -2218,7 +2218,7 @@ static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
|
||||
* calculate_sizes() determines the order and the distribution of data within
|
||||
* a slab object.
|
||||
*/
|
||||
static int calculate_sizes(struct kmem_cache *s)
|
||||
static int calculate_sizes(struct kmem_cache *s, int forced_order)
|
||||
{
|
||||
unsigned long flags = s->flags;
|
||||
unsigned long size = s->objsize;
|
||||
@ -2307,7 +2307,10 @@ static int calculate_sizes(struct kmem_cache *s)
|
||||
*/
|
||||
size = ALIGN(size, align);
|
||||
s->size = size;
|
||||
order = calculate_order(size);
|
||||
if (forced_order >= 0)
|
||||
order = forced_order;
|
||||
else
|
||||
order = calculate_order(size);
|
||||
|
||||
if (order < 0)
|
||||
return 0;
|
||||
@ -2346,7 +2349,7 @@ static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
|
||||
s->align = align;
|
||||
s->flags = kmem_cache_flags(size, flags, name, ctor);
|
||||
|
||||
if (!calculate_sizes(s))
|
||||
if (!calculate_sizes(s, -1))
|
||||
goto error;
|
||||
|
||||
s->refcount = 1;
|
||||
@ -3833,11 +3836,23 @@ static ssize_t objs_per_slab_show(struct kmem_cache *s, char *buf)
|
||||
}
|
||||
SLAB_ATTR_RO(objs_per_slab);
|
||||
|
||||
static ssize_t order_store(struct kmem_cache *s,
|
||||
const char *buf, size_t length)
|
||||
{
|
||||
int order = simple_strtoul(buf, NULL, 10);
|
||||
|
||||
if (order > slub_max_order || order < slub_min_order)
|
||||
return -EINVAL;
|
||||
|
||||
calculate_sizes(s, order);
|
||||
return length;
|
||||
}
|
||||
|
||||
static ssize_t order_show(struct kmem_cache *s, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", oo_order(s->oo));
|
||||
}
|
||||
SLAB_ATTR_RO(order);
|
||||
SLAB_ATTR(order);
|
||||
|
||||
static ssize_t ctor_show(struct kmem_cache *s, char *buf)
|
||||
{
|
||||
@ -3971,7 +3986,7 @@ static ssize_t red_zone_store(struct kmem_cache *s,
|
||||
s->flags &= ~SLAB_RED_ZONE;
|
||||
if (buf[0] == '1')
|
||||
s->flags |= SLAB_RED_ZONE;
|
||||
calculate_sizes(s);
|
||||
calculate_sizes(s, -1);
|
||||
return length;
|
||||
}
|
||||
SLAB_ATTR(red_zone);
|
||||
@ -3990,7 +4005,7 @@ static ssize_t poison_store(struct kmem_cache *s,
|
||||
s->flags &= ~SLAB_POISON;
|
||||
if (buf[0] == '1')
|
||||
s->flags |= SLAB_POISON;
|
||||
calculate_sizes(s);
|
||||
calculate_sizes(s, -1);
|
||||
return length;
|
||||
}
|
||||
SLAB_ATTR(poison);
|
||||
@ -4009,7 +4024,7 @@ static ssize_t store_user_store(struct kmem_cache *s,
|
||||
s->flags &= ~SLAB_STORE_USER;
|
||||
if (buf[0] == '1')
|
||||
s->flags |= SLAB_STORE_USER;
|
||||
calculate_sizes(s);
|
||||
calculate_sizes(s, -1);
|
||||
return length;
|
||||
}
|
||||
SLAB_ATTR(store_user);
|
||||
|
Loading…
Reference in New Issue
Block a user