Commit 505be481 authored by Imran Khan's avatar Imran Khan Committed by Linus Torvalds
Browse files

lib, stackdepot: add helper to print stack entries

To print a stack entries, users of stackdepot, first use stack_depot_fetch
to get a list of stack entries and then use stack_trace_print to print
this list.  Provide a helper in stackdepot to print stack entries based on
stackdepot handle.  Also change above mentioned users to use this helper.

Link: https://lkml.kernel.org/r/20210915014806.3206938-3-imran.f.khan@oracle.com


Signed-off-by: default avatarImran Khan <imran.f.khan@oracle.com>
Suggested-by: default avatarVlastimil Babka <vbabka@suse.cz>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
Reviewed-by: default avatarAlexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: David Airlie <airlied@linux.ie>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4d4712c1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ depot_stack_handle_t stack_depot_save(unsigned long *entries,
unsigned int stack_depot_fetch(depot_stack_handle_t handle,
			       unsigned long **entries);

void stack_depot_print(depot_stack_handle_t stack);

#ifdef CONFIG_STACKDEPOT
int stack_depot_init(void);
#else
+18 −0
Original line number Diff line number Diff line
@@ -213,6 +213,24 @@ static inline struct stack_record *find_stack(struct stack_record *bucket,
	return NULL;
}

/**
 * stack_depot_print - print stack entries from a depot
 *
 * @stack:		Stack depot handle which was returned from
 *			stack_depot_save().
 *
 */
void stack_depot_print(depot_stack_handle_t stack)
{
	unsigned long *entries;
	unsigned int nr_entries;

	nr_entries = stack_depot_fetch(stack, &entries);
	if (nr_entries > 0)
		stack_trace_print(entries, nr_entries, 0);
}
EXPORT_SYMBOL_GPL(stack_depot_print);

/**
 * stack_depot_fetch - Fetch stack entries from a depot
 *
+3 −12
Original line number Diff line number Diff line
@@ -132,20 +132,11 @@ static void end_report(unsigned long *flags, unsigned long addr)
	kasan_enable_current();
}

static void print_stack(depot_stack_handle_t stack)
{
	unsigned long *entries;
	unsigned int nr_entries;

	nr_entries = stack_depot_fetch(stack, &entries);
	stack_trace_print(entries, nr_entries, 0);
}

static void print_track(struct kasan_track *track, const char *prefix)
{
	pr_err("%s by task %u:\n", prefix, track->pid);
	if (track->stack) {
		print_stack(track->stack);
		stack_depot_print(track->stack);
	} else {
		pr_err("(stack is not available)\n");
	}
@@ -214,12 +205,12 @@ static void describe_object_stacks(struct kmem_cache *cache, void *object,
		return;
	if (alloc_meta->aux_stack[0]) {
		pr_err("Last potentially related work creation:\n");
		print_stack(alloc_meta->aux_stack[0]);
		stack_depot_print(alloc_meta->aux_stack[0]);
		pr_err("\n");
	}
	if (alloc_meta->aux_stack[1]) {
		pr_err("Second to last potentially related work creation:\n");
		print_stack(alloc_meta->aux_stack[1]);
		stack_depot_print(alloc_meta->aux_stack[1]);
		pr_err("\n");
	}
#endif
+4 −9
Original line number Diff line number Diff line
@@ -394,8 +394,6 @@ void __dump_page_owner(const struct page *page)
	struct page_ext *page_ext = lookup_page_ext(page);
	struct page_owner *page_owner;
	depot_stack_handle_t handle;
	unsigned long *entries;
	unsigned int nr_entries;
	gfp_t gfp_mask;
	int mt;

@@ -423,20 +421,17 @@ void __dump_page_owner(const struct page *page)
		 page_owner->pid, page_owner->ts_nsec, page_owner->free_ts_nsec);

	handle = READ_ONCE(page_owner->handle);
	if (!handle) {
	if (!handle)
		pr_alert("page_owner allocation stack trace missing\n");
	} else {
		nr_entries = stack_depot_fetch(handle, &entries);
		stack_trace_print(entries, nr_entries, 0);
	}
	else
		stack_depot_print(handle);

	handle = READ_ONCE(page_owner->free_handle);
	if (!handle) {
		pr_alert("page_owner free stack trace missing\n");
	} else {
		nr_entries = stack_depot_fetch(handle, &entries);
		pr_alert("page last free stack trace:\n");
		stack_trace_print(entries, nr_entries, 0);
		stack_depot_print(handle);
	}

	if (page_owner->last_migrate_reason != -1)