linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: [for-next][PATCH 03/14] tracing: Allow trace_printk() to nest in other tracing code
Date: Fri, 24 Jan 2020 10:16:54 -0500	[thread overview]
Message-ID: <20200124151724.737628955@goodmis.org> (raw)
In-Reply-To: 20200124151651.852781301@goodmis.org

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

trace_printk() is used to debug the kernel which includes the tracing
infrastructure. But because it writes to the ring buffer, and so does much
of the tracing infrastructure, the ring buffer's recursive detection will
drop writes to the ring buffer that is in the same context as the current
write is happening (it allows interrupts to write when normal context is
writing, but wont let normal context write while normal context is writing).

This can cause confusion and think that the code is where the trace_printk()
exists is not hit. To solve this, up the recursive nesting of the ring
buffer when trace_printk() is called before it writes to the buffer itself.

Note, this does make it dangerous to use trace_printk() in the ring buffer
code itself, because this basically disables the recursion protection of
trace_printk() buffer writes. But as trace_printk() is only used for
debugging, and if this does occur, the developer will see the cause real
quick (recursive blowing up of the stack). Thus the developer can deal with
that. But having trace_printk() silently ignored is a much bigger problem,
and disabling recursive protection is a small price to pay to fix it.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 kernel/trace/trace.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 106bbc0988fe..2e1db19dce97 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -866,10 +866,13 @@ int __trace_puts(unsigned long ip, const char *str, int size)
 
 	local_save_flags(irq_flags);
 	buffer = global_trace.array_buffer.buffer;
+	ring_buffer_nest_start(buffer);
 	event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, 
 					    irq_flags, pc);
-	if (!event)
-		return 0;
+	if (!event) {
+		size = 0;
+		goto out;
+	}
 
 	entry = ring_buffer_event_data(event);
 	entry->ip = ip;
@@ -885,7 +888,8 @@ int __trace_puts(unsigned long ip, const char *str, int size)
 
 	__buffer_unlock_commit(buffer, event);
 	ftrace_trace_stack(&global_trace, buffer, irq_flags, 4, pc, NULL);
-
+ out:
+	ring_buffer_nest_end(buffer);
 	return size;
 }
 EXPORT_SYMBOL_GPL(__trace_puts);
@@ -902,6 +906,7 @@ int __trace_bputs(unsigned long ip, const char *str)
 	struct bputs_entry *entry;
 	unsigned long irq_flags;
 	int size = sizeof(struct bputs_entry);
+	int ret = 0;
 	int pc;
 
 	if (!(global_trace.trace_flags & TRACE_ITER_PRINTK))
@@ -914,10 +919,12 @@ int __trace_bputs(unsigned long ip, const char *str)
 
 	local_save_flags(irq_flags);
 	buffer = global_trace.array_buffer.buffer;
+
+	ring_buffer_nest_start(buffer);
 	event = __trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size,
 					    irq_flags, pc);
 	if (!event)
-		return 0;
+		goto out;
 
 	entry = ring_buffer_event_data(event);
 	entry->ip			= ip;
@@ -926,7 +933,10 @@ int __trace_bputs(unsigned long ip, const char *str)
 	__buffer_unlock_commit(buffer, event);
 	ftrace_trace_stack(&global_trace, buffer, irq_flags, 4, pc, NULL);
 
-	return 1;
+	ret = 1;
+ out:
+	ring_buffer_nest_end(buffer);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(__trace_bputs);
 
@@ -3225,6 +3235,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
 	local_save_flags(flags);
 	size = sizeof(*entry) + sizeof(u32) * len;
 	buffer = tr->array_buffer.buffer;
+	ring_buffer_nest_start(buffer);
 	event = __trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size,
 					    flags, pc);
 	if (!event)
@@ -3240,6 +3251,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
 	}
 
 out:
+	ring_buffer_nest_end(buffer);
 	put_trace_buf();
 
 out_nobuffer:
@@ -3282,6 +3294,7 @@ __trace_array_vprintk(struct trace_buffer *buffer,
 
 	local_save_flags(flags);
 	size = sizeof(*entry) + len + 1;
+	ring_buffer_nest_start(buffer);
 	event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, size,
 					    flags, pc);
 	if (!event)
@@ -3296,6 +3309,7 @@ __trace_array_vprintk(struct trace_buffer *buffer,
 	}
 
 out:
+	ring_buffer_nest_end(buffer);
 	put_trace_buf();
 
 out_nobuffer:
-- 
2.24.1



  parent reply	other threads:[~2020-01-24 15:18 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-24 15:16 [for-next][PATCH 00/14] tracing: More updates for 5.6 Steven Rostedt
2020-01-24 15:16 ` [for-next][PATCH 01/14] ring-bufer: kernel-doc warning fixes Steven Rostedt
2020-01-24 15:16 ` [for-next][PATCH 02/14] ring-buffer: Fix kernel doc for rb_update_event() Steven Rostedt
2020-01-24 15:16 ` Steven Rostedt [this message]
2020-01-24 15:16 ` [for-next][PATCH 04/14] ftrace: Remove abandoned macros Steven Rostedt
2020-01-24 15:16 ` [for-next][PATCH 05/14] ftrace: Remove NR_TO_INIT macro Steven Rostedt
2020-01-24 15:16 ` [for-next][PATCH 06/14] bootconfig: Fix Kconfig help message for BOOT_CONFIG Steven Rostedt
2020-01-24 15:16 ` [for-next][PATCH 07/14] Documentation: bootconfig: Fix typos in bootconfig documentation Steven Rostedt
2020-01-24 15:16 ` [for-next][PATCH 08/14] Documentation: tracing: Fix typos in boot-time tracing documentation Steven Rostedt
2020-01-24 15:17 ` [for-next][PATCH 09/14] tools: bootconfig: Fix spelling mistake "faile" -> "failed" Steven Rostedt
2020-01-24 15:17 ` [for-next][PATCH 10/14] ring-buffer: Remove abandoned macro RB_MISSED_FLAGS Steven Rostedt
2020-01-24 15:17 ` [for-next][PATCH 11/14] tracing: Remove unused TRACE_SEQ_BUF_USED Steven Rostedt
2020-01-24 15:17 ` [for-next][PATCH 12/14] tracing/boot: Fix an IS_ERR() vs NULL bug Steven Rostedt
2020-01-24 15:17 ` [for-next][PATCH 13/14] tracing: Fix uninitialized buffer var on early exit to trace_vbprintk() Steven Rostedt
2020-01-24 15:17 ` [for-next][PATCH 14/14] trace/kprobe: Remove unused MAX_KPROBE_CMDLINE_SIZE Steven Rostedt

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=20200124151724.737628955@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@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).