Bug 222256 - RPI random number generator underruns when BCM2835_RNG_USE_CALLOUT is set
Summary: RPI random number generator underruns when BCM2835_RNG_USE_CALLOUT is set
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: arm Any
: --- Affects Only Me
Assignee: freebsd-arm (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-12 12:51 UTC by Sylvain Garrigues
Modified: 2018-03-10 11:38 UTC (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sylvain Garrigues 2017-09-12 12:51:41 UTC
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
Comment 1 Sylvain Garrigues 2017-09-12 14:03:16 UTC
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.
Comment 2 Stephen J. Kiernan freebsd_committer freebsd_triage 2017-09-12 16:52:01 UTC
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.
Comment 3 Sylvain Garrigues 2018-03-10 11:38:30 UTC
Fixed by commit r330727.