add_hwgenerator_randomness() currently blocks until more entropy is needed. But, the required delay function will depend on the the caller: e.g. freezable kthreads have their own freezable_XXX() APIs; and delayed_work might prefer to use mod_delayed_work(). To accommodate these requirements, remove the blocking wait, and let the function return the delay needed until more entropy is needed. Signed-off-by: Sven van Ashbrook <svenva@xxxxxxxxxxxx> --- drivers/char/hw_random/core.c | 7 +++++-- drivers/char/random.c | 13 ++++++------- include/linux/random.h | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 16f227b995e8..3675122c6cce 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -491,6 +491,7 @@ static int __init register_miscdev(void) static int hwrng_fillfn(void *unused) { size_t entropy, entropy_credit = 0; /* in 1/1024 of a bit */ + unsigned long delay; long rc; while (!kthread_should_stop()) { @@ -526,8 +527,10 @@ static int hwrng_fillfn(void *unused) entropy_credit = entropy; /* Outside lock, sure, but y'know: randomness. */ - add_hwgenerator_randomness((void *)rng_fillbuf, rc, - entropy >> 10); + delay = add_hwgenerator_randomness((void *)rng_fillbuf, rc, + entropy >> 10); + if (delay > 0) + schedule_timeout_interruptible(delay); } hwrng_fill = NULL; return 0; diff --git a/drivers/char/random.c b/drivers/char/random.c index 79d7d4e4e582..7b6c27065cf9 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -686,7 +686,7 @@ static void __cold _credit_init_bits(size_t bits) * the above entropy accumulation routines: * * void add_device_randomness(const void *buf, size_t len); - * void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy); + * unsigned long add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy); * void add_bootloader_randomness(const void *buf, size_t len); * void add_vmfork_randomness(const void *unique_vm_id, size_t len); * void add_interrupt_randomness(int irq); @@ -702,8 +702,8 @@ static void __cold _credit_init_bits(size_t bits) * available to them (particularly common in the embedded world). * * add_hwgenerator_randomness() is for true hardware RNGs, and will credit - * entropy as specified by the caller. If the entropy pool is full it will - * block until more entropy is needed. + * entropy as specified by the caller. Returns number time delay in jiffies + * until more entropy is needed. * * add_bootloader_randomness() is called by bootloader drivers, such as EFI * and device tree, and credits its input depending on whether or not the @@ -857,10 +857,10 @@ EXPORT_SYMBOL(add_device_randomness); /* * Interface for in-kernel drivers of true hardware RNGs. - * Those devices may produce endless random bits and will be throttled + * Those devices may produce endless random bits and should be throttled * when our pool is full. */ -void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy) +unsigned long add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy) { mix_pool_bytes(buf, len); credit_init_bits(entropy); @@ -869,8 +869,7 @@ void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy) * Throttle writing to once every CRNG_RESEED_INTERVAL, unless * we're not yet initialized. */ - if (!kthread_should_stop() && crng_ready()) - schedule_timeout_interruptible(CRNG_RESEED_INTERVAL); + return crng_ready() ? CRNG_RESEED_INTERVAL : 0; } EXPORT_SYMBOL_GPL(add_hwgenerator_randomness); diff --git a/include/linux/random.h b/include/linux/random.h index 3fec206487f6..6608b0fb4402 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -17,7 +17,7 @@ void __init add_bootloader_randomness(const void *buf, size_t len); void add_input_randomness(unsigned int type, unsigned int code, unsigned int value) __latent_entropy; void add_interrupt_randomness(int irq) __latent_entropy; -void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy); +unsigned long add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy); #if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__) static inline void add_latent_entropy(void) -- 2.37.2.672.g94769d06f0-goog