opnsense-src/sys/dev/random
Mark Johnston 9940c97402 random: Change the entropy harvest event queuing scheme
The entropy queue stores entropy gathered from environmental sources.
Periodically (every 100ms currently), the random kthread will drain this
queue and mix it into the CSPRNG's entropy pool(s).

The old scheme uses a ring buffer with a mutex to serialize producers,
while the sole consumer, the random kthread, avoids using a mutex on the
basis that no serialization is needed since nothing else is updating the
consumer index.  On platforms without total store ordering, however,
this isn't sufficient: when a producer inserts a queue entry and updates
`ring.in`, there is no guarantee that the consumer will see the updated
queue entry upon observing the updated producer index.  That is, the
update to `ring.in` may be visible before the updated queue entry is
visible.  As a result, we could end up mixing in zero'ed queue entries,
though this race is fairly unlikely in practice given how infrequently
the kthread runs.

The easiest way to fix this is to make the kthread acquire the mutex as
well, and hold it while processing queue entries.  However, this might
result in a long hold time if there are many queue entries, and we
really want the hold times to be short, e.g., to avoid delaying
interrupt processing.

We could introduce a proper MPSC queue, but this is probably
overcomplicated for a consumer which runs at 10Hz.

Instead, define two buffers, always with one designated as the "active"
buffer.  Producers queue entries in the active buffer, and the kthread
uses the mutex to atomically flip the two buffers, so it can process
entries from the inactive buffer without holding the mutex.  This
requires more memory, but keeps mutex hold times short and lets us keep
the queue implementation very simple.

Reviewed by:	cem
MFC after:	1 month
Sponsored by:	Stormshield
Sponsored by:	Klara, Inc.
Differential Revision:	https://reviews.freebsd.org/D51112
2025-07-07 15:41:57 +00:00
..
fenestrasX machine/stdarg.h -> sys/stdarg.h 2025-06-11 17:39:02 +01:00
armv8rng.c armv8rng: Don't require toolchain to support FEAT_RNG 2023-12-01 23:59:07 +00:00
build.sh sys: Remove $FreeBSD$: one-line sh pattern 2023-08-16 11:54:58 -06:00
darn.c sys: Automated cleanup of cdefs and other formatting 2023-11-26 22:24:00 -07:00
fortuna.c random: Avoid magic numbers 2024-09-22 00:35:47 -07:00
fortuna.h random: Avoid magic numbers 2024-09-22 00:35:47 -07:00
hash.c random(4): Fix a typo in a source code comment 2024-02-22 16:54:50 +01:00
hash.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
ivy.c sys: Automated cleanup of cdefs and other formatting 2023-11-26 22:24:00 -07:00
nehemiah.c sys: Automated cleanup of cdefs and other formatting 2023-11-26 22:24:00 -07:00
other_algorithm.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
other_algorithm.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
random_harvestq.c random: Change the entropy harvest event queuing scheme 2025-07-07 15:41:57 +00:00
random_harvestq.h random: Define a macro for getting the CPU cycle count 2025-07-03 17:31:42 +00:00
random_infra.c sys: Automated cleanup of cdefs and other formatting 2023-11-26 22:24:00 -07:00
randomdev.c random: Define a macro for getting the CPU cycle count 2025-07-03 17:31:42 +00:00
randomdev.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
uint128.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
unit_test.c sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
unit_test.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00