When used on a Raspberry Pi 3 with BCM2835_RNG_USE_CALLOUT defined, the boot lok includes a lot of: bcmrng0: Too many underruns, resetting bcmrng0: RNG stalled, disabling device -- Relevant part of boot log: bcmrng0: <Broadcom BCM2835 RNG> mem 0x7e104000-0x7e10400f on simplebus0 bcmrng0: RNG_CTRL (00000001) RNG_COMBLK2_OSC (00) Oscillator 1 enabled Oscillator 2 enabled Oscillator 3 enabled Oscillator 4 enabled Oscillator 5 enabled Oscillator 6 enabled RNG_COMBLK1_OSC (00) Oscillator 1 enabled Oscillator 2 enabled Oscillator 3 enabled Oscillator 4 enabled Oscillator 5 enabled Oscillator 6 enabled RNG_JCLK_BYP_DIV_CNT (00) APB clock frequency / 2 RNG_JCLK_BYP_SRC: Use RNG clock (APB clock) RNG_JCLK_BYP_SEL: Use internal jitter clock RNG_RBGEN_BIT: RBG enabled RNG_CTRL (04040058) RND_VAL: 04 RND_WARM_CNT: 40058 RNG_FF_THRES: 00002 RNG_INT_MASK: interrupt enabledmbox0: <BCM2835 VideoCore Mailbox> mem 0x7e00b880-0x7e00b8bf irq 17 on simplebus0 gpio0: <BCM2708/2835 GPIO controller> mem 0x7e200000-0x7e2000b3 irq 18,19 on simplebus0 gpiobus0: <OFW GPIO bus> on gpio0 gpioc0: <GPIO controller> on gpio0 uart0: <PrimeCell UART (PL011)> mem 0x7e201000-0x7e201fff irq 20 on simplebus0 uart0: console (115200,n,8,1) spi0: <BCM2708/2835 SPI controller> mem 0x7e204000-0x7e204fff irq 21 on simplebus0 spibus0: <OFW SPI bus> on spi0 spigen0: <SPI Generic IO> at cs 0 mode 0 on spibus0 spibus0: <unknown card> at cs 0 mode 0 spibus0: <unknown card> at cs 1 mode 0 iichb0: <BCM2708/2835 BSC controller> mem 0x7e804000-0x7e804fff irq 32 on simplebus0 iicbus0: <OFW I2C bus> on iichb0 iic0: <I2C generic I/O> on iicbus0 bcm283x_dwcotg0: <DWC OTG 2.0 integrated USB controller (bcm283x)> mem 0x7e980000-0x7e98ffff,0x7e006000-0x7e006fff irq 38,39 on simplebus0 usbus0 on bcm283x_dwcotg0 sdhci_bcm0: <Broadcom 2708 SDHCI controller> mem 0x7e300000-0x7e3000ff irq 42 on simplebus0 mmc0: <MMC/SD bus> on sdhci_bcm0 vchiq0: <BCM2835 VCHIQ> mem 0x7e00b840-0x7e00b84e irq 45 on simplebus0 vchiq: local ver 8 (min 3), remote ver 8. pcm0: <VCHIQ audio> on vchiq0 pmu0: <Performance Monitoring Unit> irq 46 on simplebus0 gpioled0: <GPIO LEDs> on ofwbus0 gpioled0: <led1> failed to map pin cpulist0: <Open Firmware CPU Group> on ofwbus0 cpu0: <Open Firmware CPU> on cpulist0 cpu1: <Open Firmware CPU> on cpulist0 cpu2: <Open Firmware CPU> on cpulist0 cpu3: <Open Firmware CPU> on cpulist0 cryptosoft0: <software crypto> Timecounters tick every 1.000 msec usbus0: 480Mbps High Speed USB v2.0 ugen0.1: <DWCOTG OTG Root HUB> at usbus0 uhub0: <DWCOTG OTG Root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus0 bcmrng0: Too many underruns, resetting bcmrng0: RNG stalled, disabling device bcmrng0: Too many underruns, resetting bcmrng0: RNG stalled, disabling device bcmrng0: Too many underruns, resetting bcmrng0: RNG stalled, disabling device
If I replace sc->sc_rnghz = hz / 100; with sc->sc_rnghz = 175; /* or any other value > 175 */ in https://github.com/freebsd/freebsd/blob/master/sys/arm/broadcom/bcm2835/bcm2835_rng.c#L461 the underruns disappear.
Interesting. The RPi3 must be a bit different than the RPi2 (where the initial testing using callout was done.) It might make sense to have a sysctl in the case where one would want to use the callout version to be able to tweak it as appropriate. However, it's better to use the default interrupt method rather than the callout, because, as you saw, there can be cases where the random bit generator (RBG) cannot provide enough bits to satisfy a request, if the callout period is too short. With the interrupt method, the RBG is programmed to raise an interrupt when the FIFO is full. When that occurs, the interrupt handler reads from the FIFO and feeds the bits read into the random_harvest_queue function. However, that requires the FDT for the board to have a proper entry for the RBG with an interrupt attribute, which I don't think the RPi3 FDT has currently.
Fixed by commit r330727.