diff --git a/mm/slub.c b/mm/slub.c index c79824a96470..2f40d511d172 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1541,6 +1541,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) { @@ -1615,6 +1634,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) { @@ -4968,6 +4991,7 @@ static ssize_t order_store(struct kmem_cache *s, return -EINVAL; calculate_sizes(s, order); + reinit_cache_random_seq(s); return length; } @@ -5205,6 +5229,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); @@ -5225,6 +5250,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); @@ -5246,6 +5272,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);