Skip to content

Commit

Permalink
lib/stackdepot: use fixed-sized slots for stack records
Browse files Browse the repository at this point in the history
Instead of storing stack records in stack depot pools one right after
another, use fixed-sized slots.

Add a new Kconfig option STACKDEPOT_MAX_FRAMES that allows to select the
size of the slot in frames.  Use 64 as the default value, which is the
maximum stack trace size both KASAN and KMSAN use right now.

Also add descriptions for other stack depot Kconfig options.

This is preparatory patch for implementing the eviction of stack records
from the stack depot.

Link: https://lkml.kernel.org/r/dce7d030a99ff61022509665187fac45b0827298.1700502145.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <[email protected]>
Cc: Alexander Potapenko <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: Evgenii Stepanov <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Oscar Salvador <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
xairy authored and akpm00 committed Dec 11, 2023
1 parent 83130ab commit fc60e0c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
10 changes: 10 additions & 0 deletions lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -713,10 +713,20 @@ config ARCH_STACKWALK
config STACKDEPOT
bool
select STACKTRACE
help
Stack depot: stack trace storage that avoids duplication

config STACKDEPOT_ALWAYS_INIT
bool
select STACKDEPOT
help
Always initialize stack depot during early boot

config STACKDEPOT_MAX_FRAMES
int "Maximum number of frames in trace saved in stack depot"
range 1 256
default 64
depends on STACKDEPOT

config REF_TRACKER
bool
Expand Down
13 changes: 9 additions & 4 deletions lib/stackdepot.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,12 @@ struct stack_record {
u32 hash; /* Hash in the hash table */
u32 size; /* Number of stored frames */
union handle_parts handle;
unsigned long entries[]; /* Variable-sized array of frames */
unsigned long entries[CONFIG_STACKDEPOT_MAX_FRAMES]; /* Frames */
};

#define DEPOT_STACK_RECORD_SIZE \
ALIGN(sizeof(struct stack_record), 1 << DEPOT_STACK_ALIGN)

static bool stack_depot_disabled;
static bool __stack_depot_early_init_requested __initdata = IS_ENABLED(CONFIG_STACKDEPOT_ALWAYS_INIT);
static bool __stack_depot_early_init_passed __initdata;
Expand Down Expand Up @@ -264,9 +267,7 @@ static struct stack_record *
depot_alloc_stack(unsigned long *entries, int size, u32 hash, void **prealloc)
{
struct stack_record *stack;
size_t required_size = struct_size(stack, entries, size);

required_size = ALIGN(required_size, 1 << DEPOT_STACK_ALIGN);
size_t required_size = DEPOT_STACK_RECORD_SIZE;

/* Check if there is not enough space in the current pool. */
if (unlikely(pool_offset + required_size > DEPOT_POOL_SIZE)) {
Expand Down Expand Up @@ -301,6 +302,10 @@ depot_alloc_stack(unsigned long *entries, int size, u32 hash, void **prealloc)
if (stack_pools[pool_index] == NULL)
return NULL;

/* Limit number of saved frames to CONFIG_STACKDEPOT_MAX_FRAMES. */
if (size > CONFIG_STACKDEPOT_MAX_FRAMES)
size = CONFIG_STACKDEPOT_MAX_FRAMES;

/* Save the stack trace. */
stack = stack_pools[pool_index] + pool_offset;
stack->hash = hash;
Expand Down

0 comments on commit fc60e0c

Please sign in to comment.