lkml.org 
[lkml]   [2022]   [May]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.17 094/111] random: move initialization out of reseeding hot path
    Date
    From: "Jason A. Donenfeld" <Jason@zx2c4.com>

    commit 68c9c8b192c6dae9be6278e98ee44029d5da2d31 upstream.

    Initialization happens once -- by way of credit_init_bits() -- and then
    it never happens again. Therefore, it doesn't need to be in
    crng_reseed(), which is a hot path that is called multiple times. It
    also doesn't make sense to have there, as initialization activity is
    better associated with initialization routines.

    After the prior commit, crng_reseed() now won't be called by multiple
    concurrent callers, which means that we can safely move the
    "finialize_init" logic into crng_init_bits() unconditionally.

    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 | 42 +++++++++++++++++++-----------------------
    1 file changed, 19 insertions(+), 23 deletions(-)

    --- a/drivers/char/random.c
    +++ b/drivers/char/random.c
    @@ -264,7 +264,6 @@ static void crng_reseed(void)
    unsigned long flags;
    unsigned long next_gen;
    u8 key[CHACHA_KEY_SIZE];
    - bool finalize_init = false;

    extract_entropy(key, sizeof(key));

    @@ -281,28 +280,10 @@ static void crng_reseed(void)
    ++next_gen;
    WRITE_ONCE(base_crng.generation, next_gen);
    WRITE_ONCE(base_crng.birth, jiffies);
    - if (!crng_ready()) {
    + if (!crng_ready())
    crng_init = CRNG_READY;
    - finalize_init = true;
    - }
    spin_unlock_irqrestore(&base_crng.lock, flags);
    memzero_explicit(key, sizeof(key));
    - if (finalize_init) {
    - process_random_ready_list();
    - wake_up_interruptible(&crng_init_wait);
    - kill_fasync(&fasync, SIGIO, POLL_IN);
    - pr_notice("crng init done\n");
    - if (unseeded_warning.missed) {
    - pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n",
    - unseeded_warning.missed);
    - unseeded_warning.missed = 0;
    - }
    - if (urandom_warning.missed) {
    - pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
    - urandom_warning.missed);
    - urandom_warning.missed = 0;
    - }
    - }
    }

    /*
    @@ -834,10 +815,25 @@ static void credit_init_bits(size_t nbit
    new = min_t(unsigned int, POOL_BITS, orig + add);
    } while (cmpxchg(&input_pool.init_bits, orig, new) != orig);

    - if (orig < POOL_READY_BITS && new >= POOL_READY_BITS)
    - crng_reseed();
    - else if (orig < POOL_EARLY_BITS && new >= POOL_EARLY_BITS) {
    + if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) {
    + crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */
    + process_random_ready_list();
    + wake_up_interruptible(&crng_init_wait);
    + kill_fasync(&fasync, SIGIO, POLL_IN);
    + pr_notice("crng init done\n");
    + if (unseeded_warning.missed) {
    + pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n",
    + unseeded_warning.missed);
    + unseeded_warning.missed = 0;
    + }
    + if (urandom_warning.missed) {
    + pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
    + urandom_warning.missed);
    + urandom_warning.missed = 0;
    + }
    + } else if (orig < POOL_EARLY_BITS && new >= POOL_EARLY_BITS) {
    spin_lock_irqsave(&base_crng.lock, flags);
    + /* Check if crng_init is CRNG_EMPTY, to avoid race with crng_reseed(). */
    if (crng_init == CRNG_EMPTY) {
    extract_entropy(base_crng.key, sizeof(base_crng.key));
    crng_init = CRNG_EARLY;

    \
     
     \ /
      Last update: 2022-05-27 13:57    [W:4.060 / U:0.484 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site