• Jeff Dike's avatar
    uml: random driver fixes · 5d33e4d7
    Jeff Dike authored
    The random driver would essentially hang if the host's /dev/random returned
    -EAGAIN.  There was a test of need_resched followed by a schedule inside the
    loop, but that didn't help and it's the wrong way to work anyway.
    
    The right way is to ask for an interrupt when there is input available from
    the host and handle it then rather than polling.
    
    Now, when the host's /dev/random returns -EAGAIN, the driver asks for a wakeup
    when there's randomness available again and sleeps.  The interrupt routine
    just wakes up whatever processes are sleeping on host_read_wait.
    
    There is an atomic_t, host_sleep_count, which counts the number of processes
    waiting for randomness.  When this reaches zero, the interrupt is disabled.
    
    An added complication is that async I/O notification was only recently added
    to /dev/random (by me), so essentially all hosts will lack it.  So, we use the
    sigio workaround here, which is to have a separate thread poll on the
    descriptor and send an interrupt when there is input on it.  This mechanism is
    activated when a process gets -EAGAIN (activating this multiple times is
    harmless, if a bit wasteful) and deactivated by the last process still
    waiting.
    
    The module name was changed from "random" to "hw_random" in order for udev to
    recognize it.
    
    The sigio workaround needed some changes.  sigio_broken was added for cases
    when we know that async notification doesn't work.  This is now called from
    maybe_sigio_broken, which deals with pts devices.
    Signed-off-by: default avatarJeff Dike <jdike@linux.intel.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    5d33e4d7
process.h 427 Bytes