From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D5F841A264; Sat, 28 Feb 2026 17:45:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772300736; cv=none; b=XQW+Q3d5f+f3/4ckn0bS0u3V5aUIhZOCG63rHtn06IqNR5ymtWLOmAC9EFrDQkFlW/Wqk+lB+qTR2NZW73VsLQ7fx5lQRJEabVhbpCMqhQpyjts94/N7OT0EFo8mNNRkQMjjjc9grugv6d/jxke70wP23FAGSfMjqzQBHGvHnIs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772300736; c=relaxed/simple; bh=h9Z/KId332mUdy5fm53XOU9xtmdVeVuae9Ii70xwFTQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K8+L9fdIhO14BNfIs0bi0zvQOCmvxXJN8vWZOOFbspG8JpSX3lRi/b27n/w88zmO9S5oN3ykCbz7T4vNwdOsHt+JaYNDzXrMOyATyLxsW2Ym8dM7EopCEVSzIppC2HJPfibyCaNQct2gUp6oHYvok+MVfdZmPL5OObCIlKtW04c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FNnVAvwC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FNnVAvwC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 805CFC19423; Sat, 28 Feb 2026 17:45:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772300736; bh=h9Z/KId332mUdy5fm53XOU9xtmdVeVuae9Ii70xwFTQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FNnVAvwCtf6VV0MedJFfUbSrS4k2JoxoqneC/FrSvBbXGlpWTw6dkEzyy3SjhmAOS ZtaFpkqfzHrOZSEw8linucgDz/BRQ5VfB+Fe7Kd3r98IoaIVvo85VEF/iK6D4WvdE2 Ciw9ejmL5ii5llRDCCHKJdCX1RUHiLYxF3IOWOMlOsdTNaaR7UsWa7bxs2zaYRZ4zx e/Z9qdQLwgEZNCtiab7j7NCwGytm4zXaOZp7OaBavq8xc4YDpdgQGxgscTn/703spc sFlrXXkSwogj6ToWz3bQZMMIDjQaNpModphu2m5CQXkjOwFMefPbrojNvS1ESqgT3H NCQCkWctD97dg== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Harry Yoo , Vlastimil Babka , Sasha Levin Subject: [PATCH 6.19 770/844] mm/slab: use prandom if !allow_spin Date: Sat, 28 Feb 2026 12:31:23 -0500 Message-ID: <20260228173244.1509663-771-sashal@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260228173244.1509663-1-sashal@kernel.org> References: <20260228173244.1509663-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit From: Harry Yoo [ Upstream commit a1e244a9f177894969c6cd5ebbc6d72c19fc4a7a ] When CONFIG_SLAB_FREELIST_RANDOM is enabled and get_random_u32() is called in an NMI context, lockdep complains because it acquires a local_lock: ================================ WARNING: inconsistent lock state 6.19.0-rc5-slab-for-next+ #325 Tainted: G N -------------------------------- inconsistent {INITIAL USE} -> {IN-NMI} usage. kunit_try_catch/8312 [HC2[2]:SC0[0]:HE0:SE1] takes: ffff88a02ec49cc0 (batched_entropy_u32.lock){-.-.}-{3:3}, at: get_random_u32+0x7f/0x2e0 {INITIAL USE} state was registered at: lock_acquire+0xd9/0x2f0 get_random_u32+0x93/0x2e0 __get_random_u32_below+0x17/0x70 cache_random_seq_create+0x121/0x1c0 init_cache_random_seq+0x5d/0x110 do_kmem_cache_create+0x1e0/0xa30 __kmem_cache_create_args+0x4ec/0x830 create_kmalloc_caches+0xe6/0x130 kmem_cache_init+0x1b1/0x660 mm_core_init+0x1d8/0x4b0 start_kernel+0x620/0xcd0 x86_64_start_reservations+0x18/0x30 x86_64_start_kernel+0xf3/0x140 common_startup_64+0x13e/0x148 irq event stamp: 76 hardirqs last enabled at (75): [] exc_nmi+0x11a/0x240 hardirqs last disabled at (76): [] sysvec_irq_work+0x11/0x110 softirqs last enabled at (0): [] copy_process+0xc7a/0x2350 softirqs last disabled at (0): [<0000000000000000>] 0x0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(batched_entropy_u32.lock); lock(batched_entropy_u32.lock); *** DEADLOCK *** Fix this by using pseudo-random number generator if !allow_spin. This means kmalloc_nolock() users won't get truly random numbers, but there is not much we can do about it. Note that an NMI handler might interrupt prandom_u32_state() and change the random state, but that's safe. Link: https://lore.kernel.org/all/0c33bdee-6de8-4d9f-92ca-4f72c1b6fb9f@suse.cz Fixes: af92793e52c3 ("slab: Introduce kmalloc_nolock() and kfree_nolock().") Cc: stable@vger.kernel.org Signed-off-by: Harry Yoo Link: https://patch.msgid.link/20260210081900.329447-3-harry.yoo@oracle.com Signed-off-by: Vlastimil Babka Signed-off-by: Sasha Levin --- mm/slub.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 6304a2b7b8318..889c2804bbfeb 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -3196,8 +3197,11 @@ static void *next_freelist_entry(struct kmem_cache *s, return (char *)start + idx; } +static DEFINE_PER_CPU(struct rnd_state, slab_rnd_state); + /* Shuffle the single linked freelist based on a random pre-computed sequence */ -static bool shuffle_freelist(struct kmem_cache *s, struct slab *slab) +static bool shuffle_freelist(struct kmem_cache *s, struct slab *slab, + bool allow_spin) { void *start; void *cur; @@ -3208,7 +3212,19 @@ static bool shuffle_freelist(struct kmem_cache *s, struct slab *slab) return false; freelist_count = oo_objects(s->oo); - pos = get_random_u32_below(freelist_count); + if (allow_spin) { + pos = get_random_u32_below(freelist_count); + } else { + struct rnd_state *state; + + /* + * An interrupt or NMI handler might interrupt and change + * the state in the middle, but that's safe. + */ + state = &get_cpu_var(slab_rnd_state); + pos = prandom_u32_state(state) % freelist_count; + put_cpu_var(slab_rnd_state); + } page_limit = slab->objects * s->size; start = fixup_red_left(s, slab_address(slab)); @@ -3235,7 +3251,8 @@ static inline int init_cache_random_seq(struct kmem_cache *s) return 0; } static inline void init_freelist_randomization(void) { } -static inline bool shuffle_freelist(struct kmem_cache *s, struct slab *slab) +static inline bool shuffle_freelist(struct kmem_cache *s, struct slab *slab, + bool allow_spin) { return false; } @@ -3320,7 +3337,7 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) setup_slab_debug(s, slab, start); - shuffle = shuffle_freelist(s, slab); + shuffle = shuffle_freelist(s, slab, allow_spin); if (!shuffle) { start = fixup_red_left(s, start); @@ -8627,6 +8644,9 @@ void __init kmem_cache_init_late(void) { flushwq = alloc_workqueue("slub_flushwq", WQ_MEM_RECLAIM, 0); WARN_ON(!flushwq); +#ifdef CONFIG_SLAB_FREELIST_RANDOM + prandom_init_once(&slab_rnd_state); +#endif } struct kmem_cache * -- 2.51.0