/* Test dynamic code modification and ftrace filters */ static int trace_selftest_startup_dynamic_tracing(struct tracer *trace, struct trace_array *tr, int (*func)(void)) { int save_ftrace_enabled = ftrace_enabled; unsigned long count; char *func_name; int ret; /* The ftrace test PASSED */ printk(KERN_CONT "PASSED\n"); pr_info("Testing dynamic ftrace: "); /* enable tracing, and record the filter function */ ftrace_enabled = 1; /* passed in by parameter to fool gcc from optimizing */ func(); /* * 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); /* filter only on our function */ ftrace_set_global_filter(func_name, strlen(func_name), 1); /* enable tracing */ ret = tracer_init(trace, tr); if (ret) { warn_failed_init_tracer(trace, ret); goto out; } /* Sleep for a 1/10 of a second */ msleep(100); /* we should have nothing in the buffer */ ret = trace_test_buffer(&tr->trace_buffer, &count); if (ret) goto out; if (count) { ret = -1; printk(KERN_CONT ".. filter did not filter .. "); goto out; } /* call our function again */ func(); /* sleep again */ msleep(100); /* stop the tracing. */ tracing_stop(); ftrace_enabled = 0; /* check the trace buffer */ ret = trace_test_buffer(&tr->trace_buffer, &count); ftrace_enabled = 1; tracing_start(); /* we should only have one item */ if (!ret && count != 1) { trace->reset(tr); printk(KERN_CONT ".. filter failed count=%ld ..", count); ret = -1; goto out; } /* Test the ops with global tracing running */ ret = trace_selftest_ops(tr, 1); trace->reset(tr); out: ftrace_enabled = save_ftrace_enabled; /* Enable tracing on all functions again */ ftrace_set_global_filter(NULL, 0, 1); /* Test the ops with global tracing off */ if (!ret) ret = trace_selftest_ops(tr, 2); return ret; }
int trace_selftest_startup_dynamic_tracing(struct tracer *trace, struct trace_array *tr, int (*func)(void)) { int save_ftrace_enabled = ftrace_enabled; int save_tracer_enabled = tracer_enabled; unsigned long count; char *func_name; int ret; /* */ printk(KERN_CONT "PASSED\n"); pr_info("Testing dynamic ftrace: "); /* */ ftrace_enabled = 1; tracer_enabled = 1; /* */ func(); /* */ func_name = "*" __stringify(DYN_FTRACE_TEST_NAME); /* */ ftrace_set_global_filter(func_name, strlen(func_name), 1); /* */ ret = tracer_init(trace, tr); if (ret) { warn_failed_init_tracer(trace, ret); goto out; } /* */ msleep(100); /* */ ret = trace_test_buffer(tr, &count); if (ret) goto out; if (count) { ret = -1; printk(KERN_CONT ".. filter did not filter .. "); goto out; } /* */ func(); /* */ msleep(100); /* */ tracing_stop(); ftrace_enabled = 0; /* */ ret = trace_test_buffer(tr, &count); tracing_start(); /* */ if (!ret && count != 1) { trace->reset(tr); printk(KERN_CONT ".. filter failed count=%ld ..", count); ret = -1; goto out; } /* */ ret = trace_selftest_ops(1); trace->reset(tr); out: ftrace_enabled = save_ftrace_enabled; tracer_enabled = save_tracer_enabled; /* */ ftrace_set_global_filter(NULL, 0, 1); /* */ if (!ret) ret = trace_selftest_ops(2); return ret; }