Linux-BTRFS Archive on lore.kernel.org
 help / color / 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>,
	Christoph Lameter <cl@linux.com>,
	Pekka Enberg <penberg@kernel.org>,
	linux-mm@kvack.org, David Rientjes <rientjes@google.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>,
	Christoph Hellwig <hch@lst.de>,
	iommu@lists.linux-foundation.org,
	Robin Murphy <robin.murphy@arm.com>,
	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>, Daniel Vetter <daniel@ffwll.ch>,
	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>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	Tom Zanussi <tom.zanussi@linux.intel.com>,
	Miroslav Benes <mbenes@suse.cz>,
	linux-arch@vger.kernel.org
Subject: [patch V3 21/29] tracing: Use percpu stack trace buffer more intelligently
Date: Thu, 25 Apr 2019 11:45:14 +0200
Message-ID: <20190425094803.066064076@linutronix.de> (raw)
In-Reply-To: <20190425094453.875139013@linutronix.de>

The per cpu stack trace buffer usage pattern is odd at best. The buffer has
place for 512 stack trace entries on 64-bit and 1024 on 32-bit. When
interrupts or exceptions nest after the per cpu buffer was acquired the
stacktrace length is hardcoded to 8 entries. 512/1024 stack trace entries
in kernel stacks are unrealistic so the buffer is a complete waste.

Split the buffer into 4 nest levels, which are 128/256 entries per
level. This allows nesting contexts (interrupts, exceptions) to utilize the
cpu buffer for stack retrieval and avoids the fixed length allocation along
with the conditional execution pathes.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
V3: Limit to 4 nest levels and increase size per level.
---
 kernel/trace/trace.c |   77 +++++++++++++++++++++++++--------------------------
 1 file changed, 39 insertions(+), 38 deletions(-)

