On Thu, Sep 12, 2019 at 04:25:30AM -0400, Theodore Y. Ts'o wrote: > On Thu, Sep 12, 2019 at 05:44:21AM +0200, Ahmed S. Darwish wrote: [...] > > > 1. Cutting down the number of bits needed to initialize the CRNG > > to 256 bits (CHACHA20 cipher) > > Does the attach patch (see below) help? > [...] > > diff --git a/drivers/char/random.c b/drivers/char/random.c > index 5d5ea4ce1442..b9b3a5a82abf 100644 > --- a/drivers/char/random.c > +++ b/drivers/char/random.c > @@ -500,7 +500,7 @@ static int crng_init = 0; > #define crng_ready() (likely(crng_init > 1)) > static int crng_init_cnt = 0; > static unsigned long crng_global_init_time = 0; > -#define CRNG_INIT_CNT_THRESH (2*CHACHA_KEY_SIZE) > +#define CRNG_INIT_CNT_THRESH CHACHA_KEY_SIZE > static void _extract_crng(struct crng_state *crng, __u8 out[CHACHA_BLOCK_SIZE]); > static void _crng_backtrack_protect(struct crng_state *crng, > __u8 tmp[CHACHA_BLOCK_SIZE], int used); Unfortunately, it only made the early fast init faster, but didn't fix the normal crng init blockage :-( Here's a trace log, got by applying the patch at [1]. The boot was continued only after typing some random keys after ~30s: # # entries-in-buffer/entries-written: 22/22 #P:8 # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | <idle>-0 [001] dNh. 0.687088: crng_fast_load: crng threshold = 32 <idle>-0 [001] dNh. 0.687089: crng_fast_load: crng_init_cnt = 0 <idle>-0 [001] dNh. 0.687090: crng_fast_load: crng_init_cnt, now set to 16 <idle>-0 [001] dNh. 0.705208: crng_fast_load: crng threshold = 32 <idle>-0 [001] dNh. 0.705209: crng_fast_load: crng_init_cnt = 16 <idle>-0 [001] dNh. 0.705209: crng_fast_load: crng_init_cnt, now set to 32 <idle>-0 [001] dNh. 0.708048: crng_fast_load: random: fast init done lvm-165 [001] d... 2.417971: urandom_read: random: crng_init_cnt, now set to 0 systemd-random--179 [003] .... 2.495669: wait_for_random_bytes.part.0: wait for randomness dbus-daemon-274 [006] dN.. 3.294331: urandom_read: random: crng_init_cnt, now set to 0 dbus-daemon-274 [006] dN.. 3.316618: urandom_read: random: crng_init_cnt, now set to 0 polkitd-286 [007] dN.. 3.873918: urandom_read: random: crng_init_cnt, now set to 0 polkitd-286 [007] dN.. 3.874303: urandom_read: random: crng_init_cnt, now set to 0 polkitd-286 [007] dN.. 3.874375: urandom_read: random: crng_init_cnt, now set to 0 polkitd-286 [007] d... 3.886204: urandom_read: random: crng_init_cnt, now set to 0 polkitd-286 [007] d... 3.886217: urandom_read: random: crng_init_cnt, now set to 0 polkitd-286 [007] d... 3.888519: urandom_read: random: crng_init_cnt, now set to 0 polkitd-286 [007] d... 3.888529: urandom_read: random: crng_init_cnt, now set to 0 gnome-session-b-321 [006] .... 4.292034: wait_for_random_bytes.part.0: wait for randomness <idle>-0 [002] dNh. 36.784001: crng_reseed: random: crng init done gnome-session-b-321 [006] .... 36.784019: wait_for_random_bytes.part.0: wait done systemd-random--179 [003] .... 36.784051: wait_for_random_bytes.part.0: wait done [1] patch: diff --git a/drivers/char/random.c b/drivers/char/random.c index 5d5ea4ce1442..4a50ee2c230d 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -500,7 +500,7 @@ static int crng_init = 0; #define crng_ready() (likely(crng_init > 1)) static int crng_init_cnt = 0; static unsigned long crng_global_init_time = 0; -#define CRNG_INIT_CNT_THRESH (2*CHACHA_KEY_SIZE) +#define CRNG_INIT_CNT_THRESH (CHACHA_KEY_SIZE) static void _extract_crng(struct crng_state *crng, __u8 out[CHACHA_BLOCK_SIZE]); static void _crng_backtrack_protect(struct crng_state *crng, __u8 tmp[CHACHA_BLOCK_SIZE], int used); @@ -931,6 +931,9 @@ static int crng_fast_load(const char *cp, size_t len) unsigned long flags; char *p; + trace_printk("crng threshold = %d\n", CRNG_INIT_CNT_THRESH); + trace_printk("crng_init_cnt = %d\n", crng_init_cnt); + if (!spin_trylock_irqsave(&primary_crng.lock, flags)) return 0; if (crng_init != 0) { @@ -943,11 +946,15 @@ static int crng_fast_load(const char *cp, size_t len) cp++; crng_init_cnt++; len--; } spin_unlock_irqrestore(&primary_crng.lock, flags); + + trace_printk("crng_init_cnt, now set to %d\n", crng_init_cnt); + if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { invalidate_batched_entropy(); crng_init = 1; wake_up_interruptible(&crng_init_wait); pr_notice("random: fast init done\n"); + trace_printk("random: fast init done\n"); } return 1; } @@ -1033,6 +1040,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) process_random_ready_list(); wake_up_interruptible(&crng_init_wait); pr_notice("random: crng init done\n"); + trace_printk("random: crng init done\n"); if (unseeded_warning.missed) { pr_notice("random: %d get_random_xx warning(s) missed " "due to ratelimiting\n", @@ -1743,9 +1751,16 @@ EXPORT_SYMBOL(get_random_bytes); */ int wait_for_random_bytes(void) { + int ret; + if (likely(crng_ready())) return 0; - return wait_event_interruptible(crng_init_wait, crng_ready()); + + trace_printk("wait for randomness\n"); + ret = wait_event_interruptible(crng_init_wait, crng_ready()); + trace_printk("wait done\n"); + + return ret; } EXPORT_SYMBOL(wait_for_random_bytes); @@ -1974,6 +1989,8 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) current->comm, nbytes); spin_lock_irqsave(&primary_crng.lock, flags); crng_init_cnt = 0; + trace_printk("random: crng_init_cnt, now set to %d\n", + crng_init_cnt); spin_unlock_irqrestore(&primary_crng.lock, flags); } nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3)); thanks, -- darwi http://darwish.chasingpointers.com