| 1 |
|
| 2 | |
| 3 | * Stack depot - a stack trace storage that avoids duplication.
|
| 4 | *
|
| 5 | * Stack depot is intended to be used by subsystems that need to store and
|
| 6 | * later retrieve many potentially duplicated stack traces without wasting
|
| 7 | * memory.
|
| 8 | *
|
| 9 | * For example, KASAN needs to save allocation and free stack traces for each
|
| 10 | * object. Storing two stack traces per object requires a lot of memory (e.g.
|
| 11 | * SLUB_DEBUG needs 256 bytes per object for that). Since allocation and free
|
| 12 | * stack traces often repeat, using stack depot allows to save about 100x space.
|
| 13 | *
|
| 14 | * Stack traces are never removed from the stack depot.
|
| 15 | *
|
| 16 | * Author: Alexander Potapenko <[email protected]>
|
| 17 | * Copyright (C) 2016 Google, Inc.
|
| 18 | *
|
| 19 | * Based on the code by Dmitry Chernenkov.
|
| 20 |
|
| 21 |
|
| 22 | #ifndef _LINUX_STACKDEPOT_H
|
| 23 | #define _LINUX_STACKDEPOT_H
|
| 24 |
|
| 25 | #include <linux/gfp.h>
|
| 26 |
|
| 27 | typedef u32 depot_stack_handle_t;
|
| 28 |
|
| 29 | |
| 30 | * Number of bits in the handle that stack depot doesn't use. Users may store
|
| 31 | * information in them via stack_depot_set/get_extra_bits.
|
| 32 |
|
| 33 | #define STACK_DEPOT_EXTRA_BITS 5
|
| 34 |
|
| 35 | |
| 36 | * Using stack depot requires its initialization, which can be done in 3 ways:
|
| 37 | *
|
| 38 | * 1. Selecting CONFIG_STACKDEPOT_ALWAYS_INIT. This option is suitable in
|
| 39 | * scenarios where it's known at compile time that stack depot will be used.
|
| 40 | * Enabling this config makes the kernel initialize stack depot in mm_init().
|
| 41 | *
|
| 42 | * 2. Calling stack_depot_request_early_init() during early boot, before
|
| 43 | * stack_depot_early_init() in mm_init() completes. For example, this can
|
| 44 | * be done when evaluating kernel boot parameters.
|
| 45 | *
|
| 46 | * 3. Calling stack_depot_init(). Possible after boot is complete. This option
|
| 47 | * is recommended for modules initialized later in the boot process, after
|
| 48 | * mm_init() completes.
|
| 49 | *
|
| 50 | * stack_depot_init() and stack_depot_request_early_init() can be called
|
| 51 | * regardless of whether CONFIG_STACKDEPOT is enabled and are no-op when this
|
| 52 | * config is disabled. The save/fetch/print stack depot functions can only be
|
| 53 | * called from the code that makes sure CONFIG_STACKDEPOT is enabled _and_
|
| 54 | * initializes stack depot via one of the ways listed above.
|
| 55 |
|
| 56 | #ifdef CONFIG_STACKDEPOT
|
| 57 | int stack_depot_init(void);
|
| 58 |
|
| 59 | void __init stack_depot_request_early_init(void);
|
| 60 |
|
| 61 |
|
| 62 | int __init stack_depot_early_init(void);
|
| 63 | #else
|
| 64 | static inline int stack_depot_init(void) { return 0; }
|
| 65 |
|
| 66 | static inline void stack_depot_request_early_init(void) { }
|
| 67 |
|
| 68 | static inline int stack_depot_early_init(void) { return 0; }
|
| 69 | #endif
|
| 70 |
|
| 71 | |
| 72 | * __stack_depot_save - Save a stack trace to stack depot
|
| 73 | *
|
| 74 | * @entries: Pointer to the stack trace
|
| 75 | * @nr_entries: Number of frames in the stack
|
| 76 | * @alloc_flags: Allocation GFP flags
|
| 77 | * @can_alloc: Allocate stack pools (increased chance of failure if false)
|
| 78 | *
|
| 79 | * Saves a stack trace from @entries array of size @nr_entries. If @can_alloc is
|
| 80 | * %true, stack depot can replenish the stack pools in case no space is left
|
| 81 | * (allocates using GFP flags of @alloc_flags). If @can_alloc is %false, avoids
|
| 82 | * any allocations and fails if no space is left to store the stack trace.
|
| 83 | *
|
| 84 | * If the provided stack trace comes from the interrupt context, only the part
|
| 85 | * up to the interrupt entry is saved.
|
| 86 | *
|
| 87 | * Context: Any context, but setting @can_alloc to %false is required if
|
| 88 | * alloc_pages() cannot be used from the current context. Currently
|
| 89 | * this is the case for contexts where neither %GFP_ATOMIC nor
|
| 90 | * %GFP_NOWAIT can be used (NMI, raw_spin_lock).
|
| 91 | *
|
| 92 | * Return: Handle of the stack struct stored in depot, 0 on failure
|
| 93 |
|
| 94 | depot_stack_handle_t __stack_depot_save(unsigned long *entries,
|
| 95 | unsigned int nr_entries,
|
| 96 | gfp_t gfp_flags, bool can_alloc);
|
| 97 |
|
| 98 | |
| 99 | * stack_depot_save - Save a stack trace to stack depot
|
| 100 | *
|
| 101 | * @entries: Pointer to the stack trace
|
| 102 | * @nr_entries: Number of frames in the stack
|
| 103 | * @alloc_flags: Allocation GFP flags
|
| 104 | *
|
| 105 | * Context: Contexts where allocations via alloc_pages() are allowed.
|
| 106 | * See __stack_depot_save() for more details.
|
| 107 | *
|
| 108 | * Return: Handle of the stack trace stored in depot, 0 on failure
|
| 109 |
|
| 110 | depot_stack_handle_t stack_depot_save(unsigned long *entries,
|
| 111 | unsigned int nr_entries, gfp_t gfp_flags);
|
| 112 |
|
| 113 | |
| 114 | * stack_depot_fetch - Fetch a stack trace from stack depot
|
| 115 | *
|
| 116 | * @handle: Stack depot handle returned from stack_depot_save()
|
| 117 | * @entries: Pointer to store the address of the stack trace
|
| 118 | *
|
| 119 | * Return: Number of frames for the fetched stack
|
| 120 |
|
| 121 | unsigned int stack_depot_fetch(depot_stack_handle_t handle,
|
| 122 | unsigned long **entries);
|
| 123 |
|
| 124 | |
| 125 | * stack_depot_print - Print a stack trace from stack depot
|
| 126 | *
|
| 127 | * @stack: Stack depot handle returned from stack_depot_save()
|
| 128 |
|
| 129 | void stack_depot_print(depot_stack_handle_t stack);
|
| 130 |
|
| 131 | |
| 132 | * stack_depot_snprint - Print a stack trace from stack depot into a buffer
|
| 133 | *
|
| 134 | * @handle: Stack depot handle returned from stack_depot_save()
|
| 135 | * @buf: Pointer to the print buffer
|
| 136 | * @size: Size of the print buffer
|
| 137 | * @spaces: Number of leading spaces to print
|
| 138 | *
|
| 139 | * Return: Number of bytes printed
|
| 140 |
|
| 141 | int stack_depot_snprint(depot_stack_handle_t handle, char *buf, size_t size,
|
| 142 | int spaces);
|
| 143 |
|
| 144 | |
| 145 | * stack_depot_set_extra_bits - Set extra bits in a stack depot handle
|
| 146 | *
|
| 147 | * @handle: Stack depot handle returned from stack_depot_save()
|
| 148 | * @extra_bits: Value to set the extra bits
|
| 149 | *
|
| 150 | * Return: Stack depot handle with extra bits set
|
| 151 | *
|
| 152 | * Stack depot handles have a few unused bits, which can be used for storing
|
| 153 | * user-specific information. These bits are transparent to the stack depot.
|
| 154 |
|
| 155 | depot_stack_handle_t __must_check stack_depot_set_extra_bits(
|
| 156 | depot_stack_handle_t handle, unsigned int extra_bits);
|
| 157 |
|
| 158 | |
| 159 | * stack_depot_get_extra_bits - Retrieve extra bits from a stack depot handle
|
| 160 | *
|
| 161 | * @handle: Stack depot handle with extra bits saved
|
| 162 | *
|
| 163 | * Return: Extra bits retrieved from the stack depot handle
|
| 164 |
|
| 165 | unsigned int stack_depot_get_extra_bits(depot_stack_handle_t handle);
|
| 166 |
|
| 167 | #endif
|