mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
lib/stackdepot: introduce __stack_depot_save()
Add __stack_depot_save(), which provides more fine-grained control over stackdepot's memory allocation behaviour, in case stackdepot runs out of "stack slabs". Normally stackdepot uses alloc_pages() in case it runs out of space; passing can_alloc==false to __stack_depot_save() prohibits this, at the cost of more likely failure to record a stack trace. Link: https://lkml.kernel.org/r/20210913112609.2651084-4-elver@google.com Signed-off-by: Marco Elver <elver@google.com> Tested-by: Shuah Khan <skhan@linuxfoundation.org> Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com> Cc: Alexander Potapenko <glider@google.com> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org> Cc: Lai Jiangshan <jiangshanlai@gmail.com> Cc: Taras Madan <tarasmadan@google.com> Cc: Tejun Heo <tj@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vijayanand Jitta <vjitta@codeaurora.org> Cc: Vinayak Menon <vinmenon@codeaurora.org> Cc: Walter Wu <walter-zh.wu@mediatek.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
7f2b8818ea
commit
11ac25c62c
@@ -15,6 +15,10 @@
|
|||||||
|
|
||||||
typedef u32 depot_stack_handle_t;
|
typedef u32 depot_stack_handle_t;
|
||||||
|
|
||||||
|
depot_stack_handle_t __stack_depot_save(unsigned long *entries,
|
||||||
|
unsigned int nr_entries,
|
||||||
|
gfp_t gfp_flags, bool can_alloc);
|
||||||
|
|
||||||
depot_stack_handle_t stack_depot_save(unsigned long *entries,
|
depot_stack_handle_t stack_depot_save(unsigned long *entries,
|
||||||
unsigned int nr_entries, gfp_t gfp_flags);
|
unsigned int nr_entries, gfp_t gfp_flags);
|
||||||
|
|
||||||
|
@@ -248,17 +248,28 @@ unsigned int stack_depot_fetch(depot_stack_handle_t handle,
|
|||||||
EXPORT_SYMBOL_GPL(stack_depot_fetch);
|
EXPORT_SYMBOL_GPL(stack_depot_fetch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stack_depot_save - Save a stack trace from an array
|
* __stack_depot_save - Save a stack trace from an array
|
||||||
*
|
*
|
||||||
* @entries: Pointer to storage array
|
* @entries: Pointer to storage array
|
||||||
* @nr_entries: Size of the storage array
|
* @nr_entries: Size of the storage array
|
||||||
* @alloc_flags: Allocation gfp flags
|
* @alloc_flags: Allocation gfp flags
|
||||||
|
* @can_alloc: Allocate stack slabs (increased chance of failure if false)
|
||||||
*
|
*
|
||||||
* Return: The handle of the stack struct stored in depot
|
* Saves a stack trace from @entries array of size @nr_entries. If @can_alloc is
|
||||||
|
* %true, is allowed to replenish the stack slab pool in case no space is left
|
||||||
|
* (allocates using GFP flags of @alloc_flags). If @can_alloc is %false, avoids
|
||||||
|
* any allocations and will fail if no space is left to store the stack trace.
|
||||||
|
*
|
||||||
|
* Context: Any context, but setting @can_alloc to %false is required if
|
||||||
|
* alloc_pages() cannot be used from the current context. Currently
|
||||||
|
* this is the case from contexts where neither %GFP_ATOMIC nor
|
||||||
|
* %GFP_NOWAIT can be used (NMI, raw_spin_lock).
|
||||||
|
*
|
||||||
|
* Return: The handle of the stack struct stored in depot, 0 on failure.
|
||||||
*/
|
*/
|
||||||
depot_stack_handle_t stack_depot_save(unsigned long *entries,
|
depot_stack_handle_t __stack_depot_save(unsigned long *entries,
|
||||||
unsigned int nr_entries,
|
unsigned int nr_entries,
|
||||||
gfp_t alloc_flags)
|
gfp_t alloc_flags, bool can_alloc)
|
||||||
{
|
{
|
||||||
struct stack_record *found = NULL, **bucket;
|
struct stack_record *found = NULL, **bucket;
|
||||||
depot_stack_handle_t retval = 0;
|
depot_stack_handle_t retval = 0;
|
||||||
@@ -291,7 +302,7 @@ depot_stack_handle_t stack_depot_save(unsigned long *entries,
|
|||||||
* The smp_load_acquire() here pairs with smp_store_release() to
|
* The smp_load_acquire() here pairs with smp_store_release() to
|
||||||
* |next_slab_inited| in depot_alloc_stack() and init_stack_slab().
|
* |next_slab_inited| in depot_alloc_stack() and init_stack_slab().
|
||||||
*/
|
*/
|
||||||
if (unlikely(!smp_load_acquire(&next_slab_inited))) {
|
if (unlikely(can_alloc && !smp_load_acquire(&next_slab_inited))) {
|
||||||
/*
|
/*
|
||||||
* Zero out zone modifiers, as we don't have specific zone
|
* Zero out zone modifiers, as we don't have specific zone
|
||||||
* requirements. Keep the flags related to allocation in atomic
|
* requirements. Keep the flags related to allocation in atomic
|
||||||
@@ -339,6 +350,26 @@ exit:
|
|||||||
fast_exit:
|
fast_exit:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(__stack_depot_save);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stack_depot_save - Save a stack trace from an array
|
||||||
|
*
|
||||||
|
* @entries: Pointer to storage array
|
||||||
|
* @nr_entries: Size of the storage array
|
||||||
|
* @alloc_flags: Allocation gfp flags
|
||||||
|
*
|
||||||
|
* Context: Contexts where allocations via alloc_pages() are allowed.
|
||||||
|
* See __stack_depot_save() for more details.
|
||||||
|
*
|
||||||
|
* Return: The handle of the stack struct stored in depot, 0 on failure.
|
||||||
|
*/
|
||||||
|
depot_stack_handle_t stack_depot_save(unsigned long *entries,
|
||||||
|
unsigned int nr_entries,
|
||||||
|
gfp_t alloc_flags)
|
||||||
|
{
|
||||||
|
return __stack_depot_save(entries, nr_entries, alloc_flags, true);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL_GPL(stack_depot_save);
|
EXPORT_SYMBOL_GPL(stack_depot_save);
|
||||||
|
|
||||||
static inline int in_irqentry_text(unsigned long ptr)
|
static inline int in_irqentry_text(unsigned long ptr)
|
||||||
|
Reference in New Issue
Block a user