crng_init is protected by primary_crng->lock. Therefore, we need to hold this lock when increasing crng_init to 2. As we shouldn't hold this lock for too long, only hold it for those parts which require protection. Signed-off-by: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx> --- drivers/char/random.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index cc4d9d414df2..aee56032ebb4 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -497,6 +497,7 @@ static void crng_slow_load(const void *cp, unsigned int len) static void crng_reseed(void) { + bool complete_init = false; unsigned long flags; int entropy_count; unsigned long next_gen; @@ -526,12 +527,14 @@ static void crng_reseed(void) ++next_gen; WRITE_ONCE(base_crng.generation, next_gen); base_crng.birth = jiffies; - spin_unlock_irqrestore(&base_crng.lock, flags); - memzero_explicit(key, sizeof(key)); - if (crng_init < 2) { invalidate_batched_entropy(); crng_init = 2; + complete_init = true; + } + spin_unlock_irqrestore(&base_crng.lock, flags); + memzero_explicit(key, sizeof(key)); + if (complete_init) { process_random_ready_list(); wake_up_interruptible(&crng_init_wait); kill_fasync(&fasync, SIGIO, POLL_IN);