1
0
Fork 0

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>
hifive-unleashed-5.1
Christoph Lameter 2008-04-14 19:11:41 +03:00 committed by Pekka Enberg
parent 319d1e2406
commit 06b285dc3d
1 changed files with 22 additions and 7 deletions

View File

@ -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);