Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 STATUS register for the READY bit after writing COMMAND, using readl_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(), checking IRQ_STATUS/RANDOM_READY and returning IRQ_NONE appropriately, since INTx may be shared.
  • Synchronisation: use a struct completion, signalled by the handler after it acknowledges IRQ_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.