Commit 130c0806 authored by Jiri Olsa's avatar Jiri Olsa Committed by Steven Rostedt (VMware)
Browse files

tracing: Add trampoline/graph selftest

Adding selftest for checking that direct trampoline can
co-exist together with graph tracer on same function.

This is supported for CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
config option, which is defined only for x86_64 for now.

Link: https://lkml.kernel.org/r/20211008091336.33616-5-jolsa@kernel.org



Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 0c0593b4
Loading
Loading
Loading
Loading
+53 −1
Original line number Diff line number Diff line
@@ -784,6 +784,8 @@ static struct fgraph_ops fgraph_ops __initdata = {
	.retfunc		= &trace_graph_return,
};

noinline __noclone static void trace_direct_tramp(void) { }

/*
 * Pretty much the same than for the function tracer from which the selftest
 * has been borrowed.
@@ -794,6 +796,7 @@ trace_selftest_startup_function_graph(struct tracer *trace,
{
	int ret;
	unsigned long count;
	char *func_name __maybe_unused;

#ifdef CONFIG_DYNAMIC_FTRACE
	if (ftrace_filter_param) {
@@ -842,8 +845,57 @@ trace_selftest_startup_function_graph(struct tracer *trace,
		goto out;
	}

	/* Don't test dynamic tracing, the function tracer already did */
#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
	tracing_reset_online_cpus(&tr->array_buffer);
	set_graph_array(tr);

	/*
	 * Some archs *cough*PowerPC*cough* add characters to the
	 * start of the function names. We simply put a '*' to
	 * accommodate them.
	 */
	func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
	ftrace_set_global_filter(func_name, strlen(func_name), 1);

	/*
	 * Register direct function together with graph tracer
	 * and make sure we get graph trace.
	 */
	ret = register_ftrace_direct((unsigned long) DYN_FTRACE_TEST_NAME,
				     (unsigned long) trace_direct_tramp);
	if (ret)
		goto out;

	ret = register_ftrace_graph(&fgraph_ops);
	if (ret) {
		warn_failed_init_tracer(trace, ret);
		goto out;
	}

	DYN_FTRACE_TEST_NAME();

	count = 0;

	tracing_stop();
	/* check the trace buffer */
	ret = trace_test_buffer(&tr->array_buffer, &count);

	unregister_ftrace_graph(&fgraph_ops);

	ret = unregister_ftrace_direct((unsigned long) DYN_FTRACE_TEST_NAME,
				       (unsigned long) trace_direct_tramp);
	if (ret)
		goto out;

	tracing_start();

	if (!ret && !count) {
		ret = -1;
		goto out;
	}
#endif

	/* Don't test dynamic tracing, the function tracer already did */
out:
	/* Stop it if we failed */
	if (ret)