From: Mike Rapoport <rppt@linux.ibm.com>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
Josh Poimboeuf <jpoimboe@redhat.com>,
x86@kernel.org, Andy Lutomirski <luto@kernel.org>,
Steven Rostedt <rostedt@goodmis.org>,
Alexander Potapenko <glider@google.com>,
linux-arch@vger.kernel.org, Alexey Dobriyan <adobriyan@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
Pekka Enberg <penberg@kernel.org>,
linux-mm@kvack.org, David Rientjes <rientjes@google.com>,
Christoph Lameter <cl@linux.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Dmitry Vyukov <dvyukov@google.com>,
Andrey Ryabinin <aryabinin@virtuozzo.com>,
kasan-dev@googlegroups.com,
Mike Rapoport <rppt@linux.vnet.ibm.com>,
Akinobu Mita <akinobu.mita@gmail.com>,
iommu@lists.linux-foundation.org,
Robin Murphy <robin.murphy@arm.com>,
Christoph Hellwig <hch@lst.de>,
Marek Szyprowski <m.szyprowski@samsung.com>,
Johannes Thumshirn <jthumshirn@suse.de>,
David Sterba <dsterba@suse.com>, Chris Mason <clm@fb.com>,
Josef Bacik <josef@toxicpanda.com>,
linux-btrfs@vger.kernel.org, dm-devel@redhat.com,
Mike Snitzer <snitzer@redhat.com>,
Alasdair Kergon <agk@redhat.com>,
intel-gfx@lists.freedesktop.org,
Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
dri-devel@lists.freedesktop.org, David Airlie <airlied@linux.ie>,
Jani Nikula <jani.nikula@linux.intel.com>,
Daniel Vetter <daniel@ffwll.ch>,
Rodrigo Vivi <rodrigo.vivi@intel.com>
Subject: Re: [patch V2 28/29] stacktrace: Provide common infrastructure
Date: Thu, 18 Apr 2019 14:52:07 +0300 [thread overview]
Message-ID: <20190418115207.GB13304@rapoport-lnx> (raw)
In-Reply-To: <20190418084255.652003111@linutronix.de>
On Thu, Apr 18, 2019 at 10:41:47AM +0200, Thomas Gleixner wrote:
> All architectures which support stacktrace carry duplicated code and
> do the stack storage and filtering at the architecture side.
>
> Provide a consolidated interface with a callback function for consuming the
> stack entries provided by the architecture specific stack walker. This
> removes lots of duplicated code and allows to implement better filtering
> than 'skip number of entries' in the future without touching any
> architecture specific code.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-arch@vger.kernel.org
> ---
> include/linux/stacktrace.h | 38 +++++++++
> kernel/stacktrace.c | 173 +++++++++++++++++++++++++++++++++++++++++++++
> lib/Kconfig | 4 +
> 3 files changed, 215 insertions(+)
>
> --- a/include/linux/stacktrace.h
> +++ b/include/linux/stacktrace.h
> @@ -23,6 +23,43 @@ unsigned int stack_trace_save_regs(struc
> unsigned int stack_trace_save_user(unsigned long *store, unsigned int size);
>
> /* Internal interfaces. Do not use in generic code */
> +#ifdef CONFIG_ARCH_STACKWALK
> +
> +/**
> + * stack_trace_consume_fn - Callback for arch_stack_walk()
> + * @cookie: Caller supplied pointer handed back by arch_stack_walk()
> + * @addr: The stack entry address to consume
> + * @reliable: True when the stack entry is reliable. Required by
> + * some printk based consumers.
> + *
> + * Returns: True, if the entry was consumed or skipped
> + * False, if there is no space left to store
> + */
> +typedef bool (*stack_trace_consume_fn)(void *cookie, unsigned long addr,
> + bool reliable);
> +/**
> + * arch_stack_walk - Architecture specific function to walk the stack
> +
Nit: no '*' at line beginning makes kernel-doc unhappy
> + * @consume_entry: Callback which is invoked by the architecture code for
> + * each entry.
> + * @cookie: Caller supplied pointer which is handed back to
> + * @consume_entry
> + * @task: Pointer to a task struct, can be NULL
> + * @regs: Pointer to registers, can be NULL
> + *
> + * @task @regs:
> + * NULL NULL Stack trace from current
> + * task NULL Stack trace from task (can be current)
> + * NULL regs Stack trace starting on regs->stackpointer
This will render as a single line with 'make *docs'.
Adding line separators makes this actually a table in the generated docs:
* ============ ======= ============================================
* task regs
* ============ ======= ============================================
* NULL NULL Stack trace from current
* task NULL Stack trace from task (can be current)
* NULL regs Stack trace starting on regs->stackpointer
* ============ ======= ============================================
> + */
> +void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
> + struct task_struct *task, struct pt_regs *regs);
> +int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, void *cookie,
> + struct task_struct *task);
> +void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
> + const struct pt_regs *regs);
> +
> +#else /* CONFIG_ARCH_STACKWALK */
> struct stack_trace {
> unsigned int nr_entries, max_entries;
> unsigned long *entries;
> @@ -37,6 +74,7 @@ extern void save_stack_trace_tsk(struct
> extern int save_stack_trace_tsk_reliable(struct task_struct *tsk,
> struct stack_trace *trace);
> extern void save_stack_trace_user(struct stack_trace *trace);
> +#endif /* !CONFIG_ARCH_STACKWALK */
> #endif /* CONFIG_STACKTRACE */
>
> #if defined(CONFIG_STACKTRACE) && defined(CONFIG_HAVE_RELIABLE_STACKTRACE)
> --- a/kernel/stacktrace.c
> +++ b/kernel/stacktrace.c
> @@ -5,6 +5,8 @@
> *
> * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
> */
> +#include <linux/sched/task_stack.h>
> +#include <linux/sched/debug.h>
> #include <linux/sched.h>
> #include <linux/kernel.h>
> #include <linux/export.h>
> @@ -64,6 +66,175 @@ int stack_trace_snprint(char *buf, size_
> }
> EXPORT_SYMBOL_GPL(stack_trace_snprint);
>
> +#ifdef CONFIG_ARCH_STACKWALK
> +
> +struct stacktrace_cookie {
> + unsigned long *store;
> + unsigned int size;
> + unsigned int skip;
> + unsigned int len;
> +};
> +
> +static bool stack_trace_consume_entry(void *cookie, unsigned long addr,
> + bool reliable)
> +{
> + struct stacktrace_cookie *c = cookie;
> +
> + if (c->len >= c->size)
> + return false;
> +
> + if (c->skip > 0) {
> + c->skip--;
> + return true;
> + }
> + c->store[c->len++] = addr;
> + return c->len < c->size;
> +}
> +
> +static bool stack_trace_consume_entry_nosched(void *cookie, unsigned long addr,
> + bool reliable)
> +{
> + if (in_sched_functions(addr))
> + return true;
> + return stack_trace_consume_entry(cookie, addr, reliable);
> +}
> +
> +/**
> + * stack_trace_save - Save a stack trace into a storage array
> + * @store: Pointer to storage array
> + * @size: Size of the storage array
> + * @skipnr: Number of entries to skip at the start of the stack trace
> + *
> + * Returns number of entries stored.
Can you please s/Returns/Return:/ so that kernel-doc will recognize this as
return section.
This is relevant for other comments below as well.
> + */
> +unsigned int stack_trace_save(unsigned long *store, unsigned int size,
> + unsigned int skipnr)
> +{
> + stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
> + struct stacktrace_cookie c = {
> + .store = store,
> + .size = size,
> + .skip = skipnr + 1,
> + };
> +
> + arch_stack_walk(consume_entry, &c, current, NULL);
> + return c.len;
> +}
> +EXPORT_SYMBOL_GPL(stack_trace_save);
> +
> +/**
> + * stack_trace_save_tsk - Save a task stack trace into a storage array
> + * @task: The task to examine
> + * @store: Pointer to storage array
> + * @size: Size of the storage array
> + * @skipnr: Number of entries to skip at the start of the stack trace
> + *
> + * Returns number of entries stored.
> + */
> +unsigned int stack_trace_save_tsk(struct task_struct *tsk, unsigned long *store,
> + unsigned int size, unsigned int skipnr)
> +{
> + stack_trace_consume_fn consume_entry = stack_trace_consume_entry_nosched;
> + struct stacktrace_cookie c = {
> + .store = store,
> + .size = size,
> + .skip = skipnr + 1,
> + };
> +
> + if (!try_get_task_stack(tsk))
> + return 0;
> +
> + arch_stack_walk(consume_entry, &c, tsk, NULL);
> + put_task_stack(tsk);
> + return c.len;
> +}
> +
> +/**
> + * stack_trace_save_regs - Save a stack trace based on pt_regs into a storage array
> + * @regs: Pointer to pt_regs to examine
> + * @store: Pointer to storage array
> + * @size: Size of the storage array
> + * @skipnr: Number of entries to skip at the start of the stack trace
> + *
> + * Returns number of entries stored.
> + */
> +unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store,
> + unsigned int size, unsigned int skipnr)
> +{
> + stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
> + struct stacktrace_cookie c = {
> + .store = store,
> + .size = size,
> + .skip = skipnr,
> + };
> +
> + arch_stack_walk(consume_entry, &c, current, regs);
> + return c.len;
> +}
> +
> +#ifdef CONFIG_HAVE_RELIABLE_STACKTRACE
> +/**
> + * stack_trace_save_tsk_reliable - Save task stack with verification
> + * @tsk: Pointer to the task to examine
> + * @store: Pointer to storage array
> + * @size: Size of the storage array
> + *
> + * Returns: An error if it detects any unreliable features of the
> + * stack. Otherwise it guarantees that the stack trace is
> + * reliable and returns the number of entries stored.
> + *
> + * If the task is not 'current', the caller *must* ensure the task is inactive.
> + */
> +int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store,
> + unsigned int size)
> +{
> + stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
> + struct stacktrace_cookie c = {
> + .store = store,
> + .size = size,
> + };
> + int ret;
> +
> + /*
> + * If the task doesn't have a stack (e.g., a zombie), the stack is
> + * "reliably" empty.
> + */
> + if (!try_get_task_stack(tsk))
> + return 0;
> +
> + ret = arch_stack_walk_reliable(consume_entry, &c, tsk);
> + put_task_stack(tsk);
> + return ret;
> +}
> +#endif
> +
> +#ifdef CONFIG_USER_STACKTRACE_SUPPORT
> +/**
> + * stack_trace_save_user - Save a user space stack trace into a storage array
> + * @store: Pointer to storage array
> + * @size: Size of the storage array
> + *
> + * Returns number of entries stored.
> + */
> +unsigned int stack_trace_save_user(unsigned long *store, unsigned int size)
> +{
> + stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
> + struct stacktrace_cookie c = {
> + .store = store,
> + .size = size,
> + };
> +
> + /* Trace user stack if not a kernel thread */
> + if (!current->mm)
> + return 0;
> +
> + arch_stack_walk_user(consume_entry, &c, task_pt_regs(current));
> + return c.len;
> +}
> +#endif
> +
> +#else /* CONFIG_ARCH_STACKWALK */
> +
> /*
> * Architectures that do not implement save_stack_trace_*()
> * get these weak aliases and once-per-bootup warnings
> @@ -193,3 +364,5 @@ unsigned int stack_trace_save_user(unsig
> return trace.nr_entries;
> }
> #endif /* CONFIG_USER_STACKTRACE_SUPPORT */
> +
> +#endif /* !CONFIG_ARCH_STACKWALK */
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -597,6 +597,10 @@ config ARCH_HAS_UACCESS_FLUSHCACHE
> config ARCH_HAS_UACCESS_MCSAFE
> bool
>
> +# Temporary. Goes away when all archs are cleaned up
> +config ARCH_STACKWALK
> + bool
> +
> config STACKDEPOT
> bool
> select STACKTRACE
>
>
--
Sincerely yours,
Mike.
next prev parent reply other threads:[~2019-04-18 11:52 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-18 8:41 [patch V2 00/29] stacktrace: Consolidate stack trace usage Thomas Gleixner
2019-04-18 8:41 ` [patch V2 01/29] tracing: Cleanup stack trace code Thomas Gleixner
2019-04-18 13:57 ` Josh Poimboeuf
2019-04-18 21:14 ` Thomas Gleixner
2019-04-18 21:24 ` Steven Rostedt
2019-04-18 21:50 ` Steven Rostedt
2019-04-18 22:19 ` Steven Rostedt
2019-04-18 22:44 ` Thomas Gleixner
2019-04-19 0:39 ` Steven Rostedt
2019-04-18 8:41 ` [patch V2 02/29] stacktrace: Provide helpers for common stack trace operations Thomas Gleixner
2019-04-18 8:41 ` [patch V2 03/29] lib/stackdepot: Provide functions which operate on plain storage arrays Thomas Gleixner
2019-04-18 11:51 ` Mike Rapoport
2019-04-18 11:58 ` Thomas Gleixner
2019-04-18 8:41 ` [patch V2 04/29] backtrace-test: Simplify stack trace handling Thomas Gleixner
2019-04-18 8:41 ` [patch V2 05/29] proc: Simplify task stack retrieval Thomas Gleixner
2019-04-18 8:41 ` [patch V2 06/29] latency_top: Simplify stack trace handling Thomas Gleixner
2019-04-18 8:41 ` [patch V2 07/29] mm/slub: Simplify stack trace retrieval Thomas Gleixner
2019-04-18 8:41 ` [patch V2 08/29] mm/kmemleak: Simplify stacktrace handling Thomas Gleixner
2019-04-18 15:17 ` Catalin Marinas
2019-04-18 8:41 ` [patch V2 09/29] mm/kasan: " Thomas Gleixner
2019-04-18 10:39 ` Andrey Ryabinin
2019-04-18 11:53 ` Thomas Gleixner
2019-04-18 8:41 ` [patch V2 10/29] mm/page_owner: Simplify stack trace handling Thomas Gleixner
2019-04-18 8:41 ` [patch V2 11/29] fault-inject: Simplify stacktrace retrieval Thomas Gleixner
2019-04-18 8:41 ` [patch V2 12/29] dma/debug: Simplify stracktrace retrieval Thomas Gleixner
2019-04-19 7:05 ` Christoph Hellwig
2019-04-18 8:41 ` [patch V2 13/29] btrfs: ref-verify: Simplify stack trace retrieval Thomas Gleixner
2019-04-18 8:41 ` [patch V2 14/29] dm bufio: " Thomas Gleixner
2019-04-18 10:44 ` Alexander Potapenko
2019-04-18 11:54 ` Thomas Gleixner
2019-04-18 12:11 ` Alexander Potapenko
2019-04-18 13:33 ` Steven Rostedt
2019-04-18 8:41 ` [patch V2 15/29] dm persistent data: Simplify stack trace handling Thomas Gleixner
2019-04-18 8:41 ` [patch V2 16/29] drm: Simplify stacktrace handling Thomas Gleixner
2019-04-23 7:36 ` Daniel Vetter
2019-04-18 8:41 ` [patch V2 17/29] lockdep: Remove unused trace argument from print_circular_bug() Thomas Gleixner
2019-04-18 8:41 ` [patch V2 18/29] lockdep: Move stack trace logic into check_prev_add() Thomas Gleixner
2019-04-24 19:45 ` Peter Zijlstra
2019-04-24 19:51 ` Thomas Gleixner
2019-04-18 8:41 ` [patch V2 19/29] lockdep: Simplify stack trace handling Thomas Gleixner
2019-04-24 19:45 ` Peter Zijlstra
2019-04-18 8:41 ` [patch V2 20/29] tracing: Simplify stacktrace retrieval in histograms Thomas Gleixner
2019-04-18 13:40 ` Steven Rostedt
2019-04-18 19:58 ` Tom Zanussi
2019-04-18 20:13 ` Steven Rostedt
2019-04-18 20:22 ` Tom Zanussi
2019-04-18 8:41 ` [patch V2 21/29] tracing: Use percpu stack trace buffer more intelligently Thomas Gleixner
2019-04-18 14:53 ` Steven Rostedt
2019-04-18 15:43 ` Thomas Gleixner
2019-04-18 15:46 ` Steven Rostedt
2019-04-18 8:41 ` [patch V2 22/29] tracing: Make ftrace_trace_userstack() static and conditional Thomas Gleixner
2019-04-19 13:28 ` Steven Rostedt
2019-04-18 8:41 ` [patch V2 23/29] tracing: Simplify stack trace retrieval Thomas Gleixner
2019-04-19 20:11 ` Steven Rostedt
2019-04-18 8:41 ` [patch V2 24/29] tracing: Remove the last struct stack_trace usage Thomas Gleixner
2019-04-19 20:11 ` Steven Rostedt
2019-04-18 8:41 ` [patch V2 25/29] livepatch: Simplify stack trace retrieval Thomas Gleixner
2019-04-23 8:18 ` Miroslav Benes
2019-04-18 8:41 ` [patch V2 26/29] stacktrace: Remove obsolete functions Thomas Gleixner
2019-04-18 8:41 ` [patch V2 27/29] lib/stackdepot: " Thomas Gleixner
2019-04-18 8:41 ` [patch V2 28/29] stacktrace: Provide common infrastructure Thomas Gleixner
2019-04-18 11:52 ` Mike Rapoport [this message]
2019-04-18 11:57 ` Thomas Gleixner
2019-04-18 14:52 ` Josh Poimboeuf
2019-04-18 15:42 ` Thomas Gleixner
2019-04-19 7:02 ` Peter Zijlstra
2019-04-19 15:50 ` Josh Poimboeuf
2019-04-19 7:18 ` Peter Zijlstra
2019-04-19 8:32 ` Thomas Gleixner
2019-04-19 9:07 ` Peter Zijlstra
2019-04-19 16:17 ` Josh Poimboeuf
2019-04-18 8:41 ` [patch V2 29/29] x86/stacktrace: Use " Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190418115207.GB13304@rapoport-lnx \
--to=rppt@linux.ibm.com \
--cc=adobriyan@gmail.com \
--cc=agk@redhat.com \
--cc=airlied@linux.ie \
--cc=akinobu.mita@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=aryabinin@virtuozzo.com \
--cc=catalin.marinas@arm.com \
--cc=cl@linux.com \
--cc=clm@fb.com \
--cc=daniel@ffwll.ch \
--cc=dm-devel@redhat.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=dsterba@suse.com \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=hch@lst.de \
--cc=intel-gfx@lists.freedesktop.org \
--cc=iommu@lists.linux-foundation.org \
--cc=jani.nikula@linux.intel.com \
--cc=joonas.lahtinen@linux.intel.com \
--cc=josef@toxicpanda.com \
--cc=jpoimboe@redhat.com \
--cc=jthumshirn@suse.de \
--cc=kasan-dev@googlegroups.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=luto@kernel.org \
--cc=m.szyprowski@samsung.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=penberg@kernel.org \
--cc=rientjes@google.com \
--cc=robin.murphy@arm.com \
--cc=rodrigo.vivi@intel.com \
--cc=rostedt@goodmis.org \
--cc=rppt@linux.vnet.ibm.com \
--cc=snitzer@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).