mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
		
							parent
							
								
									0c0593b45c
								
							
						
					
					
						commit
						130c080658
					
				
					 1 changed files with 53 additions and 1 deletions
				
			
		| 
						 | 
					@ -784,6 +784,8 @@ static struct fgraph_ops fgraph_ops __initdata  = {
 | 
				
			||||||
	.retfunc		= &trace_graph_return,
 | 
						.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
 | 
					 * Pretty much the same than for the function tracer from which the selftest
 | 
				
			||||||
 * has been borrowed.
 | 
					 * has been borrowed.
 | 
				
			||||||
| 
						 | 
					@ -794,6 +796,7 @@ trace_selftest_startup_function_graph(struct tracer *trace,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	unsigned long count;
 | 
						unsigned long count;
 | 
				
			||||||
 | 
						char *func_name __maybe_unused;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DYNAMIC_FTRACE
 | 
					#ifdef CONFIG_DYNAMIC_FTRACE
 | 
				
			||||||
	if (ftrace_filter_param) {
 | 
						if (ftrace_filter_param) {
 | 
				
			||||||
| 
						 | 
					@ -842,8 +845,57 @@ trace_selftest_startup_function_graph(struct tracer *trace,
 | 
				
			||||||
		goto out;
 | 
							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:
 | 
					out:
 | 
				
			||||||
	/* Stop it if we failed */
 | 
						/* Stop it if we failed */
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue