lkml.org 
[lkml]   [2013]   [Aug]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[RFC][PATCH 07/18 v2] ftrace: Add selftest to check if RCU unsafe functions are filtered properly
From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

Add a boot time start up test that has a RCU safe ftrace_ops as well
as an unsafe one. Make sure the RCU safe ops can trace RCU unsafe
functions while the unsafe ftrace_ops can not.

Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace.h | 2 +
kernel/trace/trace_selftest.c | 94 +++++++++++++++++++++++++++++++++
kernel/trace/trace_selftest_dynamic.c | 7 +++
3 files changed, 103 insertions(+)

diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 502fed7..3578be6 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -648,6 +648,8 @@ extern unsigned long ftrace_update_tot_cnt;
extern int DYN_FTRACE_TEST_NAME(void);
#define DYN_FTRACE_TEST_NAME2 trace_selftest_dynamic_test_func2
extern int DYN_FTRACE_TEST_NAME2(void);
+#define DYN_FTRACE_TEST_RCU_UNSAFE trace_selftest_dynamic_test_rcu_unsafe
+extern int DYN_FTRACE_TEST_RCU_UNSAFE(void);

extern bool ring_buffer_expanded;
extern bool tracing_selftest_disabled;
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index a7329b7..eeacb47 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -185,6 +185,97 @@ static void reset_counts(void)
trace_selftest_test_dyn_cnt = 0;
}

+static struct ftrace_ops ftrace_rcu_safe_ops = {
+ .func = trace_selftest_test_probe1_func,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_RCU_SAFE,
+};
+
+static struct ftrace_ops ftrace_rcu_unsafe_ops = {
+ .func = trace_selftest_test_probe2_func,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
+};
+
+static int test_rcu_safe_unsafe(void)
+{
+ int save_ftrace_enabled = ftrace_enabled;
+ char *func_name;
+ int len;
+ int ret = 0;
+
+ printk(KERN_CONT "PASSED\n");
+ pr_info("Testing ftrace rcu safe unsafe: ");
+
+ ftrace_enabled = 1;
+
+ trace_selftest_test_probe1_cnt = 0;
+ trace_selftest_test_probe2_cnt = 0;
+
+ func_name = "*" __stringify(DYN_FTRACE_TEST_RCU_UNSAFE);
+ len = strlen(func_name);
+
+ ftrace_set_filter(&ftrace_rcu_safe_ops, func_name, len, 1);
+ ftrace_set_filter(&ftrace_rcu_unsafe_ops, func_name, len, 1);
+
+ /* Do single registrations first */
+ register_ftrace_function(&ftrace_rcu_safe_ops);
+
+ DYN_FTRACE_TEST_RCU_UNSAFE();
+
+ unregister_ftrace_function(&ftrace_rcu_safe_ops);
+
+ if (trace_selftest_test_probe1_cnt != 1) {
+ printk(KERN_CONT "rcu_safe expected 1 call but had %d ",
+ trace_selftest_test_probe1_cnt);
+ goto out;
+ }
+
+ register_ftrace_function(&ftrace_rcu_unsafe_ops);
+
+ DYN_FTRACE_TEST_RCU_UNSAFE();
+
+ unregister_ftrace_function(&ftrace_rcu_unsafe_ops);
+
+ if (trace_selftest_test_probe2_cnt != 0) {
+ printk(KERN_CONT "rcu_safe expected 0 calls but had %d ",
+ trace_selftest_test_probe2_cnt);
+ goto out;
+ }
+
+ /* Run both together, which uses the list op */
+
+ trace_selftest_test_probe1_cnt = 0;
+ trace_selftest_test_probe2_cnt = 0;
+
+ register_ftrace_function(&ftrace_rcu_safe_ops);
+ register_ftrace_function(&ftrace_rcu_unsafe_ops);
+
+ DYN_FTRACE_TEST_RCU_UNSAFE();
+ DYN_FTRACE_TEST_RCU_UNSAFE();
+ DYN_FTRACE_TEST_RCU_UNSAFE();
+
+ unregister_ftrace_function(&ftrace_rcu_unsafe_ops);
+ unregister_ftrace_function(&ftrace_rcu_safe_ops);
+
+
+ if (trace_selftest_test_probe1_cnt != 3) {
+ printk(KERN_CONT "rcu_safe expected 3 calls but had %d ",
+ trace_selftest_test_probe1_cnt);
+ goto out;
+ }
+
+ if (trace_selftest_test_probe2_cnt != 0) {
+ printk(KERN_CONT "rcu_safe expected 0 calls but had %d ",
+ trace_selftest_test_probe2_cnt);
+ goto out;
+ }
+
+ ret = 0;
+ out:
+ ftrace_enabled = save_ftrace_enabled;
+
+ return ret;
+}
+
static int trace_selftest_ops(int cnt)
{
int save_ftrace_enabled = ftrace_enabled;
@@ -401,6 +492,9 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
if (!ret)
ret = trace_selftest_ops(2);

+ if (!ret)
+ ret = test_rcu_safe_unsafe();
+
return ret;
}

diff --git a/kernel/trace/trace_selftest_dynamic.c b/kernel/trace/trace_selftest_dynamic.c
index b4c475a..5eefa56 100644
--- a/kernel/trace/trace_selftest_dynamic.c
+++ b/kernel/trace/trace_selftest_dynamic.c
@@ -11,3 +11,10 @@ int DYN_FTRACE_TEST_NAME2(void)
/* used to call mcount */
return 0;
}
+
+int trace_selftest_dynamic_test_rcu_unsafe(void)
+{
+ /* used to call mcount */
+ return 0;
+}
+FTRACE_UNSAFE_RCU(trace_selftest_dynamic_test_rcu_unsafe);
--
1.7.10.4



\
 
 \ /
  Last update: 2013-08-31 08:21    [W:0.403 / U:0.648 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site