From nobody Wed Apr 15 00:02:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61B7FC6FA90 for ; Tue, 27 Sep 2022 10:49:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231377AbiI0Kt3 (ORCPT ); Tue, 27 Sep 2022 06:49:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229942AbiI0KtZ (ORCPT ); Tue, 27 Sep 2022 06:49:25 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 492ED115A67 for ; Tue, 27 Sep 2022 03:49:23 -0700 (PDT) From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1664275761; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tjHYpXrjzW1rmVIilucq4/ssa0Amaz+1GwZoY2Y89Iw=; b=zFTpq95r4D5NqlkmuN9pEhscWPE7cPO2fN5uED3CsSQbzHXGGmqMcOhy/J3PXruBdiULco oSktp/Mh8ZspyuF6Sri7gdxareiwoFR64PsBO5/vKh42DOVNCgx2D4y7BpogBlShXGBVcF 2NQ/gw4CWGF8ojCSjcKW7wCxTpiy4sM+wXCWtiotwkKWEkm5HEoNmRFItcZSvwpKEPP/ps 4vnoaxltzTxIY2g4Ga3WF1aDv6LHzG9BcUFlFdwLaDjGnAsbabyeCtZFTunC6ZGFRYp+/v P32+lNzyuZbql5az2tViepYqZJjWDfT7h5fupUNmmxxesrewrXtANoL9cpYT1w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1664275761; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tjHYpXrjzW1rmVIilucq4/ssa0Amaz+1GwZoY2Y89Iw=; b=pPVlaCGpLDTtzDN3jwnlsTTQGdk+Xt9bp0TLbyOwS/0tiKM7QWz6zPFoBeIzMoFuBQNswb 8Rm3QAAXtuZ64rDg== To: linux-kernel@vger.kernel.org Cc: Theodore Ts'o , Andy Shevchenko , "Jason A . Donenfeld " , John Ogness , Mike Galbraith , Peter Zijlstra , Petr Mladek , Rasmus Villemoes , Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , Sebastian Andrzej Siewior Subject: [PATCH v4 1/2] lib/vsprintf: Remove static_branch_likely() from __ptr_to_hashval(). Date: Tue, 27 Sep 2022 12:49:11 +0200 Message-Id: <20220927104912.622645-2-bigeasy@linutronix.de> In-Reply-To: <20220927104912.622645-1-bigeasy@linutronix.de> References: <20220927104912.622645-1-bigeasy@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Using static_branch_likely() to signal that ptr_key has been filled is a bit much given that it is not a fast path. Replace static_branch_likely() with bool for condition and a memory barrier for ptr_key. Suggested-by: Petr Mladek Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Petr Mladek Reviewed-by: Sergey Senozhatsky --- lib/vsprintf.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 3c1853a9d1c09..bce63cbf23779 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -750,12 +750,7 @@ static int __init debug_boot_weak_hash_enable(char *st= r) } early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable); =20 -static DEFINE_STATIC_KEY_FALSE(filled_random_ptr_key); - -static void enable_ptr_key_workfn(struct work_struct *work) -{ - static_branch_enable(&filled_random_ptr_key); -} +static bool filled_random_ptr_key __read_mostly; =20 /* Maps a pointer to a 32 bit unique identifier. */ static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval= _out) @@ -763,24 +758,26 @@ static inline int __ptr_to_hashval(const void *ptr, u= nsigned long *hashval_out) static siphash_key_t ptr_key __read_mostly; unsigned long hashval; =20 - if (!static_branch_likely(&filled_random_ptr_key)) { + if (!READ_ONCE(filled_random_ptr_key)) { static bool filled =3D false; static DEFINE_SPINLOCK(filling); - static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); unsigned long flags; =20 - if (!system_unbound_wq || !rng_is_initialized() || + if (!rng_is_initialized() || !spin_trylock_irqsave(&filling, flags)) return -EAGAIN; =20 if (!filled) { get_random_bytes(&ptr_key, sizeof(ptr_key)); - queue_work(system_unbound_wq, &enable_ptr_key_work); + /* Pairs with smp_rmb() before reading ptr_key. */ + smp_wmb(); + WRITE_ONCE(filled_random_ptr_key, true); filled =3D true; } spin_unlock_irqrestore(&filling, flags); } - + /* Pairs with smp_wmb() after writing ptr_key. */ + smp_rmb(); =20 #ifdef CONFIG_64BIT hashval =3D (unsigned long)siphash_1u64((u64)ptr, &ptr_key); --=20 2.37.2 From nobody Wed Apr 15 00:02:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FEEBC54EE9 for ; Tue, 27 Sep 2022 10:49:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231479AbiI0Kte (ORCPT ); Tue, 27 Sep 2022 06:49:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230131AbiI0KtZ (ORCPT ); Tue, 27 Sep 2022 06:49:25 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4920110AB36 for ; Tue, 27 Sep 2022 03:49:23 -0700 (PDT) From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1664275761; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O9SpVBT+ySsAWzeFgnz/SGjnqeQN8tYraD5LwJEmXBQ=; b=REqW9t/hsttkyPCWE93aLKiLfaaEU2n/FliWuUiXe88zwNNro6HXswbJuL5yIqk4Ywnk2/ KfJuMcR6PSMdYohU88OSK1wIJVoFZRQK6IDUVY/GqFfnwnYVV6aklCtHAtjUQQGpIPuMty D8sSy4zTfiu5WnfQu6rwN13cDKh49RBEEBpzmrBLXy2SeR4nQYTIFxHzothJoA13RntKYG Qpf/rlRcDMZFTzpQeyQok7B9c8aYT5J//F0jkXNAg8QXL/QI/4TWtovctR5BIuL/rbgrUq UOfo+udumfpRVPYWD7m0PQvku1GKI+vKnupwOmS24TUXnojvIhqpt01iVFX8mA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1664275761; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O9SpVBT+ySsAWzeFgnz/SGjnqeQN8tYraD5LwJEmXBQ=; b=aTqzidwARTeDTTG+/DGSJEkOzWBOFIwm78p1ehIVXT5/rmreI4ZGsVVYsXOKLoO9AGZZ7M 4SGLNENEeE80IcCw== To: linux-kernel@vger.kernel.org Cc: Theodore Ts'o , Andy Shevchenko , "Jason A . Donenfeld " , John Ogness , Mike Galbraith , Peter Zijlstra , Petr Mladek , Rasmus Villemoes , Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , Sebastian Andrzej Siewior Subject: [PATCH v4 2/2] lib/vsprintf: Initialize vsprintf's pointer hash once the random core is ready. Date: Tue, 27 Sep 2022 12:49:12 +0200 Message-Id: <20220927104912.622645-3-bigeasy@linutronix.de> In-Reply-To: <20220927104912.622645-1-bigeasy@linutronix.de> References: <20220927104912.622645-1-bigeasy@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The printk code invokes vnsprintf in order to compute the complete string before adding it into its buffer. This happens in an IRQ-off region which leads to a warning on PREEMPT_RT in the random code if the format strings contains a %p for pointer printing. This happens because the random core acquires locks which become sleeping locks on PREEMPT_RT which must not be acquired with disabled interrupts and or preemption disabled. By default the pointers are hashed which requires a random value on the first invocation (either by printk or another user which comes first. One could argue that there is no need for printk to disable interrupts during the vsprintf() invocation which would fix the just mentioned problem. However printk itself can be invoked in a context with disabled interrupts which would lead to the very same problem. Move the initialization of ptr_key into a worker and schedule it from subsys_initcall(). This happens early but after the workqueue subsystem is ready. Use get_random_bytes() to retrieve the random value if the RNG core is ready, otherwise schedule a worker in two seconds and try again. Reported-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior Acked-by: Jason A. Donenfeld Reviewed-by: Petr Mladek Reviewed-by: Sergey Senozhatsky --- lib/vsprintf.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index bce63cbf23779..44b39ba56b796 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -751,31 +751,39 @@ static int __init debug_boot_weak_hash_enable(char *s= tr) early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable); =20 static bool filled_random_ptr_key __read_mostly; +static siphash_key_t ptr_key __read_mostly; +static void fill_ptr_key_workfn(struct work_struct *work); +static DECLARE_DELAYED_WORK(fill_ptr_key_work, fill_ptr_key_workfn); + +static void fill_ptr_key_workfn(struct work_struct *work) +{ + if (!rng_is_initialized()) { + queue_delayed_work(system_unbound_wq, &fill_ptr_key_work, HZ * 2); + return; + } + + get_random_bytes(&ptr_key, sizeof(ptr_key)); + + /* Pairs with smp_rmb() before reading ptr_key. */ + smp_wmb(); + WRITE_ONCE(filled_random_ptr_key, true); +} + +static int __init vsprintf_init_hashval(void) +{ + fill_ptr_key_workfn(NULL); + return 0; +} +subsys_initcall(vsprintf_init_hashval) =20 /* Maps a pointer to a 32 bit unique identifier. */ static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval= _out) { - static siphash_key_t ptr_key __read_mostly; unsigned long hashval; =20 - if (!READ_ONCE(filled_random_ptr_key)) { - static bool filled =3D false; - static DEFINE_SPINLOCK(filling); - unsigned long flags; + if (!READ_ONCE(filled_random_ptr_key)) + return -EBUSY; =20 - if (!rng_is_initialized() || - !spin_trylock_irqsave(&filling, flags)) - return -EAGAIN; - - if (!filled) { - get_random_bytes(&ptr_key, sizeof(ptr_key)); - /* Pairs with smp_rmb() before reading ptr_key. */ - smp_wmb(); - WRITE_ONCE(filled_random_ptr_key, true); - filled =3D true; - } - spin_unlock_irqrestore(&filling, flags); - } /* Pairs with smp_wmb() after writing ptr_key. */ smp_rmb(); =20 --=20 2.37.2