net: make net_get_random_once irq safe
authorHannes Frederic Sowa <hannes@stressinduktion.org>
Wed, 23 Oct 2013 18:05:27 +0000 (20:05 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 25 Oct 2013 23:03:39 +0000 (19:03 -0400)
I initial build non irq safe version of net_get_random_once because I
would liked to have the freedom to defer even the extraction process of
get_random_bytes until the nonblocking pool is fully seeded.

I don't think this is a good idea anymore and thus this patch makes
net_get_random_once irq safe. Now someone using net_get_random_once does
not need to care from where it is called.

Cc: David S. Miller <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/net.h
net/core/utils.c

index aca446b46754fe681dcb0fb99028ac62c90a68fe..b292a04355717a503b093e2d2c424cf92951415f 100644 (file)
@@ -250,7 +250,6 @@ bool __net_get_random_once(void *buf, int nbytes, bool *done,
 #define ___NET_RANDOM_STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
 #endif /* HAVE_JUMP_LABEL */
 
-/* BE CAREFUL: this function is not interrupt safe */
 #define net_get_random_once(buf, nbytes)                               \
        ({                                                              \
                bool ___ret = false;                                    \
index bf09371e19b146369a6c580e52700588440adf49..2f737bf90b3fe4235c75ccca6640c735ecaa076b 100644 (file)
@@ -370,16 +370,17 @@ bool __net_get_random_once(void *buf, int nbytes, bool *done,
                           struct static_key *done_key)
 {
        static DEFINE_SPINLOCK(lock);
+       unsigned long flags;
 
-       spin_lock_bh(&lock);
+       spin_lock_irqsave(&lock, flags);
        if (*done) {
-               spin_unlock_bh(&lock);
+               spin_unlock_irqrestore(&lock, flags);
                return false;
        }
 
        get_random_bytes(buf, nbytes);
        *done = true;
-       spin_unlock_bh(&lock);
+       spin_unlock_irqrestore(&lock, flags);
 
        __net_random_once_disable_jump(done_key);