lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon,  5 Dec 2011 18:22:56 +0100
From:	Jiri Olsa <jolsa@...hat.com>
To:	rostedt@...dmis.org, fweisbec@...il.com, mingo@...hat.com,
	paulus@...ba.org, acme@...stprotocols.net, a.p.zijlstra@...llo.nl
Cc:	linux-kernel@...r.kernel.org, aarapov@...hat.com,
	Jiri Olsa <jolsa@...hat.com>
Subject: [PATCHv2 10/10] ftrace, graph: Add global_ops filter callback for graph tracing

The function graph tracer should depend on the global_ops filter,
and process only functions that pass the global_ops filter.

Currently the function graph tracer gets all the functions
enabled for tracing no matter what ftrace_ops enabled them.

Adding a hook for the graph entry callback, which ensures the
function is compared against the global_ops filter and bail
out of if it does not match.

This hook is enabled only if there's at least one non global
ftrace_ops registered.

Signed-off-by: Jiri Olsa <jolsa@...hat.com>
---
 kernel/trace/ftrace.c |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 2dae0c7..dc49ba6 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -95,10 +95,13 @@ ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub;
 ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
 static struct ftrace_ops global_ops;
 static struct ftrace_ops control_ops;
+static int non_global_ops_registered;
 
 static void
 ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip);
 
+static void ftrace_graph_update_filter(void);
+
 /*
  * Traverse the ftrace_global_list, invoking all entries.  The reason that we
  * can use rcu_dereference_raw() is that elements removed from this list
@@ -330,6 +333,9 @@ static int __register_ftrace_function(struct ftrace_ops *ops)
 	if (!core_kernel_data((unsigned long)ops))
 		ops->flags |= FTRACE_OPS_FL_DYNAMIC;
 
+	if (!(ops->flags & FTRACE_OPS_FL_GLOBAL))
+		non_global_ops_registered++;
+
 	if (ops->flags & FTRACE_OPS_FL_GLOBAL) {
 		add_ftrace_ops(&ftrace_global_list, &global_ops, ops);
 		ops->flags |= FTRACE_OPS_FL_ENABLED;
@@ -359,6 +365,9 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
 	if (FTRACE_WARN_ON(ops == &global_ops))
 		return -EINVAL;
 
+	if (!(ops->flags & FTRACE_OPS_FL_GLOBAL))
+		non_global_ops_registered--;
+
 	if (ops->flags & FTRACE_OPS_FL_GLOBAL) {
 		ret = remove_ftrace_ops(&ftrace_global_list, &global_ops, ops);
 		if (!ret)
@@ -1695,6 +1704,8 @@ static int __ftrace_modify_code(void *data)
 	if (*command & FTRACE_UPDATE_TRACE_FUNC)
 		ftrace_update_ftrace_func(ftrace_trace_function);
 
+	ftrace_graph_update_filter();
+
 	if (*command & FTRACE_START_FUNC_RET)
 		ftrace_enable_ftrace_graph_caller();
 	else if (*command & FTRACE_STOP_FUNC_RET)
@@ -4339,4 +4350,34 @@ void ftrace_graph_stop(void)
 {
 	ftrace_stop();
 }
+
+static trace_func_graph_ent_t ftrace_graph_entry_saved;
+
+int ftrace_graph_entry_filter(struct ftrace_graph_ent *ent)
+{
+	if (ftrace_ops_test(&global_ops, ent->func))
+		return ftrace_graph_entry_saved(ent);
+
+	return 0;
+}
+
+static void ftrace_graph_update_filter(void)
+{
+	bool installed = (ftrace_graph_entry == ftrace_graph_entry_filter);
+
+	if (!ftrace_graph_active)
+		return;
+
+	if (!installed && non_global_ops_registered) {
+		ftrace_graph_entry_saved = ftrace_graph_entry;
+		ftrace_graph_entry = ftrace_graph_entry_filter;
+		return;
+	}
+
+	if (installed && !non_global_ops_registered)
+		ftrace_graph_entry = ftrace_graph_entry_saved;
+}
+
+#else
+static void ftrace_graph_update_filter(void) { }
 #endif
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