diff --git a/mm/slub.c b/mm/slub.c index de7f0c7050b3..56549f8c147d 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1484,6 +1484,25 @@ static int init_cache_random_seq(struct kmem_cache *s) return 0; } +/* re-initialize the random sequence cache */ +static int reinit_cache_random_seq(struct kmem_cache *s) +{ + int err; + + if (s->random_seq) { + cache_random_seq_destroy(s); + err = init_cache_random_seq(s); + + if (err) { + pr_err("SLUB: Unable to re-initialize random sequence cache for %s\n", + s->name); + return err; + } + } + + return 0; +} + /* Initialize each random sequence freelist per cache */ static void __init init_freelist_randomization(void) { @@ -1558,6 +1577,10 @@ static inline int init_cache_random_seq(struct kmem_cache *s) { return 0; } +static inline int reinit_cache_random_seq(struct kmem_cache *s) +{ + return 0; +} static inline void init_freelist_randomization(void) { } static inline bool shuffle_freelist(struct kmem_cache *s, struct page *page) { @@ -4928,6 +4951,7 @@ static ssize_t order_store(struct kmem_cache *s, return -EINVAL; calculate_sizes(s, order); + reinit_cache_random_seq(s); return length; } @@ -5165,6 +5189,7 @@ static ssize_t red_zone_store(struct kmem_cache *s, s->flags |= SLAB_RED_ZONE; } calculate_sizes(s, -1); + reinit_cache_random_seq(s); return length; } SLAB_ATTR(red_zone); @@ -5185,6 +5210,7 @@ static ssize_t poison_store(struct kmem_cache *s, s->flags |= SLAB_POISON; } calculate_sizes(s, -1); + reinit_cache_random_seq(s); return length; } SLAB_ATTR(poison); @@ -5206,6 +5232,7 @@ static ssize_t store_user_store(struct kmem_cache *s, s->flags |= SLAB_STORE_USER; } calculate_sizes(s, -1); + reinit_cache_random_seq(s); return length; } SLAB_ATTR(store_user);