diff options
Diffstat (limited to 'kernel/trace/trace_selftest.c')
| -rw-r--r-- | kernel/trace/trace_selftest.c | 92 | 
1 files changed, 91 insertions, 1 deletions
| diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index adf7ef194005..afd937a46496 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -287,6 +287,40 @@ static int trace_selftest_ops(struct trace_array *tr, int cnt)  	if (trace_selftest_test_probe3_cnt != 4)  		goto out_free; +	/* Remove trace function from probe 3 */ +	func1_name = "!" __stringify(DYN_FTRACE_TEST_NAME); +	len1 = strlen(func1_name); + +	ftrace_set_filter(&test_probe3, func1_name, len1, 0); + +	DYN_FTRACE_TEST_NAME(); + +	print_counts(); + +	if (trace_selftest_test_probe1_cnt != 3) +		goto out_free; +	if (trace_selftest_test_probe2_cnt != 2) +		goto out_free; +	if (trace_selftest_test_probe3_cnt != 4) +		goto out_free; +	if (cnt > 1) { +		if (trace_selftest_test_global_cnt == 0) +			goto out_free; +	} +	if (trace_selftest_test_dyn_cnt == 0) +		goto out_free; + +	DYN_FTRACE_TEST_NAME2(); + +	print_counts(); + +	if (trace_selftest_test_probe1_cnt != 3) +		goto out_free; +	if (trace_selftest_test_probe2_cnt != 3) +		goto out_free; +	if (trace_selftest_test_probe3_cnt != 5) +		goto out_free; +  	ret = 0;   out_free:  	unregister_ftrace_function(dyn_ops); @@ -750,6 +784,12 @@ static struct fgraph_ops fgraph_ops __initdata  = {  	.retfunc		= &trace_graph_return,  }; +#if defined(CONFIG_DYNAMIC_FTRACE) && \ +    defined(CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS) +#define TEST_DIRECT_TRAMP +noinline __noclone static void trace_direct_tramp(void) { } +#endif +  /*   * Pretty much the same than for the function tracer from which the selftest   * has been borrowed. @@ -760,6 +800,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) { @@ -808,8 +849,57 @@ trace_selftest_startup_function_graph(struct tracer *trace,  		goto out;  	} -	/* Don't test dynamic tracing, the function tracer already did */ +#ifdef TEST_DIRECT_TRAMP +	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) |