--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2749,12 +2749,21 @@ trace_function(struct trace_array *tr,
 
 #ifdef CONFIG_STACKTRACE
 
-#define FTRACE_STACK_MAX_ENTRIES (PAGE_SIZE / sizeof(unsigned long))
+/* Allow 4 levels of nesting: normal, softirq, irq, NMI */
+#define FTRACE_KSTACK_NESTING	4
+
+#define FTRACE_KSTACK_ENTRIES	(PAGE_SIZE / FTRACE_KSTACK_NESTING)
+
 struct ftrace_stack {
-	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
+	unsigned long		calls[FTRACE_KSTACK_ENTRIES];
+};
+
+
+struct ftrace_stacks {
+	struct ftrace_stack	stacks[FTRACE_KSTACK_NESTING];
 };
 
-static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);
+static DEFINE_PER_CPU(struct ftrace_stacks, ftrace_stacks);
 static DEFINE_PER_CPU(int, ftrace_stack_reserve);
 
 static void __ftrace_trace_stack(struct ring_buffer *buffer,
@@ -2763,10 +2772,11 @@ static void __ftrace_trace_stack(struct
 {
 	struct trace_event_call *call = &event_kernel_stack;
 	struct ring_buffer_event *event;
+	struct ftrace_stack *fstack;
 	struct stack_entry *entry;
 	struct stack_trace trace;
-	int use_stack;
-	int size = FTRACE_STACK_ENTRIES;
+	int size = FTRACE_KSTACK_ENTRIES;
+	int stackidx;
 
 	trace.nr_entries	= 0;
 	trace.skip		= skip;
@@ -2788,29 +2798,32 @@ static void __ftrace_trace_stack(struct
 	 */
 	preempt_disable_notrace();
 
-	use_stack = __this_cpu_inc_return(ftrace_stack_reserve);
+	stackidx = __this_cpu_inc_return(ftrace_stack_reserve);
+
+	/* This should never happen. If it does, yell once and skip */
+	if (WARN_ON_ONCE(stackidx >= FTRACE_KSTACK_NESTING))
+		goto out;
+
 	/*
-	 * We don't need any atomic variables, just a barrier.
-	 * If an interrupt comes in, we don't care, because it would
-	 * have exited and put the counter back to what we want.
-	 * We just need a barrier to keep gcc from moving things
-	 * around.
+	 * The above __this_cpu_inc_return() is 'atomic' cpu local. An
+	 * interrupt will either see the value pre increment or post
+	 * increment. If the interrupt happens pre increment it will have
+	 * restored the counter when it returns.  We just need a barrier to
+	 * keep gcc from moving things around.
 	 */
 	barrier();
-	if (use_stack == 1) {
-		trace.entries		= this_cpu_ptr(ftrace_stack.calls);
-		trace.max_entries	= FTRACE_STACK_MAX_ENTRIES;
-
-		if (regs)
-			save_stack_trace_regs(regs, &trace);
-		else
-			save_stack_trace(&trace);
-
-		if (trace.nr_entries > size)
-			size = trace.nr_entries;
-	} else
-		/* From now on, use_stack is a boolean */
-		use_stack = 0;
+
+	fstack = this_cpu_ptr(ftrace_stacks.stacks) + (stackidx - 1);
+	trace.entries		= fstack->calls;
+	trace.max_entries	= FTRACE_KSTACK_ENTRIES;
+
+	if (regs)
+		save_stack_trace_regs(regs, &trace);
+	else
+		save_stack_trace(&trace);
+
+	if (trace.nr_entries > size)
+		size = trace.nr_entries;
 
 	size *= sizeof(unsigned long);
 
@@ -2820,19 +2833,7 @@ static void __ftrace_trace_stack(struct
 		goto out;
 	entry = ring_buffer_event_data(event);
 
-	memset(&entry->caller, 0, size);
-
-	if (use_stack)
-		memcpy(&entry->caller, trace.entries,
-		       trace.nr_entries * sizeof(unsigned long));
-	else {
-		trace.max_entries	= FTRACE_STACK_ENTRIES;
-		trace.entries		= entry->caller;
-		if (regs)
-			save_stack_trace_regs(regs, &trace);
-		else
-			save_stack_trace(&trace);
-	}
+	memcpy(&entry->caller, trace.entries, size);
 
 	entry->size = trace.nr_entries;
 



  parent reply index

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-25  9:44 [patch V3 00/29] stacktrace: Consolidate stack trace usage Thomas Gleixner
2019-04-25  9:44 ` [patch V3 01/29] tracing: Cleanup stack trace code Thomas Gleixner
2019-04-25  9:44 ` [patch V3 02/29] stacktrace: Provide helpers for common stack trace operations Thomas Gleixner
2019-04-25  9:44 ` [patch V3 03/29] lib/stackdepot: Provide functions which operate on plain storage arrays Thomas Gleixner
2019-04-25  9:44 ` [patch V3 04/29] backtrace-test: Simplify stack trace handling Thomas Gleixner
2019-04-25  9:44 ` [patch V3 05/29] proc: Simplify task stack retrieval Thomas Gleixner
2019-04-25  9:44 ` [patch V3 06/29] latency_top: Simplify stack trace handling Thomas Gleixner
2019-04-25  9:45 ` [patch V3 07/29] mm/slub: Simplify stack trace retrieval Thomas Gleixner
2019-04-25  9:45 ` [patch V3 08/29] mm/kmemleak: Simplify stacktrace handling Thomas Gleixner
2019-04-25  9:45 ` [patch V3 09/29] mm/kasan: " Thomas Gleixner
2019-04-25  9:45 ` [patch V3 10/29] mm/page_owner: Simplify stack trace handling Thomas Gleixner
2019-04-25  9:45 ` [patch V3 11/29] fault-inject: Simplify stacktrace retrieval Thomas Gleixner
2019-04-25  9:45 ` [patch V3 12/29] dma/debug: Simplify stracktrace retrieval Thomas Gleixner
2019-04-25  9:45 ` [patch V3 13/29] btrfs: ref-verify: Simplify stack trace retrieval Thomas Gleixner
2019-04-25  9:45 ` [patch V3 14/29] dm bufio: " Thomas Gleixner
2019-04-25  9:45 ` [patch V3 15/29] dm persistent data: Simplify stack trace handling Thomas Gleixner
2019-04-25  9:45 ` [patch V3 16/29] drm: Simplify stacktrace handling Thomas Gleixner
2019-04-25  9:45 ` [patch V3 17/29] lockdep: Remove unused trace argument from print_circular_bug() Thomas Gleixner
2019-04-25  9:45 ` [patch V3 18/29] lockdep: Remove save argument from check_prev_add() Thomas Gleixner
2019-04-25 13:35   ` Peter Zijlstra
2019-04-25  9:45 ` [patch V3 19/29] lockdep: Simplify stack trace handling Thomas Gleixner
2019-04-25  9:45 ` [patch V3 20/29] tracing: Simplify stacktrace retrieval in histograms Thomas Gleixner
2019-04-25  9:45 ` Thomas Gleixner [this message]
2019-04-25 13:29   ` [patch V3 21/29] tracing: Use percpu stack trace buffer more intelligently Josh Poimboeuf
2019-04-25  9:45 ` [patch V3 22/29] tracing: Make ftrace_trace_userstack() static and conditional Thomas Gleixner
2019-04-25  9:45 ` [patch V3 23/29] tracing: Simplify stack trace retrieval Thomas Gleixner
2019-04-25  9:45 ` [patch V3 24/29] tracing: Remove the last struct stack_trace usage Thomas Gleixner
2019-04-25 13:30   ` Josh Poimboeuf
2019-04-25  9:45 ` [patch V3 25/29] livepatch: Simplify stack trace retrieval Thomas Gleixner
2019-04-25  9:45 ` [patch V3 26/29] stacktrace: Remove obsolete functions Thomas Gleixner
2019-04-25  9:45 ` [patch V3 27/29] lib/stackdepot: " Thomas Gleixner
2019-04-25  9:45 ` [patch V3 28/29] stacktrace: Provide common infrastructure Thomas Gleixner
2019-04-25  9:45 ` [patch V3 29/29] x86/stacktrace: Use " Thomas Gleixner
2019-04-25 10:09 ` [patch V3 00/29] stacktrace: Consolidate stack trace usage Ingo Molnar
2019-04-25 13:31 ` Josh Poimboeuf

Reply instructions:

You may reply publically 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=20190425094803.066064076@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=mbenes@suse.cz \
    --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=tom.zanussi@linux.intel.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

Linux-BTRFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-btrfs/0 linux-btrfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-btrfs linux-btrfs/ https://lore.kernel.org/linux-btrfs \
		linux-btrfs@vger.kernel.org linux-btrfs@archiver.kernel.org
	public-inbox-index linux-btrfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-btrfs


AGPL code for this site: git clone https://public-inbox.org/ public-inbox