Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Mar 2013 22:42:16 +0000 (14:42 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Mar 2013 22:42:16 +0000 (14:42 -0800)
Pull random fixes from Ted Ts'o:
 "Fix a circular locking dependency in random's collection of cputime
  used by a thread when it exits."

* tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random:
  random: fix locking dependency with the tasklist_lock

drivers/char/random.c

index 594bda9..32a6c57 100644 (file)
@@ -852,6 +852,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
                      int reserved)
 {
        unsigned long flags;
+       int wakeup_write = 0;
 
        /* Hold lock while accounting */
        spin_lock_irqsave(&r->lock, flags);
@@ -873,10 +874,8 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
                else
                        r->entropy_count = reserved;
 
-               if (r->entropy_count < random_write_wakeup_thresh) {
-                       wake_up_interruptible(&random_write_wait);
-                       kill_fasync(&fasync, SIGIO, POLL_OUT);
-               }
+               if (r->entropy_count < random_write_wakeup_thresh)
+                       wakeup_write = 1;
        }
 
        DEBUG_ENT("debiting %zu entropy credits from %s%s\n",
@@ -884,6 +883,11 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
 
        spin_unlock_irqrestore(&r->lock, flags);
 
+       if (wakeup_write) {
+               wake_up_interruptible(&random_write_wait);
+               kill_fasync(&fasync, SIGIO, POLL_OUT);
+       }
+
        return nbytes;
 }