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

1  2 
drivers/char/random.c

diff --combined drivers/char/random.c
@@@ -445,7 -445,7 +445,7 @@@ static struct entropy_store input_pool 
        .poolinfo = &poolinfo_table[0],
        .name = "input",
        .limit = 1,
 -      .lock = __SPIN_LOCK_UNLOCKED(&input_pool.lock),
 +      .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
        .pool = input_pool_data
  };
  
@@@ -454,7 -454,7 +454,7 @@@ static struct entropy_store blocking_po
        .name = "blocking",
        .limit = 1,
        .pull = &input_pool,
 -      .lock = __SPIN_LOCK_UNLOCKED(&blocking_pool.lock),
 +      .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock),
        .pool = blocking_pool_data
  };
  
@@@ -462,7 -462,7 +462,7 @@@ static struct entropy_store nonblocking
        .poolinfo = &poolinfo_table[1],
        .name = "nonblocking",
        .pull = &input_pool,
 -      .lock = __SPIN_LOCK_UNLOCKED(&nonblocking_pool.lock),
 +      .lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock),
        .pool = nonblocking_pool_data
  };
  
@@@ -852,6 -852,7 +852,7 @@@ static size_t account(struct entropy_st
                      int reserved)
  {
        unsigned long flags;
+       int wakeup_write = 0;
  
        /* Hold lock while accounting */
        spin_lock_irqsave(&r->lock, flags);
                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",
  
        spin_unlock_irqrestore(&r->lock, flags);
  
+       if (wakeup_write) {
+               wake_up_interruptible(&random_write_wait);
+               kill_fasync(&fasync, SIGIO, POLL_OUT);
+       }
        return nbytes;
  }