Message ID | 20191106093019.117233-1-alexander.sverdlin@nokia.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Herbert Xu |
Headers | show |
Series | hwrng: ks-sa: Add minimum sleep time before ready-polling | expand |
On Wed, Nov 06, 2019 at 09:30:49AM +0000, Sverdlin, Alexander (Nokia - DE/Ulm) wrote: > From: Alexander Sverdlin <alexander.sverdlin@nokia.com> > > Current polling timeout is 25 us. The hardware is currently configured to > harvest the entropy for 81920 us. This leads to timeouts even during > blocking read (wait=1). > > Log snippet: > [ 5.727589] [<c040ffcc>] (ks_sa_rng_probe) from [<c04181e8>] (platform_drv_probe+0x58/0xb4) > ... > [ 5.727805] hwrng: no data available > ... > [ 13.157016] random: systemd: uninitialized urandom read (16 bytes read) > [ 13.157033] systemd[1]: Initializing machine ID from random generator. > ... > [ 15.848770] random: fast init done > ... > [ 15.848807] random: crng init done > > After the patch: > [ 6.223534] random: systemd: uninitialized urandom read (16 bytes read) > [ 6.223551] systemd[1]: Initializing machine ID from random generator. > ... > [ 6.876075] random: fast init done > ... > [ 6.954200] random: systemd: uninitialized urandom read (16 bytes read) > [ 6.955244] random: systemd: uninitialized urandom read (16 bytes read) > ... > [ 7.121948] random: crng init done > > Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com> > --- > drivers/char/hw_random/ks-sa-rng.c | 38 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 38 insertions(+) Patch applied. Thanks.
On Fri, Nov 15, 2019 at 02:06:10PM +0800, Herbert Xu wrote: > On Wed, Nov 06, 2019 at 09:30:49AM +0000, Sverdlin, Alexander (Nokia - DE/Ulm) wrote: > > From: Alexander Sverdlin <alexander.sverdlin@nokia.com> > > > > Current polling timeout is 25 us. The hardware is currently configured to > > harvest the entropy for 81920 us. This leads to timeouts even during > > blocking read (wait=1). > > > > Log snippet: > > [ 5.727589] [<c040ffcc>] (ks_sa_rng_probe) from [<c04181e8>] (platform_drv_probe+0x58/0xb4) > > ... > > [ 5.727805] hwrng: no data available > > ... > > [ 13.157016] random: systemd: uninitialized urandom read (16 bytes read) > > [ 13.157033] systemd[1]: Initializing machine ID from random generator. > > ... > > [ 15.848770] random: fast init done > > ... > > [ 15.848807] random: crng init done > > > > After the patch: > > [ 6.223534] random: systemd: uninitialized urandom read (16 bytes read) > > [ 6.223551] systemd[1]: Initializing machine ID from random generator. > > ... > > [ 6.876075] random: fast init done > > ... > > [ 6.954200] random: systemd: uninitialized urandom read (16 bytes read) > > [ 6.955244] random: systemd: uninitialized urandom read (16 bytes read) > > ... > > [ 7.121948] random: crng init done > > > > Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com> > > --- > > drivers/char/hw_random/ks-sa-rng.c | 38 ++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 38 insertions(+) > > Patch applied. Thanks. This is causing a build error. Seems that a line of the patch in ks_sa_rng_init() went missing when it was applied...? drivers/char/hw_random/ks-sa-rng.c: In function 'ks_sa_rng_init': drivers/char/hw_random/ks-sa-rng.c:146:47: error: 'clk_rate' undeclared (first use in this function) 146 | ks_sa_rng->refill_delay_ns = refill_delay_ns(clk_rate); | ^~~~~~~~ drivers/char/hw_random/ks-sa-rng.c:146:47: note: each undeclared identifier is reported only once for each function it appears in
On Fri, Nov 15, 2019 at 11:32:29PM -0800, Eric Biggers wrote: > > This is causing a build error. Seems that a line of the patch in > ks_sa_rng_init() went missing when it was applied...? > > drivers/char/hw_random/ks-sa-rng.c: In function 'ks_sa_rng_init': > drivers/char/hw_random/ks-sa-rng.c:146:47: error: 'clk_rate' undeclared (first use in this function) > 146 | ks_sa_rng->refill_delay_ns = refill_delay_ns(clk_rate); > | ^~~~~~~~ > drivers/char/hw_random/ks-sa-rng.c:146:47: note: each undeclared identifier is reported only once for each function it appears in Sorry, I missed that line when applying this patch byhand as it conflicted with another change. It should be fixed now. I'll also enable COMPILE_TEST on this driver. Thanks,
diff --git a/drivers/char/hw_random/ks-sa-rng.c b/drivers/char/hw_random/ks-sa-rng.c index a674300..4b223cb 100644 --- a/drivers/char/hw_random/ks-sa-rng.c +++ b/drivers/char/hw_random/ks-sa-rng.c @@ -21,6 +21,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/delay.h> +#include <linux/timekeeping.h> #define SA_CMD_STATUS_OFS 0x8 @@ -85,13 +86,36 @@ struct ks_sa_rng { struct clk *clk; struct regmap *regmap_cfg; struct trng_regs *reg_rng; + u64 ready_ts; + unsigned int refill_delay_ns; }; +static unsigned int cycles_to_ns(unsigned long clk_rate, unsigned int cycles) +{ + return DIV_ROUND_UP_ULL((TRNG_DEF_CLK_DIV_CYCLES + 1) * 1000000000ull * + cycles, clk_rate); +} + +static unsigned int startup_delay_ns(unsigned long clk_rate) +{ + if (!TRNG_DEF_STARTUP_CYCLES) + return cycles_to_ns(clk_rate, BIT(24)); + return cycles_to_ns(clk_rate, 256 * TRNG_DEF_STARTUP_CYCLES); +} + +static unsigned int refill_delay_ns(unsigned long clk_rate) +{ + if (!TRNG_DEF_MAX_REFILL_CYCLES) + return cycles_to_ns(clk_rate, BIT(24)); + return cycles_to_ns(clk_rate, 256 * TRNG_DEF_MAX_REFILL_CYCLES); +} + static int ks_sa_rng_init(struct hwrng *rng) { u32 value; struct device *dev = (struct device *)rng->priv; struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev); + unsigned long clk_rate = clk_get_rate(ks_sa_rng->clk); /* Enable RNG module */ regmap_write_bits(ks_sa_rng->regmap_cfg, SA_CMD_STATUS_OFS, @@ -120,6 +144,10 @@ static int ks_sa_rng_init(struct hwrng *rng) value |= TRNG_CNTL_REG_TRNG_ENABLE; writel(value, &ks_sa_rng->reg_rng->control); + ks_sa_rng->refill_delay_ns = refill_delay_ns(clk_rate); + ks_sa_rng->ready_ts = ktime_get_ns() + + startup_delay_ns(clk_rate); + return 0; } @@ -144,6 +172,7 @@ static int ks_sa_rng_data_read(struct hwrng *rng, u32 *data) data[1] = readl(&ks_sa_rng->reg_rng->output_h); writel(TRNG_INTACK_REG_READY, &ks_sa_rng->reg_rng->intack); + ks_sa_rng->ready_ts = ktime_get_ns() + ks_sa_rng->refill_delay_ns; return sizeof(u32) * 2; } @@ -152,10 +181,19 @@ static int ks_sa_rng_data_present(struct hwrng *rng, int wait) { struct device *dev = (struct device *)rng->priv; struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev); + u64 now = ktime_get_ns(); u32 ready; int j; + if (wait && now < ks_sa_rng->ready_ts) { + /* Max delay expected here is 81920000 ns */ + unsigned long min_delay = + DIV_ROUND_UP((u32)(ks_sa_rng->ready_ts - now), 1000); + + usleep_range(min_delay, min_delay + SA_RNG_DATA_RETRY_DELAY); + } + for (j = 0; j < SA_MAX_RNG_DATA_RETRIES; j++) { ready = readl(&ks_sa_rng->reg_rng->status); ready &= TRNG_STATUS_REG_READY;