linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>,
	x86@kernel.org, Andy Lutomirski <luto@kernel.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Alexander Potapenko <glider@google.com>,
	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>,
	linux-arch@vger.kernel.org
Subject: [patch V2 02/29] stacktrace: Provide helpers for common stack trace operations
Date: Thu, 18 Apr 2019 10:41:21 +0200	[thread overview]
Message-ID: <20190418084253.234868907@linutronix.de> (raw)
In-Reply-To: 20190418084119.056416939@linutronix.de

All operations with stack traces are based on struct stack_trace. That's a
horrible construct as the struct is a kitchen sink for input and
output. Quite some usage sites embed it into their own data structures
which creates weird indirections.

There is absolutely no point in doing so. For all use cases a storage array
and the number of valid stack trace entries in the array is sufficient.

Provide helper functions which avoid the struct stack_trace indirection so
the usage sites can be cleaned up.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/stacktrace.h |   27 +++++++
 kernel/stacktrace.c        |  160 ++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 172 insertions(+), 15 deletions(-)

--- a/include/linux/stacktrace.h
+++ b/include/linux/stacktrace.h
@@ -3,11 +3,26 @@
 #define __LINUX_STACKTRACE_H
 
 #include <linux/types.h>
+#include <asm/errno.h>
 
 struct task_struct;
 struct pt_regs;
 
 #ifdef CONFIG_STACKTRACE
