Skip to content

Commit ed4f142

Browse files
mflemingakpm00
authored andcommitted
stackdepot: make max number of pools boot-time configurable
We're hitting the WARN in depot_init_pool() about reaching the stack depot limit because we have long stacks that don't dedup very well. Introduce a new start-up parameter to allow users to set the number of maximum stack depot pools. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Matt Fleming <[email protected]> Acked-by: Vlastimil Babka <[email protected]> Acked-by: Marco Elver <[email protected]> Cc: Alexander Potapenko <[email protected]> Cc: Andrey Konovalov <[email protected]> Cc: Dmitriy Vyukov <[email protected]> Cc: Oscar Salvador <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 6c6d8f8 commit ed4f142

2 files changed

Lines changed: 63 additions & 9 deletions

File tree

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7029,6 +7029,11 @@
70297029
consumed by the stack hash table. By default this is set
70307030
to false.
70317031

7032+
stack_depot_max_pools= [KNL,EARLY]
7033+
Specify the maximum number of pools to use for storing
7034+
stack traces. Pools are allocated on-demand up to this
7035+
limit. Default value is 8191 pools.
7036+
70327037
stacktrace [FTRACE]
70337038
Enabled the stack tracer on boot up.
70347039

lib/stackdepot.c

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@
3636
#include <linux/memblock.h>
3737
#include <linux/kasan-enabled.h>
3838

39-
#define DEPOT_POOLS_CAP 8192
40-
/* The pool_index is offset by 1 so the first record does not have a 0 handle. */
41-
#define DEPOT_MAX_POOLS \
42-
(((1LL << (DEPOT_POOL_INDEX_BITS)) - 1 < DEPOT_POOLS_CAP) ? \
43-
(1LL << (DEPOT_POOL_INDEX_BITS)) - 1 : DEPOT_POOLS_CAP)
39+
/*
40+
* The pool_index is offset by 1 so the first record does not have a 0 handle.
41+
*/
42+
static unsigned int stack_max_pools __read_mostly =
43+
MIN((1LL << DEPOT_POOL_INDEX_BITS) - 1, 8192);
4444

4545
static bool stack_depot_disabled;
4646
static bool __stack_depot_early_init_requested __initdata = IS_ENABLED(CONFIG_STACKDEPOT_ALWAYS_INIT);
@@ -62,7 +62,7 @@ static unsigned int stack_bucket_number_order;
6262
static unsigned int stack_hash_mask;
6363

6464
/* Array of memory regions that store stack records. */
65-
static void *stack_pools[DEPOT_MAX_POOLS];
65+
static void **stack_pools;
6666
/* Newly allocated pool that is not yet added to stack_pools. */
6767
static void *new_pool;
6868
/* Number of pools in stack_pools. */
@@ -101,6 +101,34 @@ static int __init disable_stack_depot(char *str)
101101
}
102102
early_param("stack_depot_disable", disable_stack_depot);
103103

104+
static int __init parse_max_pools(char *str)
105+
{
106+
const long long limit = (1LL << (DEPOT_POOL_INDEX_BITS)) - 1;
107+
unsigned int max_pools;
108+
int rv;
109+
110+
rv = kstrtouint(str, 0, &max_pools);
111+
if (rv)
112+
return rv;
113+
114+
if (max_pools < 1024) {
115+
pr_err("stack_depot_max_pools below 1024, using default of %u\n",
116+
stack_max_pools);
117+
goto out;
118+
}
119+
120+
if (max_pools > limit) {
121+
pr_err("stack_depot_max_pools exceeds %lld, using default of %u\n",
122+
limit, stack_max_pools);
123+
goto out;
124+
}
125+
126+
stack_max_pools = max_pools;
127+
out:
128+
return 0;
129+
}
130+
early_param("stack_depot_max_pools", parse_max_pools);
131+
104132
void __init stack_depot_request_early_init(void)
105133
{
106134
/* Too late to request early init now. */
@@ -182,6 +210,17 @@ int __init stack_depot_early_init(void)
182210
}
183211
init_stack_table(entries);
184212

213+
pr_info("allocating space for %u stack pools via memblock\n",
214+
stack_max_pools);
215+
stack_pools =
216+
memblock_alloc(stack_max_pools * sizeof(void *), PAGE_SIZE);
217+
if (!stack_pools) {
218+
pr_err("stack pools allocation failed, disabling\n");
219+
memblock_free(stack_table, entries * sizeof(struct list_head));
220+
stack_depot_disabled = true;
221+
return -ENOMEM;
222+
}
223+
185224
return 0;
186225
}
187226

@@ -231,6 +270,16 @@ int stack_depot_init(void)
231270
stack_hash_mask = entries - 1;
232271
init_stack_table(entries);
233272

273+
pr_info("allocating space for %u stack pools via kvcalloc\n",
274+
stack_max_pools);
275+
stack_pools = kvcalloc(stack_max_pools, sizeof(void *), GFP_KERNEL);
276+
if (!stack_pools) {
277+
pr_err("stack pools allocation failed, disabling\n");
278+
kvfree(stack_table);
279+
stack_depot_disabled = true;
280+
ret = -ENOMEM;
281+
}
282+
234283
out_unlock:
235284
mutex_unlock(&stack_depot_init_mutex);
236285

@@ -245,9 +294,9 @@ static bool depot_init_pool(void **prealloc)
245294
{
246295
lockdep_assert_held(&pool_lock);
247296

248-
if (unlikely(pools_num >= DEPOT_MAX_POOLS)) {
297+
if (unlikely(pools_num >= stack_max_pools)) {
249298
/* Bail out if we reached the pool limit. */
250-
WARN_ON_ONCE(pools_num > DEPOT_MAX_POOLS); /* should never happen */
299+
WARN_ON_ONCE(pools_num > stack_max_pools); /* should never happen */
251300
WARN_ON_ONCE(!new_pool); /* to avoid unnecessary pre-allocation */
252301
WARN_ONCE(1, "Stack depot reached limit capacity");
253302
return false;
@@ -273,7 +322,7 @@ static bool depot_init_pool(void **prealloc)
273322
* NULL; do not reset to NULL if we have reached the maximum number of
274323
* pools.
275324
*/
276-
if (pools_num < DEPOT_MAX_POOLS)
325+
if (pools_num < stack_max_pools)
277326
WRITE_ONCE(new_pool, NULL);
278327
else
279328
WRITE_ONCE(new_pool, STACK_DEPOT_POISON);

0 commit comments

Comments
 (0)