aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/random.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-28 12:43:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-28 13:40:47 -0400
commita11e1d432b51f63ba698d044441284a661f01144 (patch)
tree9f3c5a10bf0d7f9a342d5fb39c0c35ea14170124 /drivers/char/random.c
parentf57494321cbf5b1e7769b6135407d2995a369e28 (diff)
Revert changes to convert to ->poll_mask() and aio IOCB_CMD_POLL
The poll() changes were not well thought out, and completely unexplained. They also caused a huge performance regression, because "->poll()" was no longer a trivial file operation that just called down to the underlying file operations, but instead did at least two indirect calls. Indirect calls are sadly slow now with the Spectre mitigation, but the performance problem could at least be largely mitigated by changing the "->get_poll_head()" operation to just have a per-file-descriptor pointer to the poll head instead. That gets rid of one of the new indirections. But that doesn't fix the new complexity that is completely unwarranted for the regular case. The (undocumented) reason for the poll() changes was some alleged AIO poll race fixing, but we don't make the common case slower and more complex for some uncommon special case, so this all really needs way more explanations and most likely a fundamental redesign. [ This revert is a revert of about 30 different commits, not reverted individually because that would just be unnecessarily messy - Linus ] Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/random.c')
-rw-r--r--drivers/char/random.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index a8fb0020ba5c..cd888d4ee605 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -402,7 +402,8 @@ static struct poolinfo {
402/* 402/*
403 * Static global variables 403 * Static global variables
404 */ 404 */
405static DECLARE_WAIT_QUEUE_HEAD(random_wait); 405static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
406static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
406static struct fasync_struct *fasync; 407static struct fasync_struct *fasync;
407 408
408static DEFINE_SPINLOCK(random_ready_list_lock); 409static DEFINE_SPINLOCK(random_ready_list_lock);
@@ -721,8 +722,8 @@ retry:
721 722
722 /* should we wake readers? */ 723 /* should we wake readers? */
723 if (entropy_bits >= random_read_wakeup_bits && 724 if (entropy_bits >= random_read_wakeup_bits &&
724 wq_has_sleeper(&random_wait)) { 725 wq_has_sleeper(&random_read_wait)) {
725 wake_up_interruptible_poll(&random_wait, POLLIN); 726 wake_up_interruptible(&random_read_wait);
726 kill_fasync(&fasync, SIGIO, POLL_IN); 727 kill_fasync(&fasync, SIGIO, POLL_IN);
727 } 728 }
728 /* If the input pool is getting full, send some 729 /* If the input pool is getting full, send some
@@ -1396,7 +1397,7 @@ retry:
1396 trace_debit_entropy(r->name, 8 * ibytes); 1397 trace_debit_entropy(r->name, 8 * ibytes);
1397 if (ibytes && 1398 if (ibytes &&
1398 (r->entropy_count >> ENTROPY_SHIFT) < random_write_wakeup_bits) { 1399 (r->entropy_count >> ENTROPY_SHIFT) < random_write_wakeup_bits) {
1399 wake_up_interruptible_poll(&random_wait, POLLOUT); 1400 wake_up_interruptible(&random_write_wait);
1400 kill_fasync(&fasync, SIGIO, POLL_OUT); 1401 kill_fasync(&fasync, SIGIO, POLL_OUT);
1401 } 1402 }
1402 1403
@@ -1838,7 +1839,7 @@ _random_read(int nonblock, char __user *buf, size_t nbytes)
1838 if (nonblock) 1839 if (nonblock)
1839 return -EAGAIN; 1840 return -EAGAIN;
1840 1841
1841 wait_event_interruptible(random_wait, 1842 wait_event_interruptible(random_read_wait,
1842 ENTROPY_BITS(&input_pool) >= 1843 ENTROPY_BITS(&input_pool) >=
1843 random_read_wakeup_bits); 1844 random_read_wakeup_bits);
1844 if (signal_pending(current)) 1845 if (signal_pending(current))
@@ -1875,17 +1876,14 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
1875 return ret; 1876 return ret;
1876} 1877}
1877 1878
1878static struct wait_queue_head *
1879random_get_poll_head(struct file *file, __poll_t events)
1880{
1881 return &random_wait;
1882}
1883
1884static __poll_t 1879static __poll_t
1885random_poll_mask(struct file *file, __poll_t events) 1880random_poll(struct file *file, poll_table * wait)
1886{ 1881{
1887 __poll_t mask = 0; 1882 __poll_t mask;
1888 1883
1884 poll_wait(file, &random_read_wait, wait);
1885 poll_wait(file, &random_write_wait, wait);
1886 mask = 0;
1889 if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits) 1887 if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits)
1890 mask |= EPOLLIN | EPOLLRDNORM; 1888 mask |= EPOLLIN | EPOLLRDNORM;
1891 if (ENTROPY_BITS(&input_pool) < random_write_wakeup_bits) 1889 if (ENTROPY_BITS(&input_pool) < random_write_wakeup_bits)
@@ -1992,8 +1990,7 @@ static int random_fasync(int fd, struct file *filp, int on)
1992const struct file_operations random_fops = { 1990const struct file_operations random_fops = {
1993 .read = random_read, 1991 .read = random_read,
1994 .write = random_write, 1992 .write = random_write,
1995 .get_poll_head = random_get_poll_head, 1993 .poll = random_poll,
1996 .poll_mask = random_poll_mask,
1997 .unlocked_ioctl = random_ioctl, 1994 .unlocked_ioctl = random_ioctl,
1998 .fasync = random_fasync, 1995 .fasync = random_fasync,
1999 .llseek = noop_llseek, 1996 .llseek = noop_llseek,
@@ -2326,7 +2323,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
2326 * We'll be woken up again once below random_write_wakeup_thresh, 2323 * We'll be woken up again once below random_write_wakeup_thresh,
2327 * or when the calling thread is about to terminate. 2324 * or when the calling thread is about to terminate.
2328 */ 2325 */
2329 wait_event_interruptible(random_wait, kthread_should_stop() || 2326 wait_event_interruptible(random_write_wait, kthread_should_stop() ||
2330 ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits); 2327 ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
2331 mix_pool_bytes(poolp, buffer, count); 2328 mix_pool_bytes(poolp, buffer, count);
2332 credit_entropy_bits(poolp, entropy); 2329 credit_entropy_bits(poolp, entropy);