Skip to content

Commit 239d6c9

Browse files
surenbaghdasaryanakpm00
authored andcommitted
codetag: debug: skip objext checking when it's for objext itself
objext objects are created with __GFP_NO_OBJ_EXT flag and therefore have no corresponding objext themselves (otherwise we would get an infinite recursion). When freeing these objects their codetag will be empty and when CONFIG_MEM_ALLOC_PROFILING_DEBUG is enabled this will lead to false warnings. Introduce CODETAG_EMPTY special codetag value to mark allocations which intentionally lack codetag to avoid these warnings. Set objext codetags to CODETAG_EMPTY before freeing to indicate that the codetag is expected to be empty. Link: https://lkml.kernel.org/r/20240321163705.3067592-34-surenb@google.com Signed-off-by: Suren Baghdasaryan <surenb@google.com> Tested-by: Kees Cook <keescook@chromium.org> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Alex Gaynor <alex.gaynor@gmail.com> Cc: Alice Ryhl <aliceryhl@google.com> Cc: Andreas Hindborg <a.hindborg@samsung.com> Cc: Benno Lossin <benno.lossin@proton.me> Cc: "Björn Roy Baron" <bjorn3_gh@protonmail.com> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Christoph Lameter <cl@linux.com> Cc: Dennis Zhou <dennis@kernel.org> Cc: Gary Guo <gary@garyguo.net> Cc: Kent Overstreet <kent.overstreet@linux.dev> Cc: Miguel Ojeda <ojeda@kernel.org> Cc: Pasha Tatashin <pasha.tatashin@soleen.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Tejun Heo <tj@kernel.org> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Wedson Almeida Filho <wedsonaf@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 1438d34 commit 239d6c9

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

include/linux/alloc_tag.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,27 @@ struct alloc_tag {
2929
struct alloc_tag_counters __percpu *counters;
3030
} __aligned(8);
3131

32+
#ifdef CONFIG_MEM_ALLOC_PROFILING_DEBUG
33+
34+
#define CODETAG_EMPTY ((void *)1)
35+
36+
static inline bool is_codetag_empty(union codetag_ref *ref)
37+
{
38+
return ref->ct == CODETAG_EMPTY;
39+
}
40+
41+
static inline void set_codetag_empty(union codetag_ref *ref)
42+
{
43+
if (ref)
44+
ref->ct = CODETAG_EMPTY;
45+
}
46+
47+
#else /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */
48+
49+
static inline bool is_codetag_empty(union codetag_ref *ref) { return false; }
50+
51+
#endif /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */
52+
3253
#ifdef CONFIG_MEM_ALLOC_PROFILING
3354

3455
struct codetag_bytes {
@@ -151,6 +172,11 @@ static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes)
151172
if (!ref || !ref->ct)
152173
return;
153174

175+
if (is_codetag_empty(ref)) {
176+
ref->ct = NULL;
177+
return;
178+
}
179+
154180
tag = ct_to_alloc_tag(ref->ct);
155181

156182
this_cpu_sub(tag->counters->bytes, bytes);

mm/slub.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,30 @@ static inline enum node_stat_item cache_vmstat_idx(struct kmem_cache *s)
18731873

18741874
#ifdef CONFIG_SLAB_OBJ_EXT
18751875

1876+
#ifdef CONFIG_MEM_ALLOC_PROFILING_DEBUG
1877+
1878+
static inline void mark_objexts_empty(struct slabobj_ext *obj_exts)
1879+
{
1880+
struct slabobj_ext *slab_exts;
1881+
struct slab *obj_exts_slab;
1882+
1883+
obj_exts_slab = virt_to_slab(obj_exts);
1884+
slab_exts = slab_obj_exts(obj_exts_slab);
1885+
if (slab_exts) {
1886+
unsigned int offs = obj_to_index(obj_exts_slab->slab_cache,
1887+
obj_exts_slab, obj_exts);
1888+
/* codetag should be NULL */
1889+
WARN_ON(slab_exts[offs].ref.ct);
1890+
set_codetag_empty(&slab_exts[offs].ref);
1891+
}
1892+
}
1893+
1894+
#else /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */
1895+
1896+
static inline void mark_objexts_empty(struct slabobj_ext *obj_exts) {}
1897+
1898+
#endif /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */
1899+
18761900
/*
18771901
* The allocated objcg pointers array is not accounted directly.
18781902
* Moreover, it should not come from DMA buffer and is not readily
@@ -1913,6 +1937,7 @@ static int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
19131937
* assign slabobj_exts in parallel. In this case the existing
19141938
* objcg vector should be reused.
19151939
*/
1940+
mark_objexts_empty(vec);
19161941
kfree(vec);
19171942
return 0;
19181943
}
@@ -1929,6 +1954,14 @@ static inline void free_slab_obj_exts(struct slab *slab)
19291954
if (!obj_exts)
19301955
return;
19311956

1957+
/*
1958+
* obj_exts was created with __GFP_NO_OBJ_EXT flag, therefore its
1959+
* corresponding extension will be NULL. alloc_tag_sub() will throw a
1960+
* warning if slab has extensions but the extension of an object is
1961+
* NULL, therefore replace NULL with CODETAG_EMPTY to indicate that
1962+
* the extension for obj_exts is expected to be NULL.
1963+
*/
1964+
mark_objexts_empty(obj_exts);
19321965
kfree(obj_exts);
19331966
slab->obj_exts = 0;
19341967
}

0 commit comments

Comments
 (0)