![Jeff Dike](/assets/img/avatar_default.png)
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: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
24 lines
454 B
C
24 lines
454 B
C
#ifndef __UM_IRQ_H
|
|
#define __UM_IRQ_H
|
|
|
|
#define TIMER_IRQ 0
|
|
#define UMN_IRQ 1
|
|
#define CONSOLE_IRQ 2
|
|
#define CONSOLE_WRITE_IRQ 3
|
|
#define UBD_IRQ 4
|
|
#define UM_ETH_IRQ 5
|
|
#define SSL_IRQ 6
|
|
#define SSL_WRITE_IRQ 7
|
|
#define ACCEPT_IRQ 8
|
|
#define MCONSOLE_IRQ 9
|
|
#define WINCH_IRQ 10
|
|
#define SIGIO_WRITE_IRQ 11
|
|
#define TELNETD_IRQ 12
|
|
#define XTERM_IRQ 13
|
|
#define RANDOM_IRQ 14
|
|
|
|
#define LAST_IRQ RANDOM_IRQ
|
|
#define NR_IRQS (LAST_IRQ + 1)
|
|
|
|
#endif
|