random: convert to ->poll_mask
authorChristoph Hellwig <hch@lst.de>
Mon, 9 Apr 2018 13:29:32 +0000 (15:29 +0200)
committerChristoph Hellwig <hch@lst.de>
Sat, 26 May 2018 07:16:44 +0000 (09:16 +0200)
The big change is that random_read_wait and random_write_wait are merged
into a single waitqueue that uses keyed wakeups.  Because wait_event_*
doesn't know about that this will lead to occassional spurious wakeups
in _random_read and add_hwgenerator_randomness, but wait_event_* is
designed to handle these and were are not in a a hot path there.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/char/random.c

index cd888d4ee605e0b9cf5f4970d34989d4b72f3b72..a8fb0020ba5ccfb9f4b72b689544299815fab60a 100644 (file)
@@ -402,8 +402,7 @@ static struct poolinfo {
 /*
  * Static global variables
  */
-static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
-static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
+static DECLARE_WAIT_QUEUE_HEAD(random_wait);
 static struct fasync_struct *fasync;
 
 static DEFINE_SPINLOCK(random_ready_list_lock);
@@ -722,8 +721,8 @@ retry:
 
                /* should we wake readers? */
                if (entropy_bits >= random_read_wakeup_bits &&
-                   wq_has_sleeper(&random_read_wait)) {
-                       wake_up_interruptible(&random_read_wait);
+                   wq_has_sleeper(&random_wait)) {
+                       wake_up_interruptible_poll(&random_wait, POLLIN);
                        kill_fasync(&fasync, SIGIO, POLL_IN);
                }
                /* If the input pool is getting full, send some
@@ -1397,7 +1396,7 @@ retry:
        trace_debit_entropy(r->name, 8 * ibytes);
        if (ibytes &&
            (r->entropy_count >> ENTROPY_SHIFT) < random_write_wakeup_bits) {
-               wake_up_interruptible(&random_write_wait);
+               wake_up_interruptible_poll(&random_wait, POLLOUT);
                kill_fasync(&fasync, SIGIO, POLL_OUT);
        }
 
@@ -1839,7 +1838,7 @@ _random_read(int nonblock, char __user *buf, size_t nbytes)
                if (nonblock)
                        return -EAGAIN;
 
-               wait_event_interruptible(random_read_wait,
+               wait_event_interruptible(random_wait,
                        ENTROPY_BITS(&input_pool) >=
                        random_read_wakeup_bits);
                if (signal_pending(current))
@@ -1876,14 +1875,17 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
        return ret;
 }
 
+static struct wait_queue_head *
+random_get_poll_head(struct file *file, __poll_t events)
+{
+       return &random_wait;
+}
+
 static __poll_t
-random_poll(struct file *file, poll_table * wait)
+random_poll_mask(struct file *file, __poll_t events)
 {
-       __poll_t mask;
+       __poll_t mask = 0;
 
-       poll_wait(file, &random_read_wait, wait);
-       poll_wait(file, &random_write_wait, wait);
-       mask = 0;
        if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits)
                mask |= EPOLLIN | EPOLLRDNORM;
        if (ENTROPY_BITS(&input_pool) < random_write_wakeup_bits)
@@ -1990,7 +1992,8 @@ static int random_fasync(int fd, struct file *filp, int on)
 const struct file_operations random_fops = {
        .read  = random_read,
        .write = random_write,
-       .poll  = random_poll,
+       .get_poll_head  = random_get_poll_head,
+       .poll_mask  = random_poll_mask,
        .unlocked_ioctl = random_ioctl,
        .fasync = random_fasync,
        .llseek = noop_llseek,
@@ -2323,7 +2326,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
         * We'll be woken up again once below random_write_wakeup_thresh,
         * or when the calling thread is about to terminate.
         */
-       wait_event_interruptible(random_write_wait, kthread_should_stop() ||
+       wait_event_interruptible(random_wait, kthread_should_stop() ||
                        ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
        mix_pool_bytes(poolp, buffer, count);
        credit_entropy_bits(poolp, entropy);