Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ea21c1e authored by Steven Rostedt's avatar Steven Rostedt Committed by Ingo Molnar
Browse files

tracing/events: perform function tracing in event selftests



We can find some bugs in the trace events if we stress the writes as well.
The function tracer is a good way to stress the events.

[ Impact: extend scope of event tracer self-tests ]

Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <20090416161746.604786131@goodmis.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 69abe6a5
Loading
Loading
Loading
Loading
+72 −6
Original line number Diff line number Diff line
@@ -1017,7 +1017,7 @@ static __init void event_test_stuff(void)
 * For every trace event defined, we will test each trace point separately,
 * and then by groups, and finally all trace points.
 */
static __init int event_trace_self_tests(void)
static __init void event_trace_self_tests(void)
{
	struct ftrace_event_call *call;
	struct event_subsystem *system;
@@ -1071,7 +1071,7 @@ static __init int event_trace_self_tests(void)
		sysname = kstrdup(system->name, GFP_KERNEL);
		if (WARN_ON(!sysname)) {
			pr_warning("Can't allocate memory, giving up!\n");
			return 0;
			return;
		}
		ret = ftrace_set_clr_event(sysname, 1);
		kfree(sysname);
@@ -1086,7 +1086,7 @@ static __init int event_trace_self_tests(void)
		sysname = kstrdup(system->name, GFP_KERNEL);
		if (WARN_ON(!sysname)) {
			pr_warning("Can't allocate memory, giving up!\n");
			return 0;
			return;
		}
		ret = ftrace_set_clr_event(sysname, 0);
		kfree(sysname);
@@ -1106,14 +1106,14 @@ static __init int event_trace_self_tests(void)
	sysname = kmalloc(4, GFP_KERNEL);
	if (WARN_ON(!sysname)) {
		pr_warning("Can't allocate memory, giving up!\n");
		return 0;
		return;
	}
	memcpy(sysname, "*:*", 4);
	ret = ftrace_set_clr_event(sysname, 1);
	if (WARN_ON_ONCE(ret)) {
		kfree(sysname);
		pr_warning("error enabling all events\n");
		return 0;
		return;
	}

	event_test_stuff();
@@ -1125,10 +1125,76 @@ static __init int event_trace_self_tests(void)

	if (WARN_ON_ONCE(ret)) {
		pr_warning("error disabling all events\n");
		return 0;
		return;
	}

	pr_cont("OK\n");
}

#ifdef CONFIG_FUNCTION_TRACER

static DEFINE_PER_CPU(atomic_t, test_event_disable);

static void
function_test_events_call(unsigned long ip, unsigned long parent_ip)
{
	struct ring_buffer_event *event;
	struct ftrace_entry *entry;
	unsigned long flags;
	long disabled;
	int resched;
	int cpu;
	int pc;

	pc = preempt_count();
	resched = ftrace_preempt_disable();
	cpu = raw_smp_processor_id();
	disabled = atomic_inc_return(&per_cpu(test_event_disable, cpu));

	if (disabled != 1)
		goto out;

	local_save_flags(flags);

	event = trace_current_buffer_lock_reserve(TRACE_FN, sizeof(*entry),
						  flags, pc);
	if (!event)
		goto out;
	entry	= ring_buffer_event_data(event);
	entry->ip			= ip;
	entry->parent_ip		= parent_ip;

	trace_current_buffer_unlock_commit(event, flags, pc);

 out:
	atomic_dec(&per_cpu(test_event_disable, cpu));
	ftrace_preempt_enable(resched);
}

static struct ftrace_ops trace_ops __initdata  =
{
	.func = function_test_events_call,
};

static __init void event_trace_self_test_with_function(void)
{
	register_ftrace_function(&trace_ops);
	pr_info("Running tests again, along with the function tracer\n");
	event_trace_self_tests();
	unregister_ftrace_function(&trace_ops);
}
#else
static __init void event_trace_self_test_with_function(void)
{
}
#endif

static __init int event_trace_self_tests_init(void)
{

	event_trace_self_tests();

	event_trace_self_test_with_function();

	return 0;
}