[PATCH v2 5/5] tracing: Make internal_trace_puts() write to correct instance

From: Howard Cochran
Date: Fri Apr 15 2016 - 18:33:32 EST


Currently, internal_trace_puts() always writes to the top level
instance, but callers use this to write warnings which may apply
to any instance. Fixed by adding a struct trace_array * parameter
and changing current callers to use it.

Note that this still queries the trace_printk option for the top level
to decide whether to actually write to the buffer because that option is
documented to only apply to the top level buffer. This behavior also
matches that of the existing error message in update_max_tr_single().

Signed-off-by: Howard Cochran <hcochran@xxxxxxxxxxxxxxxx>
---
kernel/trace/trace.c | 31 ++++++++++++++++++++++---------
kernel/trace/trace.h | 5 ++++-
2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e98770b..b03dda4 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -529,11 +529,13 @@ EXPORT_SYMBOL_GPL(tracing_on);

/**
* __trace_puts - write a constant string into the trace buffer.
+ * @tr: Which buffer (instance) to write to
* @ip: The address of the caller
* @str: The constant string to write
* @size: The size of the string.
*/
-int __trace_puts(unsigned long ip, const char *str, int size)
+int __trace_puts_tr(struct trace_array *tr, unsigned long ip,
+ const char *str, int size)
{
struct ring_buffer_event *event;
struct ring_buffer *buffer;
@@ -553,7 +555,7 @@ int __trace_puts(unsigned long ip, const char *str, int size)
alloc = sizeof(*entry) + size + 2; /* possible \n added */

local_save_flags(irq_flags);
- buffer = global_trace.trace_buffer.buffer;
+ buffer = tr->trace_buffer.buffer;
event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc,
irq_flags, pc);
if (!event)
@@ -572,10 +574,21 @@ int __trace_puts(unsigned long ip, const char *str, int size)
entry->buf[size] = '\0';

__buffer_unlock_commit(buffer, event);
- ftrace_trace_stack(&global_trace, buffer, irq_flags, 4, pc, NULL);
+ ftrace_trace_stack(tr, buffer, irq_flags, 4, pc, NULL);

return size;
}
+
+/**
+ * __trace_puts - write a constant string into the top level trace buffer.
+ * @ip: The address of the caller
+ * @str: The constant string to write
+ * @size: The size of the string.
+ */
+int __trace_puts(unsigned long ip, const char *str, int size)
+{
+ return __trace_puts_tr(&global_trace, ip, str, size);
+}
EXPORT_SYMBOL_GPL(__trace_puts);

/**
@@ -629,22 +642,22 @@ void __tracing_snapshot(struct trace_array *tr)
unsigned long flags;

if (in_nmi()) {
- internal_trace_puts("*** SNAPSHOT CALLED FROM NMI CONTEXT ***\n");
- internal_trace_puts("*** snapshot is being ignored ***\n");
+ internal_trace_puts(tr, "*** SNAPSHOT CALLED FROM NMI CONTEXT ***\n");
+ internal_trace_puts(tr, "*** snapshot is being ignored ***\n");
return;
}

if (!tr->allocated_snapshot) {
- internal_trace_puts("*** SNAPSHOT NOT ALLOCATED ***\n");
- internal_trace_puts("*** stopping trace here! ***\n");
+ internal_trace_puts(tr, "*** SNAPSHOT NOT ALLOCATED ***\n");
+ internal_trace_puts(tr, "*** stopping trace here! ***\n");
tracer_tracing_off(tr);
return;
}

/* Note, snapshot can not be used when the tracer uses it */
if (tracer->use_max_tr) {
- internal_trace_puts("*** LATENCY TRACER ACTIVE ***\n");
- internal_trace_puts("*** Can not use snapshot (sorry) ***\n");
+ internal_trace_puts(tr, "*** LATENCY TRACER ACTIVE ***\n");
+ internal_trace_puts(tr, "*** Can not use snapshot (sorry) ***\n");
return;
}

diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index d98d54c..d23e6ac 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1404,6 +1404,8 @@ void trace_printk_start_comm(void);
int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set);
int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled);

+int __trace_puts_tr(struct trace_array *tr, unsigned long ip,
+ const char *str, int size);
/*
* Normal trace_printk() and friends allocates special buffers
* to do the manipulation, as well as saves the print formats
@@ -1413,7 +1415,8 @@ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled);
* about performance). The internal_trace_puts() is for such
* a purpose.
*/
-#define internal_trace_puts(str) __trace_puts(_THIS_IP_, str, strlen(str))
+#define internal_trace_puts(tr, str) \
+ __trace_puts_tr(tr, _THIS_IP_, str, strlen(str))

#undef FTRACE_ENTRY
#define FTRACE_ENTRY(call, struct_name, id, tstruct, print, filter) \
--
1.9.1