From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 5F3EB2652AF for ; Mon, 13 Jul 2026 14:29:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783952945; cv=none; b=FhP1wOHKjCsCPYvQgdLscjVPE7TnP3NOkias5nojkTC+3FU2M+qr/iFFW0YiwkYZUCgLBFhWA/sgw94VbalFLr1vIW4fF0Jj4uDBhQbhbtqFW2CJmVljCb2wfvqkOm6q965GAoTdJi+9CC18f53u1QU2BikcgbuubCXRbA3uBIM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783952945; c=relaxed/simple; bh=eUB++SpfgqxHZYKvAiXsIxBwguAlrJYcKJCAHENepJ0=; h=From:Subject:Date:Message-Id:MIME-Version:Content-Type:To:Cc; b=LlVGJ/COe0izwx3kG2+TwZv70nRbY8t+8rZwJYeb922nA1ihlkLwgrMN+5FBqAN9AxGaNchfgL1BqEdwvbDGVtxTEWCBWyptvxUAMciQpm6TZv6FgdXGYPSCUfreTowDaSBhIvgZqvNgtUPmPejOcu5lVf/FaIT/x+5YtSmi2hI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JlvhXVf2; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JlvhXVf2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1FE911F000E9; Mon, 13 Jul 2026 14:29:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783952944; bh=2SO7+dHwB9ZC/vvSfz8DpHJtqvNEWkUaK12E32Z2y6Q=; h=From:Subject:Date:To:Cc; b=JlvhXVf2OEsY7SagkEv0DG2h2H0pnUmCMSETdH+1ksf45YbcdQxoKqwol/lTMA8ki 2IvFKBxvqJ3HfX2kPvPyuTkmpoQaT6vGDRTjNZW+sfChDjJo6AICNqtMVKNiioVnJL p9UmDoe/KqHX85KuzAT3RjHbfhhKi5eYpbbxh+XM9bRweqjHv6ub367O8QcrrSvNbk WYmxweJp35gjzfsN8+brWzK4LxtCIkop9hxfPrR/J4P2IWH2GfjJYNmGeQIKo71W/m 4IfZB5TzTSJVGiQp0AdISm8rsJv3CPW13AQxaIcrbzUlUMj11eQmKq/RcuRZMH8NHS 9yGiU1iHnTrVQ== From: "Harry Yoo (Oracle)" Subject: [PATCH slab/for-next-fixes v3 0/4] mm/slab: fix unbounded recursion in free path with memalloc profiling Date: Mon, 13 Jul 2026 23:28:48 +0900 Message-Id: <20260713-kmalloc-no-objext-v3-0-47c7bd138de7@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-B4-Tracking: v=1; b=H4sIAAAAAAAC/6XNQQ6CMBAF0KuQrq1OWyngynsYFwUHqNTWtIRgC He34sZE44bln/x5fyIBvcZADslEPA46aGdjEJuEVK2yDVJ9iZlw4BIy4LS7KWNcRa2jrrzi2FM uWVExBAm5IPHv7rHW42KeSDCq3NXOU/uqvu/nWGp16J1/LLsDW6p/JgZGgTKZsSwFyFORHzv0F s3W+WbhBrGe2H8QDH4RPBI8g0LVpVQg4Ivg64h5np/raUsCkQEAAA== X-Change-ID: 20260702-kmalloc-no-objext-2619c1e06083 To: Vlastimil Babka , Harry Yoo , Andrew Morton , Hao Li , Christoph Lameter , David Rientjes , Roman Gushchin , "Liam R. Howlett" , Suren Baghdasaryan , Hao Ge , Kees Cook , Pedro Falcato , Shakeel Butt , Danielle Constantino Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.3 This is a follow-up fix after the recent discussion [1]. See patch 4 for the detailed description on the bug. Based on slab/for-next-fixes (af9ea231c0b45) and is available at git.kernel.org [2]. Instead preventing cycles by bumping up the allocation size of obj_exts arrays, it introduces a new kmalloc type called KMALLOC_NO_OBJ_EXT and disallow formation of cycles between kmalloc types when allocating obj_exts arrays. obj_exts arrays of normal kmalloc caches are served from KMALLOC_NO_OBJ_EXT caches (that don't have obj_exts), and all other obj_exts arrays are served from normal kmalloc caches. I tried to reuse SLAB_ALLOC_NO_RECURSE to make kmalloc_slab() select KMALLOC_NO_OBJ_EXT, but it was not great because it does not allow sheaves for those caches. So I introduced a new slab alloc flag SLAB_ALLOC_NO_OBJ_EXT. To avoid huge confusion, I had to decouple "disallowing sheaves" semantics from SLAB_NO_OBJ_EXT and introduced SLAB_NO_SHEAVES. While this cannot be directly backported to v6.18 and v6.12 due to lack of SLAB_ALLOC_* flags and kmalloc_flags(), I don't this will be particularily challenging to backport it. Instead of a new slab alloc flag, we can use __GFP_NO_OBJ_EXT to select KMALLOC_NO_OBJ_EXT as kmalloc caches don't have sheaves in v6.18 anyway. [1] https://lore.kernel.org/linux-mm/9a139365-28e6-4f1e-b35b-7f6091e9aa14@kernel.org [2] https://git.kernel.org/pub/scm/linux/kernel/git/harry/linux.git/log/?h=kmalloc-no-objext-v3r1 To: Vlastimil Babka To: Andrew Morton To: Hao Li To: Christoph Lameter To: David Rientjes To: Roman Gushchin To: Suren Baghdasaryan To: Hao Ge To: Kees Cook To: Pedro Falcato To: Shakeel Butt To: Danielle Constantino To: Liam R. Howlett Cc: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Harry Yoo (Oracle) --- Changes in v3 (range-diff included at the end): - Do not create kmalloc-no-objext-* caches unless required (Vlastimil) - Introduce mem_alloc_profiling_permanently_disabled() in patch 3, to avoid creating KMALLOC_NO_OBJ_EXT caches when mem_profiling is permanently disabled. - Make KMALLOC_NO_OBJ_EXT an alias for KMALLOC_NORMAL if CONFIG_SLAB_OBJ_EXT is not defined and avoid ifdefs (refactoring). - Link to v2: https://lore.kernel.org/r/20260710-kmalloc-no-objext-v2-0-2709afb6a030@kernel.org Changes in v2: - Fix a memory leak when kmalloc caches are aliased (patch 1). This is included as part of this series as patch 3 makes it easier to trigger the leak. - Fix a warning in MEM_ALLOC_PROFILING_DEBUG by dropping mark_obj_codetag_empty() for obj_exts. Sashiko raised this and I reproduced it and confirmed that the warnings are gone. https://sashiko.dev/#/patchset/20260702-kmalloc-no-objext-v1-0-167175008538%40kernel.org - Added R-b from Vlastimil on patch 2, thanks! - Adjusted Vlastimil's feedback on RFC v1 - Link to v1: https://lore.kernel.org/r/20260702-kmalloc-no-objext-v1-0-167175008538@kernel.org --- $ b4 prep --compare-to v2 1: 26e19124ce7a = 1: 701534464f8e mm/slab: fix a memory leak due to bootstrapping sheaves twice 2: a4a3a61cea59 = 2: 8c23ba4a36c9 mm/slab: decouple SLAB_NO_SHEAVES from SLAB_NO_OBJ_EXT -: ------------ > 3: c285dbfbf6fb lib/alloc_tag: introduce mem_alloc_profiling_permanently_disabled() 3: 836ba88ba786 ! 4: 8d7f1e6dd334 mm/slab: prevent unbounded recursion in free path with new kmalloc type @@ Commit message never have obj_exts arrays. To achieve this, create a new kmalloc type called KMALLOC_NO_OBJ_EXT. - KMALLOC_NO_OBJ_EXT caches are created when CONFIG_SLAB_OBJ_EXT is - enabled, and they have SLAB_NO_OBJ_EXT flag to prevent allocation - of obj_exts arrays. They remain unused until allocation of obj_exts - arrays for normal kmalloc caches happens. + KMALLOC_NO_OBJ_EXT caches are created with SLAB_NO_OBJ_EXT flag when + either 1) memory allocation profiling is not permanently disabled, + or 2) kmalloc types with a priority higher than KMALLOC_CGROUP are + aliased with KMALLOC_NORMAL. Sheaf bootstrapping for KMALLOC_NO_OBJ_EXT caches now must be deferred because allocation of a barn can trigger obj_exts array allocation of @@ Commit message Signed-off-by: Harry Yoo (Oracle) ## include/linux/slab.h ## +@@ include/linux/slab.h: enum kmalloc_cache_type { + #endif + #ifndef CONFIG_MEMCG + KMALLOC_CGROUP = KMALLOC_NORMAL, ++#endif ++#ifndef CONFIG_SLAB_OBJ_EXT ++ KMALLOC_NO_OBJ_EXT = KMALLOC_NORMAL, + #endif + KMALLOC_PARTITION_START = KMALLOC_NORMAL, + KMALLOC_PARTITION_END = KMALLOC_PARTITION_START + KMALLOC_PARTITION_CACHES_NR, @@ include/linux/slab.h: enum kmalloc_cache_type { #endif #ifdef CONFIG_MEMCG @@ mm/slab.h: static inline unsigned int size_index_elem(unsigned int bytes) unsigned int index; + enum kmalloc_cache_type type = kmalloc_type(flags, token); + -+#ifdef CONFIG_SLAB_OBJ_EXT + if (alloc_flags & SLAB_ALLOC_NO_OBJ_EXT) + type = KMALLOC_NO_OBJ_EXT; -+#endif if (!b) - b = &kmalloc_caches[kmalloc_type(flags, token)]; @@ mm/slab.h: static inline bool is_kmalloc_normal(struct kmem_cache *s) } bool __kfree_rcu_sheaf(struct kmem_cache *s, void *obj); +@@ mm/slab.h: static inline void metadata_access_disable(void) + kasan_enable_current(); + } + ++/* ++ * Return true if KMALLOC_NORMAL caches may need obj_exts arrays. ++ * ++ * Memory allocation profiling requires obj_exts for all caches. ++ * Memcg usually doesn't need them for normal kmalloc caches, but kmalloc types ++ * with a priority higher than KMALLOC_CGROUP can be aliased with KMALLOC_NORMAL. ++ */ ++static inline bool need_kmalloc_no_objext(void) ++{ ++ if (!mem_alloc_profiling_permanently_disabled()) ++ return true; ++ ++ if (!mem_cgroup_kmem_disabled() && ++ (KMALLOC_NORMAL == KMALLOC_RECLAIM)) ++ return true; ++ ++ return false; ++} ++ + #ifdef CONFIG_SLAB_OBJ_EXT + + /* ## mm/slab_common.c ## @@ mm/slab_common.c: u8 kmalloc_size_index[24] __ro_after_init = { @@ mm/slab_common.c: EXPORT_SYMBOL(kmalloc_size_roundup); } @@ mm/slab_common.c: new_kmalloc_cache(int idx, enum kmalloc_cache_type type) - flags |= SLAB_NO_MERGE; - #endif - -+#ifdef CONFIG_SLAB_OBJ_EXT -+ if (type == KMALLOC_NO_OBJ_EXT) + return; + } + flags |= SLAB_ACCOUNT; ++ } else if (IS_ENABLED(CONFIG_SLAB_OBJ_EXT) && type == KMALLOC_NO_OBJ_EXT) { ++ if (!need_kmalloc_no_objext()) { ++ kmalloc_caches[type][idx] = kmalloc_caches[KMALLOC_NORMAL][idx]; ++ return; ++ } + flags |= SLAB_NO_OBJ_EXT | SLAB_NO_MERGE; -+#endif -+ - /* - * If CONFIG_MEMCG is enabled, disable cache merging for - * KMALLOC_NORMAL caches. + } else if (IS_ENABLED(CONFIG_ZONE_DMA) && (type == KMALLOC_DMA)) { + flags |= SLAB_CACHE_DMA; + } ## mm/slub.c ## @@ mm/slub.c: static inline void init_slab_obj_exts(struct slab *slab) @@ mm/slub.c: int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, + * However, normal kmalloc caches must allocate them from + * KMALLOC_NO_OBJ_EXT caches to prevent recursion. + */ -+ if (is_kmalloc_normal(s)) ++ if (is_kmalloc_normal(s)) { ++ VM_WARN_ON_ONCE(!need_kmalloc_no_objext()); + alloc_flags |= SLAB_ALLOC_NO_OBJ_EXT; ++ } - sz = obj_exts_alloc_size(s, slab, gfp); + alloc_flags &= ~SLAB_ALLOC_NEW_SLAB; --- Harry Yoo (Oracle) (4): mm/slab: fix a memory leak due to bootstrapping sheaves twice mm/slab: decouple SLAB_NO_SHEAVES from SLAB_NO_OBJ_EXT lib/alloc_tag: introduce mem_alloc_profiling_permanently_disabled() mm/slab: prevent unbounded recursion in free path with new kmalloc type include/linux/alloc_tag.h | 3 ++ include/linux/slab.h | 19 +++++++- lib/alloc_tag.c | 9 ++++ mm/slab.h | 32 +++++++++++-- mm/slab_common.c | 19 +++++++- mm/slub.c | 111 ++++++++++++++++++++-------------------------- 6 files changed, 123 insertions(+), 70 deletions(-) --- base-commit: 72bb229f9161a1efcd5df32141b69fcc6ae81a13 change-id: 20260702-kmalloc-no-objext-2619c1e06083 Best regards, -- Harry Yoo (Oracle)