[PATCH] tracing: add tracing C helper functions

From: Ioan-Adrian Ratiu
Date: Fri Nov 27 2015 - 08:53:59 EST


Tracing/debugging programatically from kernel C code is quite limited
compared to its tracefs alternative mainly due to lack of interfaces.
linux/kernel.h provides traceing_on/off() and *_snapshot(), but these
only allow access to a limited subset of the tracing functionality.

This patch adds 5 new functions to make tracing from C easier:
tracing_change_tracer - change the live tracer
tracing_clear_all - clear all cpu ringbuffers
tracing_clear_cpu - clear a specific cpu's buffer
tracing_resize_all - set ringbuffer size for all cpus
tracing_resize_cpu - set ringbuffer size for specific cpu

These functions are very helpful when combined with existing ones, for
example to debug the call serial8250_pnp_init() in serial8250_init():

tracing_resize_all(1 << 23);
tracing_change_tracer("function_graph");
tracing_on();

trace_printk("starting pnp init\n");
ret = serial8250_pnp_init();
trace_printk("done pnp init\n");

tracing_off();
tracing_clear_cpu((1 - smp_processor_id());

or conditionally trace driver_register() only for the serial driver:

if (!strncmp(drv->name, "serial", 6)) {
tracing_change_tracer("function_graph");
tracing_on();
}

Signed-off-by: Ioan-Adrian Ratiu <adrian.ratiu@xxxxxx>
---
include/linux/kernel.h | 5 +++++
kernel/trace/trace.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index ae6adf8..7cd24dd 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -552,6 +552,11 @@ void tracing_off(void);
int tracing_is_on(void);
void tracing_snapshot(void);
void tracing_snapshot_alloc(void);
+void tracing_clear_all(void);
+void tracing_clear_cpu(int cpu);
+void tracing_resize_all(unsigned long size);
+void tracing_resize_cpu(unsigned long size, int cpu);
+void tracing_change_tracer(const char *tracer);

extern void tracing_start(void);
extern void tracing_stop(void);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 87fb980..a8ed37e 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -533,6 +533,62 @@ void tracing_on(void)
EXPORT_SYMBOL_GPL(tracing_on);

/**
+ * tracing_change_tracer - switch live tracing to specified tracer
+ * @tracer: Name of the tracer to change to
+ */
+void tracing_change_tracer(const char *tracer)
+{
+ tracing_set_tracer(&global_trace, tracer);
+}
+EXPORT_SYMBOL_GPL(tracing_change_tracer);
+
+/**
+ * tracing_clear_cpu - reset a cpu live tracing buffer
+ * @cpu: cpu to clear
+ */
+void tracing_clear_cpu(int cpu)
+{
+ mutex_lock(&trace_types_lock);
+ tracing_reset(&global_trace.trace_buffer, cpu);
+ mutex_unlock(&trace_types_lock);
+}
+EXPORT_SYMBOL_GPL(tracing_clear_cpu);
+
+/**
+ * tracing_clear_all - reset all cpu tracing buffers
+ */
+void tracing_clear_all(void)
+{
+ mutex_lock(&trace_types_lock);
+ tracing_reset_online_cpus(&global_trace.trace_buffer);
+ mutex_unlock(&trace_types_lock);
+}
+EXPORT_SYMBOL_GPL(tracing_clear_all);
+
+static ssize_t tracing_resize_ring_buffer(struct trace_array *, unsigned long, int);
+
+/**
+ * tracing_resize_cpu - resize a cpu's ring buffer
+ * @size - new size in KB
+ * @cpu - target cpu for buf resize
+ */
+void tracing_resize_cpu(unsigned long size, int cpu)
+{
+ tracing_resize_ring_buffer(&global_trace, size, cpu);
+}
+EXPORT_SYMBOL_GPL(tracing_resize_cpu);
+
+/**
+ * tracing_resize_all - resize all per-cpu ring buffers
+ * @size - new size in KB
+ */
+void tracing_resize_all(unsigned long size)
+{
+ tracing_resize_ring_buffer(&global_trace, size, RING_BUFFER_ALL_CPUS);
+}
+EXPORT_SYMBOL_GPL(tracing_resize_all);
+
+/**
* __trace_puts - write a constant string into the trace buffer.
* @ip: The address of the caller
* @str: The constant string to write
--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/