[RFC PATCH v7 05/10] trace: make the stackmap capacity settable on the kernel command line
From: Li Pengfei <hidden>
Date: 2026-09-12 08:39:27
Also in:
linux-doc, linux-kselftest, lkml
Subsystem:
documentation, the rest, tracing · Maintainers:
Jonathan Corbet, Linus Torvalds, Steven Rostedt, Masami Hiramatsu
From: Pengfei Li <redacted> Add ftrace_stackmap.bits=N to size the map at boot, replacing the fixed capacity the map was created with so far. N is clamped to [10, 18], and the value is clamped again at create time so a bogus setting cannot get through even if early_param is bypassed. The upper bound keeps the worst case bounded: bits=18 means 256K elements, 512K table slots and a ~130 MB element pool. The default stays at 14, which gives 16K elements and a ~8 MB pool. Signed-off-by: Pengfei Li <redacted> --- .../admin-guide/kernel-parameters.txt | 7 ++++ kernel/trace/Kconfig | 4 +++ kernel/trace/trace_stackmap.c | 36 +++++++++++++++---- 3 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index b5493a7f8f22..9ca271e21bf0 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt@@ -1794,6 +1794,13 @@ Kernel parameters can be changed at run time by the max_graph_depth file in the tracefs tracing directory. default: 0 (no limit) + ftrace_stackmap.bits= + [FTRACE] Set the stackmap capacity to 2^N records. + Format: <int> + default: 14; values are clamped to the range 10-18. + The upper bound reserves roughly 130 MB for the element + pool. See Documentation/trace/ftrace-stackmap.rst. + fw_devlink= [KNL,EARLY] Create device links between consumer and supplier devices by scanning the firmware to infer the consumer/supplier relationships. This feature is
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 7001453bbfd3..b2cde74d803b 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig@@ -435,6 +435,10 @@ config FTRACE_STACKMAP deduplicated when stackmap is enabled for their trace array. Stackmap is currently available only for the global trace array. + Map capacity defaults to 2^14 records and can be changed with the + ftrace_stackmap.bits= boot parameter. Values are clamped to 10-18; + the upper bound reserves roughly 130 MB for the element pool. + The deduplicated stacks are exported via: /sys/kernel/debug/tracing/stack_map
diff --git a/kernel/trace/trace_stackmap.c b/kernel/trace/trace_stackmap.c
index 439d3be9e351..49ea403822ba 100644
--- a/kernel/trace/trace_stackmap.c
+++ b/kernel/trace/trace_stackmap.c@@ -150,12 +150,31 @@ struct ftrace_stackmap { }; /* - * Map capacity: 2^FTRACE_STACKMAP_BITS stack records, with the hash - * table over-provisioned 2x on top of that. This gives 16K elements - * and a ~8 MB element pool, sized for the repetitive-stack workloads - * the map targets. + * Map capacity: 2^bits stack records, with the hash table + * over-provisioned 2x on top of that. The range is capped to keep + * worst-case allocations bounded: + * bits=18 -> 256K elts, 512K slots, ~130 MB elt pool, and a + * stack_map_bin reader walking that many entries. + * The default of 14 gives 16K elts and a ~8 MB pool, which suits the + * repetitive-stack workloads the map targets; raise it through + * ftrace_stackmap.bits= for a higher stack-record capacity. */ -#define FTRACE_STACKMAP_BITS 14 +#define FTRACE_STACKMAP_BITS_MIN 10 +#define FTRACE_STACKMAP_BITS_MAX 18 +#define FTRACE_STACKMAP_BITS_DEFAULT 14 + +static unsigned int stackmap_map_bits = FTRACE_STACKMAP_BITS_DEFAULT; +static int __init stackmap_bits_setup(char *str) +{ + unsigned long val; + + if (kstrtoul(str, 0, &val)) + return -EINVAL; + val = clamp_val(val, FTRACE_STACKMAP_BITS_MIN, FTRACE_STACKMAP_BITS_MAX); + stackmap_map_bits = val; + return 0; +} +early_param("ftrace_stackmap.bits", stackmap_bits_setup); /* --- Element pool --- */
@@ -182,12 +201,17 @@ static struct stackmap_elt *stackmap_get_elt(struct ftrace_stackmap *smap) struct ftrace_stackmap *ftrace_stackmap_create(struct trace_array *tr) { struct ftrace_stackmap *smap; - unsigned int bits = FTRACE_STACKMAP_BITS; + unsigned int bits; smap = kzalloc_obj(*smap, GFP_KERNEL); if (!smap) return ERR_PTR(-ENOMEM); + /* Defensive clamp even if the early parameter path is bypassed. */ + bits = clamp_val(stackmap_map_bits, + FTRACE_STACKMAP_BITS_MIN, + FTRACE_STACKMAP_BITS_MAX); + smap->tr = tr; smap->map_bits = bits; smap->max_elts = 1U << bits;
--
2.34.1