mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-03 00:54:09 +08:00
hwrng: bcm2835 - Fix hwrng throughput regression
[ Upstream commitb58a36008b
] The last RCU stall fix caused a massive throughput regression of the hwrng on Raspberry Pi 0 - 3. hwrng_msleep doesn't sleep precisely enough and usleep_range doesn't allow scheduling. So try to restore the best possible throughput by introducing hwrng_yield which interruptable sleeps for one jiffy. Some performance measurements on Raspberry Pi 3B+ (arm64/defconfig): sudo dd if=/dev/hwrng of=/dev/null count=1 bs=10000 cpu_relax ~138025 Bytes / sec hwrng_msleep(1000) ~13 Bytes / sec hwrng_yield ~2510 Bytes / sec Fixes:96cb9d0554
("hwrng: bcm2835 - use hwrng_msleep() instead of cpu_relax()") Link: https://lore.kernel.org/linux-arm-kernel/bc97ece5-44a3-4c4e-77da-2db3eb66b128@gmx.net/ Signed-off-by: Stefan Wahren <wahrenst@gmx.net> Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
00dcb2738b
commit
d0f3994c6a
@ -70,7 +70,7 @@ static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max,
|
||||
while ((rng_readl(priv, RNG_STATUS) >> 24) == 0) {
|
||||
if (!wait)
|
||||
return 0;
|
||||
hwrng_msleep(rng, 1000);
|
||||
hwrng_yield(rng);
|
||||
}
|
||||
|
||||
num_words = rng_readl(priv, RNG_STATUS) >> 24;
|
||||
|
@ -678,6 +678,12 @@ long hwrng_msleep(struct hwrng *rng, unsigned int msecs)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hwrng_msleep);
|
||||
|
||||
long hwrng_yield(struct hwrng *rng)
|
||||
{
|
||||
return wait_for_completion_interruptible_timeout(&rng->dying, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hwrng_yield);
|
||||
|
||||
static int __init hwrng_modinit(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -63,5 +63,6 @@ extern void hwrng_unregister(struct hwrng *rng);
|
||||
extern void devm_hwrng_unregister(struct device *dve, struct hwrng *rng);
|
||||
|
||||
extern long hwrng_msleep(struct hwrng *rng, unsigned int msecs);
|
||||
extern long hwrng_yield(struct hwrng *rng);
|
||||
|
||||
#endif /* LINUX_HWRANDOM_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user