]> Pileus Git - ~andy/linux/commitdiff
random: optimize spinlock use in add_device_randomness()
authorTheodore Ts'o <tytso@mit.edu>
Thu, 12 Sep 2013 18:27:22 +0000 (14:27 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 10 Oct 2013 18:32:17 +0000 (14:32 -0400)
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" <tytso@mit.edu>
drivers/char/random.c

index 80b58774e891a906fde1a2eb63729b4ad69153a3..89eb5a8dec826973b7cab1c8df55ffeca915f7f4 100644 (file)
@@ -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);