diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-08 23:42:16 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-08 23:42:16 +0100 |
commit | c77f8bf918e66711938a25b19b188b24971a7d30 (patch) | |
tree | 859badcf79e0e1873108a24930618b69c12835fa /drivers/char | |
parent | vfs: don't BUG_ON() if following a /proc fd pseudo-symlink results in a symlink (diff) | |
parent | random: fix locking dependency with the tasklist_lock (diff) | |
download | linux-c77f8bf918e66711938a25b19b188b24971a7d30.tar.xz linux-c77f8bf918e66711938a25b19b188b24971a7d30.zip |
Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random
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
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/random.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 594bda9dcfc8..32a6c5764950 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -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; } |