From 3ef4cb2d65ee13d84140cbede8e1980c6ae49ffd Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 12 Sep 2013 14:27:22 -0400 Subject: [PATCH] random: optimize spinlock use in add_device_randomness() The add_device_randomness() function calls mix_pool_bytes() twice for the input pool and the non-blocking pool, for a total of four times. By using _mix_pool_byte() and taking the spinlock in add_device_randomness(), we can halve the number of times we need take each pool's spinlock. Signed-off-by: "Theodore Ts'o" --- drivers/char/random.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 80b58774e891..89eb5a8dec82 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -710,12 +710,18 @@ struct timer_rand_state { void add_device_randomness(const void *buf, unsigned int size) { unsigned long time = random_get_entropy() ^ jiffies; + unsigned long flags; trace_add_device_randomness(size, _RET_IP_); - mix_pool_bytes(&input_pool, buf, size, NULL); - mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); - mix_pool_bytes(&nonblocking_pool, buf, size, NULL); - mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); + spin_lock_irqsave(&input_pool.lock, flags); + _mix_pool_bytes(&input_pool, buf, size, NULL); + _mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); + spin_unlock_irqrestore(&input_pool.lock, flags); + + spin_lock_irqsave(&nonblocking_pool.lock, flags); + _mix_pool_bytes(&nonblocking_pool, buf, size, NULL); + _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); + spin_unlock_irqrestore(&nonblocking_pool.lock, flags); } EXPORT_SYMBOL(add_device_randomness); -- 2.39.5