linux-rt-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Tom Zanussi <tom.zanussi@linux.intel.com>
Cc: tglx@linutronix.de, mhiramat@kernel.org, namhyung@kernel.org,
	vedang.patel@intel.com, bigeasy@linutronix.de,
	joel.opensrc@gmail.com, joelaf@google.com,
	mathieu.desnoyers@efficios.com, baohong.liu@intel.com,
	rajvi.jingar@intel.com, julia@ni.com, fengguang.wu@intel.com,
	linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org
Subject: Re: [PATCH v9 35/37] tracing: Increase trace_recursive_lock() limit for synthetic events
Date: Wed, 7 Feb 2018 20:55:01 -0500	[thread overview]
Message-ID: <20180207205501.2b19c8d6@gandalf.local.home> (raw)
In-Reply-To: <827fcc7a6840db06d196fc18905033d519681eff.1516069914.git.tom.zanussi@linux.intel.com>

[-- Attachment #1: Type: text/plain, Size: 584 bytes --]

On Mon, 15 Jan 2018 20:52:09 -0600
Tom Zanussi <tom.zanussi@linux.intel.com> wrote:

>  static __always_inline int
>  trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer)
>  {
> -	if (cpu_buffer->current_context >= 4)
> +	if (cpu_buffer->current_context >= 6)

I can't apply this patch because the new context counting broke tracing
suspend and resume because it depended on the context recursive locking.

Link: http://lkml.kernel.org/r/20180116020051.776011914@goodmis.org

I added the attached two patches which appear to do the job.

Let me know what you think.

-- Steve

[-- Attachment #2: 0001-ring-buffer-Add-nesting-for-adding-events-within-eve.patch --]
[-- Type: text/x-patch, Size: 4428 bytes --]

>From f932ff1d98c482716b4b71a5d76b2aa3d65f66f0 Mon Sep 17 00:00:00 2001
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Date: Wed, 7 Feb 2018 17:26:32 -0500
Subject: [PATCH] ring-buffer: Add nesting for adding events within events

The ring-buffer code has recusion protection in case tracing ends up tracing
itself, the ring-buffer will detect that it was called at the same context
(normal, softirq, interrupt or NMI), and not continue to record the event.

With the histogram synthetic events, they are called while tracing another
event at the same context. The recusion protection triggers because it
detects tracing at the same context and stops it.

Add ring_buffer_nest_start() and ring_buffer_nest_end() that will notify the
ring buffer that a trace is about to happen within another trace and that it
is intended, and not to trigger the recursion blocking.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 include/linux/ring_buffer.h |  3 +++
 kernel/trace/ring_buffer.c  | 57 ++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index b37a5df05e81..467db0a7b82d 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -117,6 +117,9 @@ int ring_buffer_unlock_commit(struct ring_buffer *buffer,
 int ring_buffer_write(struct ring_buffer *buffer,
 		      unsigned long length, void *data);
 
+void ring_buffer_nest_start(struct ring_buffer *buffer);
+void ring_buffer_nest_end(struct ring_buffer *buffer);
+
 struct ring_buffer_event *
 ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts,
 		 unsigned long *lost_events);
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 9c4d6cbfd258..d09e453b6c52 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -477,6 +477,7 @@ struct ring_buffer_per_cpu {
 	struct buffer_page		*reader_page;
 	unsigned long			lost_events;
 	unsigned long			last_overrun;
+	unsigned long			nest;
 	local_t				entries_bytes;
 	local_t				entries;
 	local_t				overrun;
@@ -2624,10 +2625,10 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer)
 		bit = pc & NMI_MASK ? RB_CTX_NMI :
 			pc & HARDIRQ_MASK ? RB_CTX_IRQ : RB_CTX_SOFTIRQ;
 
-	if (unlikely(val & (1 << bit)))
+	if (unlikely(val & (1 << (bit + cpu_buffer->nest))))
 		return 1;
 
-	val |= (1 << bit);
+	val |= (1 << (bit + cpu_buffer->nest));
 	cpu_buffer->current_context = val;
 
 	return 0;
@@ -2636,7 +2637,57 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer)
 static __always_inline void
 trace_recursive_unlock(struct ring_buffer_per_cpu *cpu_buffer)
 {
-	cpu_buffer->current_context &= cpu_buffer->current_context - 1;
+	cpu_buffer->current_context &=
+		cpu_buffer->current_context - (1 << cpu_buffer->nest);
+}
+
+/* The recursive locking above uses 4 bits */
+#define NESTED_BITS 4
+
+/**
+ * ring_buffer_nest_start - Allow to trace while nested
+ * @buffer: The ring buffer to modify
+ *
+ * The ring buffer has a safty mechanism to prevent recursion.
+ * But there may be a case where a trace needs to be done while
+ * tracing something else. In this case, calling this function
+ * will allow this function to nest within a currently active
+ * ring_buffer_lock_reserve().
+ *
+ * Call this function before calling another ring_buffer_lock_reserve() and
+ * call ring_buffer_nest_end() after the nested ring_buffer_unlock_commit().
+ */
+void ring_buffer_nest_start(struct ring_buffer *buffer)
+{
+	struct ring_buffer_per_cpu *cpu_buffer;
+	int cpu;
+
+	/* Enabled by ring_buffer_nest_end() */
+	preempt_disable_notrace();
+	cpu = raw_smp_processor_id();
+	cpu_buffer = buffer->buffers[cpu];
+	/* This is the shift value for the above recusive locking */
+	cpu_buffer->nest += NESTED_BITS;
+}
+
+/**
+ * ring_buffer_nest_end - Allow to trace while nested
+ * @buffer: The ring buffer to modify
+ *
+ * Must be called after ring_buffer_nest_start() and after the
+ * ring_buffer_unlock_commit().
+ */
+void ring_buffer_nest_end(struct ring_buffer *buffer)
+{
+	struct ring_buffer_per_cpu *cpu_buffer;
+	int cpu;
+
+	/* disabled by ring_buffer_nest_start() */
+	cpu = raw_smp_processor_id();
+	cpu_buffer = buffer->buffers[cpu];
+	/* This is the shift value for the above recusive locking */
+	cpu_buffer->nest -= NESTED_BITS;
+	preempt_enable_notrace();
 }
 
 /**
-- 
2.13.6


[-- Attachment #3: 0001-tracing-Use-the-ring-buffer-nesting-to-allow-synthet.patch --]
[-- Type: text/x-patch, Size: 1969 bytes --]

>From 92c571543120ffed5e725f5b57b9de0b535e9d0a Mon Sep 17 00:00:00 2001
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Date: Wed, 7 Feb 2018 17:29:46 -0500
Subject: [PATCH] tracing: Use the ring-buffer nesting to allow synthetic
 events to be traced

Synthetic events can be done within the recording of other events. Notify
the ring buffer via ring_buffer_nest_start() and ring_buffer_nest_end() that
this is intended and not to block it due to its recursion protection.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 kernel/trace/trace_events_hist.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index fdd5c6438d12..b87ea7421f3d 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -640,6 +640,7 @@ static notrace void trace_event_raw_event_synth(void *__data,
 	struct trace_event_file *trace_file = __data;
 	struct synth_trace_event *entry;
 	struct trace_event_buffer fbuffer;
+	struct ring_buffer *buffer;
 	struct synth_event *event;
 	unsigned int i, n_u64;
 	int fields_size = 0;
@@ -651,10 +652,17 @@ static notrace void trace_event_raw_event_synth(void *__data,
 
 	fields_size = event->n_u64 * sizeof(u64);
 
+	/*
+	 * Avoid ring buffer recursion detection, as this event
+	 * is being performed within another event.
+	 */
+	buffer = trace_file->tr->trace_buffer.buffer;
+	ring_buffer_nest_start(buffer);
+
 	entry = trace_event_buffer_reserve(&fbuffer, trace_file,
 					   sizeof(*entry) + fields_size);
 	if (!entry)
-		return;
+		goto out;
 
 	for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
 		if (event->fields[i]->is_string) {
@@ -670,6 +678,8 @@ static notrace void trace_event_raw_event_synth(void *__data,
 	}
 
 	trace_event_buffer_commit(&fbuffer);
+out:
+	ring_buffer_nest_end(buffer);
 }
 
 static void free_synth_event_print_fmt(struct trace_event_call *call)
-- 
2.13.6


  reply	other threads:[~2018-02-08  1:55 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-16  2:51 [PATCH v9 00/37] tracing: Inter-event (e.g. latency) support Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 01/37] tracing: Move hist trigger Documentation to histogram.txt Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 02/37] tracing: Add Documentation for log2 modifier Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 03/37] tracing: Add support to detect and avoid duplicates Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 04/37] tracing: Remove code which merges duplicates Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 05/37] ring-buffer: Add interface for setting absolute time stamps Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 06/37] ring-buffer: Redefine the unimplemented RINGBUF_TYPE_TIME_STAMP Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 07/37] tracing: Add timestamp_mode trace file Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 08/37] tracing: Give event triggers access to ring_buffer_event Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 09/37] tracing: Add ring buffer event param to hist field functions Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 10/37] tracing: Break out hist trigger assignment parsing Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 11/37] tracing: Add hist trigger timestamp support Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 12/37] tracing: Add per-element variable support to tracing_map Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 13/37] tracing: Add hist_data member to hist_field Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 14/37] tracing: Add usecs modifier for hist trigger timestamps Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 15/37] tracing: Add variable support to hist triggers Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 16/37] tracing: Account for variables in named trigger compatibility Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 17/37] tracing: Move get_hist_field_flags() Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 18/37] tracing: Add simple expression support to hist triggers Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 19/37] tracing: Generalize per-element hist trigger data Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 20/37] tracing: Pass tracing_map_elt to hist_field accessor functions Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 21/37] tracing: Add hist_field 'type' field Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 22/37] tracing: Add variable reference handling to hist triggers Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 23/37] tracing: Add hist trigger action hook Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 24/37] tracing: Add support for 'synthetic' events Tom Zanussi
