From nobody Wed Apr 15 00:02:07 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 77CA2C00144 for ; Fri, 29 Jul 2022 15:47:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237976AbiG2Pr2 (ORCPT ); Fri, 29 Jul 2022 11:47:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236558AbiG2PrX (ORCPT ); Fri, 29 Jul 2022 11:47:23 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92A3E5A146 for ; Fri, 29 Jul 2022 08:47:22 -0700 (PDT) From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1659109640; 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=d9PVUuAB1SdBd5kJRCLOfGBGYgfkz4K2McYyw0hE8Ng=; b=hGgmsAvci7ydwRIonahSBPWE8XbLf7eUGRnE6Gdqr6HpgM83uw+B3Cb1aST2DK1/j+dF5B zpGSDeGA3NtI8Uo+sYjeT9xfYDs4fUx5w4DN0SLQbca1i/RTHau7dt5SC6BHCKhQGwrjrj Bq6HdaCdTmfRj7CxNYwkrCIsK6LUUI0WudJe5L57azn9keeDpGc1iMguGZRyMSjoV0r7l5 gAUNwj5VYHYS3WDrIZGZ8dvNc/uuRGWdFPql/MMD12c9kqppAoNKHA3c55dczPTvQXTc7e UMw2al4N5+X4YKEQs8Tv+ZpSAZvxSRBKw5ZOT4NCt5DQzmHrCUZtY4HM70/xRQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1659109640; 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=d9PVUuAB1SdBd5kJRCLOfGBGYgfkz4K2McYyw0hE8Ng=; b=pTlfQjgC6wG/AndfPO6eEWh8uSn3AB4QsE+Ux5u2WqsP/n1CWTOQAjvug2ML440Qm3izhk O2DlGWhpAPFfENDw== To: linux-kernel@vger.kernel.org Cc: Andy Shevchenko , "Jason A . Donenfeld" , John Ogness , Mike Galbraith , Petr Mladek , Rasmus Villemoes , Sergey Senozhatsky , Steven Rostedt , Theodore Ts'o , Thomas Gleixner , Sebastian Andrzej Siewior Subject: [PATCH 1/2 v2] lib/vsprintf: Remove static_branch_likely() from __ptr_to_hashval(). Date: Fri, 29 Jul 2022 17:47:15 +0200 Message-Id: <20220729154716.429964-2-bigeasy@linutronix.de> In-Reply-To: <20220729154716.429964-1-bigeasy@linutronix.de> References: <20220729154716.429964-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 --- lib/vsprintf.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -750,12 +750,7 @@ static int __init debug_boot_weak_hash_e } 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; =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 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); From nobody Wed Apr 15 00:02:07 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 6FE6BC00144 for ; Fri, 29 Jul 2022 15:47:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237930AbiG2PrZ (ORCPT ); Fri, 29 Jul 2022 11:47:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237496AbiG2PrX (ORCPT ); Fri, 29 Jul 2022 11:47:23 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92D625A178 for ; Fri, 29 Jul 2022 08:47:22 -0700 (PDT) From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1659109640; 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=bv4+WczCS/N+pAcLquU4cectt+GICbjZxHfYjibJb04=; b=LaJXY0Nnai6PSvLVZBnHdhsxnzrc3bBwsl7L7+kGe/NJeGy4MDDRaTRP6ogdEUopFsN/xi W0gAH9Mge0EU1jXmaALQvKWRleyWaoZSFQGVYwgfC5/MCLAS+RAkLyYZ/Bs0ghan3anh67 cTnNdFhZWzLobGQ4o7/tA+o56wrF8xQOoYFm1HWC11G10PfGfzVE5DEO2bosy084qoh6Nh fKrfV2casrpmQ2VJHrChZCyrZnnWzwhbLFw1IJquLw/uhhI4cDM2a89zhCzG3UY40O4yiT 7dVc98AreG/RfSjEpKPi9XpHKdgh+8qpBCb4VPGLRS6MAYWxZ0jKbJxpnEhzDQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1659109640; 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=bv4+WczCS/N+pAcLquU4cectt+GICbjZxHfYjibJb04=; b=hyC5Z7clAWI3QXTeOt0FKj7ffrh+5nnJgemaRp/Xts4zDJwY2has+kxioRuzJOv3iWKdc0 Pe1eaRn2ZnnGR6CA== To: linux-kernel@vger.kernel.org Cc: Andy Shevchenko , "Jason A . Donenfeld" , John Ogness , Mike Galbraith , Petr Mladek , Rasmus Villemoes , Sergey Senozhatsky , Steven Rostedt , Theodore Ts'o , Thomas Gleixner , Sebastian Andrzej Siewior Subject: [PATCH 2/2 v2] lib/vsprintf: Initialize vsprintf's pointer hash once the random core is ready. Date: Fri, 29 Jul 2022 17:47:16 +0200 Message-Id: <20220729154716.429964-3-bigeasy@linutronix.de> In-Reply-To: <20220729154716.429964-1-bigeasy@linutronix.de> References: <20220729154716.429964-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 initializaion 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_wait() to retrieve the random value which will block until random data is available. Reported-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior --- lib/vsprintf.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -751,31 +751,37 @@ static int __init debug_boot_weak_hash_e early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable); =20 static bool filled_random_ptr_key; +static siphash_key_t ptr_key __read_mostly; + +static void fill_ptr_key_workfn(struct work_struct *work) +{ + int ret; + + ret =3D get_random_bytes_wait(&ptr_key, sizeof(ptr_key)); + if (WARN_ON(ret < 0)) + return; + /* Pairs with smp_rmb() before reading ptr_key. */ + smp_wmb(); + WRITE_ONCE(filled_random_ptr_key, true); +} + +static int vsprintf_init_hashval(void) +{ + static DECLARE_WORK(fill_ptr_key_work, fill_ptr_key_workfn); + + queue_work(system_unbound_wq, &fill_ptr_key_work); + 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 (!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); - } + if (!READ_ONCE(filled_random_ptr_key)) + return -EBUSY; + /* Pairs with smp_wmb() after writting ptr_key. */ smp_rmb(); =20