On Mon, 6 Jun 2016 22:11:37 -0700 Randy Dunlap <rdunlap@xxxxxxxxxxxxx> wrote: > On 06/05/16 21:20, Stephen Rothwell wrote: > > Hi all, > > > > Changes since 20160603: > > > > on i386: > > mm/built-in.o: In function `init_cache_random_seq': > slub.c:(.text+0x76921): undefined reference to `cache_random_seq_create' > mm/built-in.o: In function `__kmem_cache_release': > (.text+0x80525): undefined reference to `cache_random_seq_destroy' Yup. This, I guess... From: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Subject: mm-slub-freelist-randomization-fix freelist_randomize(), cache_random_seq_create() and cache_random_seq_destroy() should not be inside CONFIG_SLABINFO. Cc: Christoph Lameter <cl@xxxxxxxxx> Cc: David Rientjes <rientjes@xxxxxxxxxx> Cc: Joonsoo Kim <iamjoonsoo.kim@xxxxxxx> Cc: Kees Cook <keescook@xxxxxxxxxxxx> Cc: Pekka Enberg <penberg@xxxxxxxxxx> Cc: Thomas Garnier <thgarnie@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- --- a/mm/slab_common.c~mm-reorganize-slab-freelist-randomization-fix +++ a/mm/slab_common.c @@ -1030,6 +1030,53 @@ void *kmalloc_order_trace(size_t size, g EXPORT_SYMBOL(kmalloc_order_trace); #endif +#ifdef CONFIG_SLAB_FREELIST_RANDOM +/* Randomize a generic freelist */ +static void freelist_randomize(struct rnd_state *state, unsigned int *list, + size_t count) +{ + size_t i; + unsigned int rand; + + for (i = 0; i < count; i++) + list[i] = i; + + /* Fisher-Yates shuffle */ + for (i = count - 1; i > 0; i--) { + rand = prandom_u32_state(state); + rand %= (i + 1); + swap(list[i], list[rand]); + } +} + +/* Create a random sequence per cache */ +int cache_random_seq_create(struct kmem_cache *cachep, unsigned int count, + gfp_t gfp) +{ + struct rnd_state state; + + if (count < 2 || cachep->random_seq) + return 0; + + cachep->random_seq = kcalloc(count, sizeof(unsigned int), gfp); + if (!cachep->random_seq) + return -ENOMEM; + + /* Get best entropy at this stage of boot */ + prandom_seed_state(&state, get_random_long()); + + freelist_randomize(&state, cachep->random_seq, count); + return 0; +} + +/* Destroy the per-cache random freelist sequence */ +void cache_random_seq_destroy(struct kmem_cache *cachep) +{ + kfree(cachep->random_seq); + cachep->random_seq = NULL; +} +#endif /* CONFIG_SLAB_FREELIST_RANDOM */ + #ifdef CONFIG_SLABINFO #ifdef CONFIG_SLAB @@ -1142,53 +1189,6 @@ int memcg_slab_show(struct seq_file *m, } #endif -#ifdef CONFIG_SLAB_FREELIST_RANDOM -/* Randomize a generic freelist */ -static void freelist_randomize(struct rnd_state *state, unsigned int *list, - size_t count) -{ - size_t i; - unsigned int rand; - - for (i = 0; i < count; i++) - list[i] = i; - - /* Fisher-Yates shuffle */ - for (i = count - 1; i > 0; i--) { - rand = prandom_u32_state(state); - rand %= (i + 1); - swap(list[i], list[rand]); - } -} - -/* Create a random sequence per cache */ -int cache_random_seq_create(struct kmem_cache *cachep, unsigned int count, - gfp_t gfp) -{ - struct rnd_state state; - - if (count < 2 || cachep->random_seq) - return 0; - - cachep->random_seq = kcalloc(count, sizeof(unsigned int), gfp); - if (!cachep->random_seq) - return -ENOMEM; - - /* Get best entropy at this stage of boot */ - prandom_seed_state(&state, get_random_long()); - - freelist_randomize(&state, cachep->random_seq, count); - return 0; -} - -/* Destroy the per-cache random freelist sequence */ -void cache_random_seq_destroy(struct kmem_cache *cachep) -{ - kfree(cachep->random_seq); - cachep->random_seq = NULL; -} -#endif /* CONFIG_SLAB_FREELIST_RANDOM */ - /* * slabinfo_op - iterator that generates /proc/slabinfo * _ -- To unsubscribe from this list: send the line "unsubscribe linux-next" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html