2018-01-16  2:51 ` [PATCH v9 25/37] tracing: Add support for 'field variables' Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 26/37] tracing: Add 'onmatch' hist trigger action support Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 27/37] tracing: Add 'onmax' " Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 28/37] tracing: Allow whitespace to surround hist trigger filter Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 29/37] tracing: Add cpu field for hist triggers Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 30/37] tracing: Add hist trigger support for variable reference aliases Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 31/37] tracing: Add 'last error' error facility for hist triggers Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 32/37] tracing: Add inter-event hist trigger Documentation Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 33/37] tracing: Make tracing_set_clock() non-static Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 34/37] tracing: Add a clock attribute for hist triggers Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 35/37] tracing: Increase trace_recursive_lock() limit for synthetic events Tom Zanussi
2018-02-08  1:55   ` Steven Rostedt [this message]
2018-02-08  4:34     ` Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 36/37] tracing: Add inter-event blurb to HIST_TRIGGERS config option Tom Zanussi
2018-01-16  2:52 ` [PATCH v9 37/37] selftests: ftrace: Add inter-event hist triggers testcases Tom Zanussi

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=20180207205501.2b19c8d6@gandalf.local.home \
    --to=rostedt@goodmis.org \
    --cc=baohong.liu@intel.com \
    --cc=bigeasy@linutronix.de \
    --cc=fengguang.wu@intel.com \
    --cc=joel.opensrc@gmail.com \
    --cc=joelaf@google.com \
    --cc=julia@ni.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mhiramat@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=rajvi.jingar@intel.com \
    --cc=tglx@linutronix.de \
    --cc=tom.zanussi@linux.intel.com \
    --cc=vedang.patel@intel.com \
    /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).