+void stack_trace_print(unsigned long *trace, unsigned int nr_entries,
+		       int spaces);
+int stack_trace_snprint(char *buf, size_t size, unsigned long *entries,
+			unsigned int nr_entries, int spaces);
+unsigned int stack_trace_save(unsigned long *store, unsigned int size,
+			      unsigned int skipnr);
+unsigned int stack_trace_save_tsk(struct task_struct *task,
+				  unsigned long *store, unsigned int size,
+				  unsigned int skipnr);
+unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store,
+				   unsigned int size, unsigned int skipnr);
+unsigned int stack_trace_save_user(unsigned long *store, unsigned int size);
+
+/* Internal interfaces. Do not use in generic code */
 struct stack_trace {
 	unsigned int nr_entries, max_entries;
 	unsigned long *entries;
@@ -41,4 +56,16 @@ extern void save_stack_trace_user(struct
 # define save_stack_trace_tsk_reliable(tsk, trace)	({ -ENOSYS; })
 #endif /* CONFIG_STACKTRACE */
 
+#if defined(CONFIG_STACKTRACE) && defined(CONFIG_HAVE_RELIABLE_STACKTRACE)
+int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store,
+				  unsigned int size);
+#else
+static inline int stack_trace_save_tsk_reliable(struct task_struct *tsk,
+						unsigned long *store,
+						unsigned int size)
+{
+	return -ENOSYS;
+}
+#endif
+
 #endif /* __LINUX_STACKTRACE_H */
--- a/kernel/stacktrace.c
+++ b/kernel/stacktrace.c
@@ -11,35 +11,52 @@
 #include <linux/kallsyms.h>
 #include <linux/stacktrace.h>
 
-void print_stack_trace(struct stack_trace *trace, int spaces)
+/**
+ * stack_trace_print - Print the entries in the stack trace
+ * @entries:	Pointer to storage array
+ * @nr_entries:	Number of entries in the storage array
+ * @spaces:	Number of leading spaces to print
+ */
+void stack_trace_print(unsigned long *entries, unsigned int nr_entries,
+		       int spaces)
 {
-	int i;
+	unsigned int i;
 
-	if (WARN_ON(!trace->entries))
+	if (WARN_ON(!entries))
 		return;
 
-	for (i = 0; i < trace->nr_entries; i++)
-		printk("%*c%pS\n", 1 + spaces, ' ', (void *)trace->entries[i]);
+	for (i = 0; i < nr_entries; i++)
+		printk("%*c%pS\n", 1 + spaces, ' ', (void *)entries[i]);
+}
+EXPORT_SYMBOL_GPL(stack_trace_print);
+
+void print_stack_trace(struct stack_trace *trace, int spaces)
+{
+	stack_trace_print(trace->entries, trace->nr_entries, spaces);
 }
 EXPORT_SYMBOL_GPL(print_stack_trace);
 
-int snprint_stack_trace(char *buf, size_t size,
-			struct stack_trace *trace, int spaces)
+/**
+ * stack_trace_snprint - Print the entries in the stack trace into a buffer
+ * @buf:	Pointer to the print buffer
+ * @size:	Size of the print buffer
+ * @entries:	Pointer to storage array
+ * @nr_entries:	Number of entries in the storage array
+ * @spaces:	Number of leading spaces to print
+ */
+int stack_trace_snprint(char *buf, size_t size, unsigned long *entries,
+			unsigned int nr_entries, int spaces)
 {
-	int i;
-	int generated;
-	int total = 0;
+	unsigned int generated, i, total = 0;
 
-	if (WARN_ON(!trace->entries))
+	if (WARN_ON(!entries))
 		return 0;
 
-	for (i = 0; i < trace->nr_entries; i++) {
+	for (i = 0; i < nr_entries; i++) {
 		generated = snprintf(buf, size, "%*c%pS\n", 1 + spaces, ' ',
-				     (void *)trace->entries[i]);
+				     (void *)entries[i]);
 
 		total += generated;
-
-		/* Assume that generated isn't a negative number */
 		if (generated >= size) {
 			buf += size;
 			size = 0;
@@ -51,6 +68,14 @@ int snprint_stack_trace(char *buf, size_
 
 	return total;
 }
+EXPORT_SYMBOL_GPL(stack_trace_snprint);
+
+int snprint_stack_trace(char *buf, size_t size,
+			struct stack_trace *trace, int spaces)
+{
+	return stack_trace_snprint(buf, size, trace->entries,
+				   trace->nr_entries, spaces);
+}
 EXPORT_SYMBOL_GPL(snprint_stack_trace);
 
 /*
@@ -77,3 +102,108 @@ save_stack_trace_tsk_reliable(struct tas
 	WARN_ONCE(1, KERN_INFO "save_stack_tsk_reliable() not implemented yet.\n");
 	return -ENOSYS;
 }
+
+/**
+ * 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
+ */
+unsigned int stack_trace_save(unsigned long *store, unsigned int size,
+			      unsigned int skipnr)
+{
+	struct stack_trace trace = {
+		.entries	= store,
+		.max_entries	= size,
+		.skip		= skipnr + 1,
+	};
+
+	save_stack_trace(&trace);
+	return trace.nr_entries;
+}
+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
+ */
+unsigned int stack_trace_save_tsk(struct task_struct *task,
+				  unsigned long *store, unsigned int size,
+				  unsigned int skipnr)
+{
+	struct stack_trace trace = {
+		.entries	= store,
+		.max_entries	= size,
+		.skip		= skipnr + 1,
+	};
+
+	save_stack_trace_tsk(task, &trace);
+	return trace.nr_entries;
+}
+
+/**
+ * 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
+ */
+unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store,
+				   unsigned int size, unsigned int skipnr)
+{
+	struct stack_trace trace = {
+		.entries	= store,
+		.max_entries	= size,
+		.skip		= skipnr,
+	};
+
+	save_stack_trace_regs(regs, &trace);
+	return trace.nr_entries;
+}
+
+#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)
+{
+	struct stack_trace trace = {
+		.entries	= store,
+		.max_entries	= size,
+	};
+	int ret = save_stack_trace_tsk_reliable(tsk, &trace);
+
+	return ret ? ret : trace.nr_entries;
+}
+#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
+ */
+unsigned int stack_trace_save_user(unsigned long *store, unsigned int size)
+{
+	struct stack_trace trace = {
+		.entries	= store,
+		.max_entries	= size,
+	};
+
+	save_stack_trace_user(&trace);
+	return trace.nr_entries;
+}
+#endif /* CONFIG_USER_STACKTRACE_SUPPORT */



  parent reply	other threads:[~2019-04-18  9:06 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 ` Thomas Gleixner [this message]
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
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=20190418084253.234868907@linutronix.de \
    --to=tglx@linutronix.de \
    --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=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).