Commit-ID: c0cfc337264c5e02e0bc79de6b62857999588879 Gitweb: https://git.kernel.org/tip/c0cfc337264c5e02e0bc79de6b62857999588879 Author: Thomas Gleixner <tglx@xxxxxxxxxxxxx> AuthorDate: Thu, 25 Apr 2019 11:44:56 +0200 Committer: Thomas Gleixner <tglx@xxxxxxxxxxxxx> CommitDate: Mon, 29 Apr 2019 12:37:47 +0200 lib/stackdepot: Provide functions which operate on plain storage arrays The struct stack_trace indirection in the stack depot functions is a truly pointless excercise which requires horrible code at the callsites. Provide interfaces based on plain storage arrays. Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Reviewed-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx> Acked-by: Alexander Potapenko <glider@xxxxxxxxxx> Cc: Andy Lutomirski <luto@xxxxxxxxxx> Cc: Steven Rostedt <rostedt@xxxxxxxxxxx> Cc: Alexey Dobriyan <adobriyan@xxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Christoph Lameter <cl@xxxxxxxxx> Cc: Pekka Enberg <penberg@xxxxxxxxxx> Cc: linux-mm@xxxxxxxxx Cc: David Rientjes <rientjes@xxxxxxxxxx> Cc: Catalin Marinas <catalin.marinas@xxxxxxx> Cc: Dmitry Vyukov <dvyukov@xxxxxxxxxx> Cc: Andrey Ryabinin <aryabinin@xxxxxxxxxxxxx> Cc: kasan-dev@xxxxxxxxxxxxxxxx Cc: Mike Rapoport <rppt@xxxxxxxxxxxxxxxxxx> Cc: Akinobu Mita <akinobu.mita@xxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx Cc: Robin Murphy <robin.murphy@xxxxxxx> Cc: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx> Cc: Johannes Thumshirn <jthumshirn@xxxxxxx> Cc: David Sterba <dsterba@xxxxxxxx> Cc: Chris Mason <clm@xxxxxx> Cc: Josef Bacik <josef@xxxxxxxxxxxxxx> Cc: linux-btrfs@xxxxxxxxxxxxxxx Cc: dm-devel@xxxxxxxxxx Cc: Mike Snitzer <snitzer@xxxxxxxxxx> Cc: Alasdair Kergon <agk@xxxxxxxxxx> Cc: Daniel Vetter <daniel@xxxxxxxx> Cc: intel-gfx@xxxxxxxxxxxxxxxxxxxxx Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx Cc: David Airlie <airlied@xxxxxxxx> Cc: Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx> Cc: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> Cc: Tom Zanussi <tom.zanussi@xxxxxxxxxxxxxxx> Cc: Miroslav Benes <mbenes@xxxxxxx> Cc: linux-arch@xxxxxxxxxxxxxxx Link: https://lkml.kernel.org/r/20190425094801.414574828@xxxxxxxxxxxxx --- include/linux/stackdepot.h | 4 +++ lib/stackdepot.c | 70 +++++++++++++++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/include/linux/stackdepot.h b/include/linux/stackdepot.h index 7978b3e2c1e1..4297c6d2991d 100644 --- a/include/linux/stackdepot.h +++ b/include/linux/stackdepot.h @@ -26,7 +26,11 @@ typedef u32 depot_stack_handle_t; struct stack_trace; depot_stack_handle_t depot_save_stack(struct stack_trace *trace, gfp_t flags); +depot_stack_handle_t stack_depot_save(unsigned long *entries, + unsigned int nr_entries, gfp_t gfp_flags); void depot_fetch_stack(depot_stack_handle_t handle, struct stack_trace *trace); +unsigned int stack_depot_fetch(depot_stack_handle_t handle, + unsigned long **entries); #endif diff --git a/lib/stackdepot.c b/lib/stackdepot.c index e513459a5601..e84f8e58495c 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -194,40 +194,60 @@ static inline struct stack_record *find_stack(struct stack_record *bucket, return NULL; } -void depot_fetch_stack(depot_stack_handle_t handle, struct stack_trace *trace) +/** + * stack_depot_fetch - Fetch stack entries from a depot + * + * @handle: Stack depot handle which was returned from + * stack_depot_save(). + * @entries: Pointer to store the entries address + * + * Return: The number of trace entries for this depot. + */ +unsigned int stack_depot_fetch(depot_stack_handle_t handle, + unsigned long **entries) { union handle_parts parts = { .handle = handle }; void *slab = stack_slabs[parts.slabindex]; size_t offset = parts.offset << STACK_ALLOC_ALIGN; struct stack_record *stack = slab + offset; - trace->nr_entries = trace->max_entries = stack->size; - trace->entries = stack->entries; - trace->skip = 0; + *entries = stack->entries; + return stack->size; +} +EXPORT_SYMBOL_GPL(stack_depot_fetch); + +void depot_fetch_stack(depot_stack_handle_t handle, struct stack_trace *trace) +{ + unsigned int nent = stack_depot_fetch(handle, &trace->entries); + + trace->max_entries = trace->nr_entries = nent; } EXPORT_SYMBOL_GPL(depot_fetch_stack); /** - * depot_save_stack - save stack in a stack depot. - * @trace - the stacktrace to save. - * @alloc_flags - flags for allocating additional memory if required. + * 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 * - * Returns the handle of the stack struct stored in depot. + * Return: The handle of the stack struct stored in depot */ -depot_stack_handle_t depot_save_stack(struct stack_trace *trace, - gfp_t alloc_flags) +depot_stack_handle_t stack_depot_save(unsigned long *entries, + unsigned int nr_entries, + gfp_t alloc_flags) { - u32 hash; - depot_stack_handle_t retval = 0; struct stack_record *found = NULL, **bucket; - unsigned long flags; + depot_stack_handle_t retval = 0; struct page *page = NULL; void *prealloc = NULL; + unsigned long flags; + u32 hash; - if (unlikely(trace->nr_entries == 0)) + if (unlikely(nr_entries == 0)) goto fast_exit; - hash = hash_stack(trace->entries, trace->nr_entries); + hash = hash_stack(entries, nr_entries); bucket = &stack_table[hash & STACK_HASH_MASK]; /* @@ -235,8 +255,8 @@ depot_stack_handle_t depot_save_stack(struct stack_trace *trace, * The smp_load_acquire() here pairs with smp_store_release() to * |bucket| below. */ - found = find_stack(smp_load_acquire(bucket), trace->entries, - trace->nr_entries, hash); + found = find_stack(smp_load_acquire(bucket), entries, + nr_entries, hash); if (found) goto exit; @@ -264,10 +284,10 @@ depot_stack_handle_t depot_save_stack(struct stack_trace *trace, spin_lock_irqsave(&depot_lock, flags); - found = find_stack(*bucket, trace->entries, trace->nr_entries, hash); + found = find_stack(*bucket, entries, nr_entries, hash); if (!found) { struct stack_record *new = - depot_alloc_stack(trace->entries, trace->nr_entries, + depot_alloc_stack(entries, nr_entries, hash, &prealloc, alloc_flags); if (new) { new->next = *bucket; @@ -297,4 +317,16 @@ exit: fast_exit: return retval; } +EXPORT_SYMBOL_GPL(stack_depot_save); + +/** + * depot_save_stack - save stack in a stack depot. + * @trace - the stacktrace to save. + * @alloc_flags - flags for allocating additional memory if required. + */ +depot_stack_handle_t depot_save_stack(struct stack_trace *trace, + gfp_t alloc_flags) +{ + return stack_depot_save(trace->entries, trace->nr_entries, alloc_flags); +} EXPORT_SYMBOL_GPL(depot_save_stack);
![]() |