random: use lockless method of accessing and updating f->reg_idx

Linus pointed out that there is a much more efficient way of avoiding
the problem that we were trying to address in commit 9dfa7bba35ac0:
"fix race in drivers/char/random.c:get_reg()".

Signed-off-by: Theodore Ts'o <tytso@mit.edu>

Changed files
+6 -6
drivers
char
+6 -6
drivers/char/random.c
··· 1097 1097 static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs) 1098 1098 { 1099 1099 __u32 *ptr = (__u32 *) regs; 1100 - unsigned long flags; 1100 + unsigned int idx; 1101 1101 1102 1102 if (regs == NULL) 1103 1103 return 0; 1104 - local_irq_save(flags); 1105 - if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32)) 1106 - f->reg_idx = 0; 1107 - ptr += f->reg_idx++; 1108 - local_irq_restore(flags); 1104 + idx = READ_ONCE(f->reg_idx); 1105 + if (idx >= sizeof(struct pt_regs) / sizeof(__u32)) 1106 + idx = 0; 1107 + ptr += idx++; 1108 + WRITE_ONCE(f->reg_idx, idx); 1109 1109 return *ptr; 1110 1110 } 1111 1111