@@ -750,37 +750,42 @@ static int __init debug_boot_weak_hash_enable(char *str)
750750}
751751early_param ("debug_boot_weak_hash" , debug_boot_weak_hash_enable );
752752
753- static DEFINE_STATIC_KEY_FALSE (filled_random_ptr_key );
753+ static bool filled_random_ptr_key __read_mostly ;
754+ static siphash_key_t ptr_key __read_mostly ;
755+ static void fill_ptr_key_workfn (struct work_struct * work );
756+ static DECLARE_DELAYED_WORK (fill_ptr_key_work , fill_ptr_key_workfn );
754757
755- static void enable_ptr_key_workfn (struct work_struct * work )
758+ static void fill_ptr_key_workfn (struct work_struct * work )
756759{
757- static_branch_enable (& filled_random_ptr_key );
760+ if (!rng_is_initialized ()) {
761+ queue_delayed_work (system_unbound_wq , & fill_ptr_key_work , HZ * 2 );
762+ return ;
763+ }
764+
765+ get_random_bytes (& ptr_key , sizeof (ptr_key ));
766+
767+ /* Pairs with smp_rmb() before reading ptr_key. */
768+ smp_wmb ();
769+ WRITE_ONCE (filled_random_ptr_key , true);
770+ }
771+
772+ static int __init vsprintf_init_hashval (void )
773+ {
774+ fill_ptr_key_workfn (NULL );
775+ return 0 ;
758776}
777+ subsys_initcall (vsprintf_init_hashval )
759778
760779/* Maps a pointer to a 32 bit unique identifier. */
761780static inline int __ptr_to_hashval (const void * ptr , unsigned long * hashval_out )
762781{
763- static siphash_key_t ptr_key __read_mostly ;
764782 unsigned long hashval ;
765783
766- if (!static_branch_likely (& filled_random_ptr_key )) {
767- static bool filled = false;
768- static DEFINE_SPINLOCK (filling );
769- static DECLARE_WORK (enable_ptr_key_work , enable_ptr_key_workfn );
770- unsigned long flags ;
771-
772- if (!system_unbound_wq || !rng_is_initialized () ||
773- !spin_trylock_irqsave (& filling , flags ))
774- return - EAGAIN ;
775-
776- if (!filled ) {
777- get_random_bytes (& ptr_key , sizeof (ptr_key ));
778- queue_work (system_unbound_wq , & enable_ptr_key_work );
779- filled = true;
780- }
781- spin_unlock_irqrestore (& filling , flags );
782- }
784+ if (!READ_ONCE (filled_random_ptr_key ))
785+ return - EBUSY ;
783786
787+ /* Pairs with smp_wmb() after writing ptr_key. */
788+ smp_rmb ();
784789
785790#ifdef CONFIG_64BIT
786791 hashval = (unsigned long )siphash_1u64 ((u64 )ptr , & ptr_key );
0 commit comments