From: Marco Elver <elver@google.com>
To: Caleb Kan <calebkan1106@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
kasan-dev@googlegroups.com, Vlastimil Babka <vbabka@kernel.org>,
Alexander Potapenko <glider@google.com>,
Dmitry Vyukov <dvyukov@google.com>,
Andrey Konovalov <andreyknvl@gmail.com>,
Oscar Salvador <osalvador@suse.de>,
Caleb Kan <ckan@cloudflare.com>,
kernel-team@cloudflare.com
Subject: Re: [PATCH RFC v2 05/11] kmsan: report trie-backed stack depot traces
Date: Tue, 20 Oct 2026 14:53:24 +0000 [thread overview]
Message-ID: <ateAZGtPTpdBDSbn@elver.google.com> (raw)
In-Reply-To: <20260908-stackdepot-trie-v2-5-1996d5cef732@cloudflare.com>
On Tue, Sep 08, 2026 at 02:13PM +0100, Caleb Kan wrote:
> From: Caleb Kan <ckan@cloudflare.com>
>
> KMSAN stores ordinary origin stacks and synthetic alloca and chain origins
> in stack depot and retains the resulting persistent handles. Once trie
> storage is enabled, these handles can refer to trie-backed entries, while
> kmsan_print_origin() still relies on the hash-only stack_depot_fetch() API.
>
> Use one KMSAN_STACK_DEPTH array to materialize each origin and chained
> stack in turn. Preserve the chain's head and next-origin handles before
> reusing the array for the chained stack. The array covers both the regular
> save limit and the smaller synthetic records.
>
> Pass the scratch array into a common origin-printing helper. Keep local
> storage for standalone kmsan_print_origin() calls, but let kmsan_report()
> reuse its existing stack_entries array after printing the report stack.
> With x86-64 Clang 19, the regular nested report path uses 752 bytes, below
> its 768-byte size before this conversion.
>
> lib/stackdepot.c is uninstrumented, so stack_depot_fetch_into() unpoisons
> the successfully copied range before returning it to KMSAN. Remove the
> now-redundant explicit unpoisoning of chained entries. Origin depth and
> use-after-free metadata remain in the handle's extra bits and are
> unchanged.
>
> Update test_stackdepot_roundtrip() to use caller-owned storage while
> retaining its frame-count and kmsan_check_memory() checks. This verifies
> that the copy-out API returns initialized entries to instrumented callers.
>
> Signed-off-by: Caleb Kan <ckan@cloudflare.com>
> ---
> mm/kmsan/kmsan_test.c | 4 ++--
> mm/kmsan/report.c | 28 ++++++++++++++++------------
> 2 files changed, 18 insertions(+), 14 deletions(-)
>
> diff --git a/mm/kmsan/kmsan_test.c b/mm/kmsan/kmsan_test.c
> index 31f47cc4dab4..7c04e4b21873 100644
> --- a/mm/kmsan/kmsan_test.c
> +++ b/mm/kmsan/kmsan_test.c
> @@ -669,7 +669,7 @@ static void test_long_origin_chain(struct kunit *test)
> */
> static void test_stackdepot_roundtrip(struct kunit *test)
> {
> - unsigned long src_entries[16], *dst_entries;
> + unsigned long src_entries[16], dst_entries[16];
> unsigned int src_nentries, dst_nentries;
> EXPECTATION_NO_REPORT(expect);
> depot_stack_handle_t handle;
> @@ -680,7 +680,7 @@ static void test_stackdepot_roundtrip(struct kunit *test)
> stack_trace_save(src_entries, ARRAY_SIZE(src_entries), 1);
> handle = stack_depot_save(src_entries, src_nentries, GFP_KERNEL);
> stack_depot_print(handle);
> - dst_nentries = stack_depot_fetch(handle, &dst_entries);
> + dst_nentries = stack_depot_fetch_into(handle, dst_entries, ARRAY_SIZE(dst_entries));
> KUNIT_EXPECT_TRUE(test, src_nentries == dst_nentries);
>
> kmsan_check_memory((void *)dst_entries,
> diff --git a/mm/kmsan/report.c b/mm/kmsan/report.c
> index d6853ce08954..0770658ba932 100644
> --- a/mm/kmsan/report.c
> +++ b/mm/kmsan/report.c
> @@ -83,9 +83,9 @@ static char *pretty_descr(char *descr)
> return report_local_descr;
> }
>
> -void kmsan_print_origin(depot_stack_handle_t origin)
> +static void kmsan_print_origin_with_buf(depot_stack_handle_t origin,
> + unsigned long *entries)
> {
> - unsigned long *entries = NULL, *chained_entries = NULL;
> unsigned int nr_entries, chained_nr_entries, skipnr;
> void *pc1 = NULL, *pc2 = NULL;
> depot_stack_handle_t head;
> @@ -97,7 +97,8 @@ void kmsan_print_origin(depot_stack_handle_t origin)
> return;
>
> while (true) {
> - nr_entries = stack_depot_fetch(origin, &entries);
> + nr_entries =
> + stack_depot_fetch_into(origin, entries, KMSAN_STACK_DEPTH);
> depth = kmsan_depth_from_eb(stack_depot_get_extra_bits(origin));
> magic = nr_entries ? entries[0] : 0;
> if ((nr_entries == 4) && (magic == KMSAN_ALLOCA_MAGIC_ORIGIN)) {
Routing KMSAN's synthetic alloca and chain origins into the trie (patch 10)
breaks KMSAN after 1024 origins:
__msan_poison_alloca():
entries[0] = KMSAN_ALLOCA_MAGIC_ORIGIN
entries[1] = (u64)descr /* unique per instrumented local variable */
kmsan_internal_chain_origin():
entries[0] = KMSAN_CHAIN_MAGIC_ORIGIN
entries[1] = extra | ((u64)id << 32)
Because the trie in patch 10 is keyed starting at entries[0], *every*
alloca origin in the kernel is a direct child of the single depth-1
[KMSAN_ALLOCA_MAGIC_ORIGIN] node, and every distinct stack handle is a
direct child of [KMSAN_CHAIN_MAGIC_ORIGIN].
In patch 10, a node's child array cannot exceed 1024 children
(roundup_pow_of_two(1025) = 2048 -> 16424 bytes >
STACK_DEPOT_TRIE_POOL_USABLE_SIZE = 16208 bytes). Once 1024 local
variables are poisoned during boot, every subsequent new
__msan_poison_alloca() and kmsan_internal_chain_origin() permanently
returns 0.
Even below that limit, a 3-entry chain origin takes ~120 bytes in the
trie (node + child slot + side-table slot) vs 48 bytes in the hash table.
next prev parent reply other threads:[~2026-10-20 14:53 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 13:13 [PATCH RFC v2 00/11] stackdepot: reduce memory use for persistent stack records with a trie Caleb Kan
2026-09-08 13:13 ` [PATCH RFC v2 01/11] stackdepot: stop preallocating after the final pool Caleb Kan
2026-10-16 16:53 ` Marco Elver
2026-09-08 13:13 ` [PATCH RFC v2 02/11] stackdepot: add caller-owned stack trace fetching Caleb Kan
2026-10-20 11:00 ` Marco Elver
2026-09-08 13:13 ` [PATCH RFC v2 03/11] mm/page_owner: preserve accounting with countable stack depot records Caleb Kan
2026-10-20 11:11 ` Marco Elver
2026-09-08 13:13 ` [PATCH RFC v2 04/11] mm/kmemleak: print trie-backed stack depot traces Caleb Kan
2026-09-08 13:13 ` [PATCH RFC v2 05/11] kmsan: report " Caleb Kan
2026-10-20 14:53 ` Marco Elver [this message]
2026-09-08 13:13 ` [PATCH RFC v2 06/11] mm/slub: materialize " Caleb Kan
2026-09-08 13:13 ` [PATCH RFC v2 07/11] drm/locking: preserve deadlock diagnostics for trie-backed stacks Caleb Kan
2026-09-08 13:13 ` [PATCH RFC v2 08/11] scripts/gdb: reject trie-backed stack depot handles Caleb Kan
2026-09-08 13:13 ` [PATCH RFC v2 09/11] stackdepot: add architecture hooks for compact frame storage Caleb Kan
2026-10-20 14:56 ` Marco Elver
2026-09-08 13:13 ` [PATCH RFC v2 10/11] stackdepot: share persistent stack prefixes with trie storage Caleb Kan
2026-10-20 15:04 ` Marco Elver
2026-09-08 13:13 ` [PATCH RFC v2 11/11] stackdepot: add KUnit tests for " Caleb Kan
2026-10-07 10:34 ` [PATCH RFC v2 00/11] stackdepot: reduce memory use for persistent stack records with a trie Matt Fleming
2026-10-20 15:07 ` Marco Elver
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ateAZGtPTpdBDSbn@elver.google.com \
--to=elver@google.com \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@gmail.com \
--cc=calebkan1106@gmail.com \
--cc=ckan@cloudflare.com \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=kasan-dev@googlegroups.com \
--cc=kernel-team@cloudflare.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=osalvador@suse.de \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.