From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Theodore Tso <tytso@mit.edu>,
Sultan Alsawaf <sultan@kerneltoast.com>,
Dominik Brodowski <linux@dominikbrodowski.net>,
"Jason A. Donenfeld" <Jason@zx2c4.com>
Subject: [PATCH 5.18 35/47] random: use static branch for crng_ready()
Date: Fri, 27 May 2022 10:50:15 +0200 [thread overview]
Message-ID: <20220527084807.168271453@linuxfoundation.org> (raw)
In-Reply-To: <20220527084801.223648383@linuxfoundation.org>
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
commit f5bda35fba615ace70a656d4700423fa6c9bebee upstream.
Since crng_ready() is only false briefly during initialization and then
forever after becomes true, we don't need to evaluate it after, making
it a prime candidate for a static branch.
One complication, however, is that it changes state in a particular call
to credit_init_bits(), which might be made from atomic context, which
means we must kick off a workqueue to change the static key. Further
complicating things, credit_init_bits() may be called sufficiently early
on in system initialization such that system_wq is NULL.
Fortunately, there exists the nice function execute_in_process_context(),
which will immediately execute the function if !in_interrupt(), and
otherwise defer it to a workqueue. During early init, before workqueues
are available, in_interrupt() is always false, because interrupts
haven't even been enabled yet, which means the function in that case
executes immediately. Later on, after workqueues are available,
in_interrupt() might be true, but in that case, the work is queued in
system_wq and all goes well.
Cc: Theodore Ts'o <tytso@mit.edu>
Cc: Sultan Alsawaf <sultan@kerneltoast.com>
Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/char/random.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -77,8 +77,9 @@ static enum {
CRNG_EMPTY = 0, /* Little to no entropy collected */
CRNG_EARLY = 1, /* At least POOL_EARLY_BITS collected */
CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */
-} crng_init = CRNG_EMPTY;
-#define crng_ready() (likely(crng_init >= CRNG_READY))
+} crng_init __read_mostly = CRNG_EMPTY;
+static DEFINE_STATIC_KEY_FALSE(crng_is_ready);
+#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)
/* Various types of waiters for crng_init->CRNG_READY transition. */
static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
static struct fasync_struct *fasync;
@@ -108,6 +109,11 @@ bool rng_is_initialized(void)
}
EXPORT_SYMBOL(rng_is_initialized);
+static void crng_set_ready(struct work_struct *work)
+{
+ static_branch_enable(&crng_is_ready);
+}
+
/* Used by wait_for_random_bytes(), and considered an entropy collector, below. */
static void try_to_generate_entropy(void);
@@ -267,7 +273,7 @@ static void crng_reseed(void)
++next_gen;
WRITE_ONCE(base_crng.generation, next_gen);
WRITE_ONCE(base_crng.birth, jiffies);
- if (!crng_ready())
+ if (!static_branch_likely(&crng_is_ready))
crng_init = CRNG_READY;
spin_unlock_irqrestore(&base_crng.lock, flags);
memzero_explicit(key, sizeof(key));
@@ -785,6 +791,7 @@ static void extract_entropy(void *buf, s
static void credit_init_bits(size_t nbits)
{
+ static struct execute_work set_ready;
unsigned int new, orig, add;
unsigned long flags;
@@ -800,6 +807,7 @@ static void credit_init_bits(size_t nbit
if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) {
crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */
+ execute_in_process_context(crng_set_ready, &set_ready);
process_random_ready_list();
wake_up_interruptible(&crng_init_wait);
kill_fasync(&fasync, SIGIO, POLL_IN);
@@ -1348,7 +1356,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if (count > INT_MAX)
count = INT_MAX;
- if (!(flags & GRND_INSECURE) && !crng_ready()) {
+ if (!crng_ready() && !(flags & GRND_INSECURE)) {
int ret;
if (flags & GRND_NONBLOCK)
next prev parent reply other threads:[~2022-05-27 8:59 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-27 8:49 [PATCH 5.18 00/47] 5.18.1-rc1 review Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 01/47] lockdown: also lock down previous kgdb use Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 02/47] HID: amd_sfh: Add support for sensor discovery Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 03/47] random: fix sysctl documentation nits Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 04/47] init: call time_init() before rand_initialize() Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 05/47] ia64: define get_cycles macro for arch-override Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 06/47] s390: " Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 07/47] parisc: " Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 08/47] alpha: " Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 09/47] powerpc: " Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 10/47] timekeeping: Add raw clock fallback for random_get_entropy() Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 11/47] m68k: use fallback for random_get_entropy() instead of zero Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 12/47] riscv: " Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 13/47] mips: use fallback for random_get_entropy() instead of just c0 random Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 14/47] arm: use fallback for random_get_entropy() instead of zero Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 15/47] nios2: " Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 16/47] x86/tsc: Use " Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 17/47] um: use " Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 18/47] sparc: " Greg Kroah-Hartman
2022-05-27 8:49 ` [PATCH 5.18 19/47] xtensa: " Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 20/47] random: insist on random_get_entropy() existing in order to simplify Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 21/47] random: do not use batches when !crng_ready() Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 22/47] random: use first 128 bits of input as fast init Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 23/47] random: do not pretend to handle premature next security model Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 24/47] random: order timer entropy functions below interrupt functions Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 25/47] random: do not use input pool from hard IRQs Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 26/47] random: help compiler out with fast_mix() by using simpler arguments Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 27/47] siphash: use one source of truth for siphash permutations Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 28/47] random: use symbolic constants for crng_init states Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 29/47] random: avoid initializing twice in credit race Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 30/47] random: move initialization out of reseeding hot path Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 31/47] random: remove ratelimiting for in-kernel unseeded randomness Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 32/47] random: use proper jiffies comparison macro Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 33/47] random: handle latent entropy and command line from random_init() Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 34/47] random: credit architectural init the exact amount Greg Kroah-Hartman
2022-05-27 8:50 ` Greg Kroah-Hartman [this message]
2022-05-27 8:50 ` [PATCH 5.18 36/47] random: remove extern from functions in header Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 37/47] random: use proper return types on get_random_{int,long}_wait() Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 38/47] random: make consistent use of buf and len Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 39/47] random: move initialization functions out of hot pages Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 40/47] random: move randomize_page() into mm where it belongs Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 41/47] random: unify batched entropy implementations Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 42/47] random: convert to using fops->read_iter() Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 43/47] random: convert to using fops->write_iter() Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 44/47] random: wire up fops->splice_{read,write}_iter() Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 45/47] random: check for signals after page of pool writes Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 46/47] ACPI: sysfs: Fix BERT error region memory mapping Greg Kroah-Hartman
2022-05-27 8:50 ` [PATCH 5.18 47/47] ALSA: ctxfi: Add SB046x PCI ID Greg Kroah-Hartman
2022-05-27 22:40 ` [PATCH 5.18 00/47] 5.18.1-rc1 review Guenter Roeck
2022-05-28 1:53 ` Justin Forbes
2022-05-28 2:24 ` Ron Economos
2022-05-28 2:50 ` Bagas Sanjaya
2022-05-28 11:16 ` Naresh Kamboju
2022-05-28 13:39 ` Rudi Heitbaum
2022-05-29 2:48 ` Fox Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220527084807.168271453@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=Jason@zx2c4.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@dominikbrodowski.net \
--cc=stable@vger.kernel.org \
--cc=sultan@kerneltoast.com \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.