Asynchronous RNG: Writing the Driver
Implement the driver for the asynchronous RNG in the kernel source tree, in a new file named drivers/misc/edu-rng-async.c.
The user-space API exposed by the driver should be similar to that of the synchronous RNG: a character device /dev/edu_rng_async should be created, supporting two ioctl operations: EDU_RNG_ASYNC_IOCTL_RAND and EDU_RNG_ASYNC_IOCTL_SEED.
A kernel user-space API header file edu-rng-async.h should share the device file name and ioctl definitions with user space.
Make sure to reuse the knowledge you gained during the development of the driver for the synchronous device. This part of the exercise is less guided vs. how we proceeded with the synchronous RNG, and you can use AI tools responsibly to implement the driver. Once again we assume no concurrent accesses: the device and its driver are accessed by a single process/thread at a time.
Hints
Two implementation strategies are possible for detecting completion of a generation operation.
Polling Version
- Polling with a timeout: poll the
STATUSregister for theREADYbit after writingCOMMAND, usingreadl_poll_timeout()to avoid busy-spinning. - No interrupt registered: explicitly disable the device’s INTx assertion (
pci_intx(pdev, 0)).
Interrupt-Driven Version
- Interrupt registration: enable the device’s legacy PCI INTx line and register a handler with
request_irq(), checkingIRQ_STATUS/RANDOM_READYand returningIRQ_NONEappropriately, since INTx may be shared. - Synchronisation: use a
struct completion, signalled by the handler after it acknowledgesIRQ_STATUS(write-one-to-clear), and waited on with a timeout from the ioctl path. - Cleanup: free the IRQ and complete any waiters in your driver code’s
remove()/error paths.
The interrupt-based wait is clearly the superior approach here, as the waiting driver code can sleep without wasting CPU cycles on polling, and is woken up as soon as the generated random number is ready.
Testing the Driver
Use the application (edu-rng-async-app.c) and the test suite (edu-rng-async-test-suite.c) present in shared-folder/ to check the validity of the driver.
These programs are very similar to the ones used for the synchronous RNG.
The main difference is that they use a different kernel user-space API header defining the specific device file name and ioctls for the asynchronous device mentioned above.
The stress test in the test suite also runs for a lower number of iterations, as obtaining a random number takes more time with the asynchronous component due to the generation delay.