summaryrefslogtreecommitdiffstats
path: root/kernel/extable.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-05-05 21:14:55 -0400
committerSteven Rostedt <rostedt@goodmis.org>2011-05-18 15:29:51 -0400
commitcdbe61bfe70440939e457fb4a8d0995eaaed17de (patch)
tree6e82066db25ab6fa42455a42bb77783dac5260b8 /kernel/extable.c
parentb848914ce39589d89ee0078a6d1ef452b464729e (diff)
downloadlinux-stable-cdbe61bfe70440939e457fb4a8d0995eaaed17de.tar.gz
linux-stable-cdbe61bfe70440939e457fb4a8d0995eaaed17de.tar.bz2
linux-stable-cdbe61bfe70440939e457fb4a8d0995eaaed17de.zip
ftrace: Allow dynamically allocated function tracers
Now that functions may be selected individually, it only makes sense that we should allow dynamically allocated trace structures to be traced. This will allow perf to allocate a ftrace_ops structure at runtime and use it to pick and choose which functions that structure will trace. Note, a dynamically allocated ftrace_ops will always be called indirectly instead of being called directly from the mcount in entry.S. This is because there's no safe way to prevent mcount from being preempted before calling the function, unless we modify every entry.S to do so (not likely). Thus, dynamically allocated functions will now be called by the ftrace_ops_list_func() that loops through the ops that are allocated if there are more than one op allocated at a time. This loop is protected with a preempt_disable. To determine if an ftrace_ops structure is allocated or not, a new util function was added to the kernel/extable.c called core_kernel_data(), which returns 1 if the address is between _sdata and _edata. Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/extable.c')
-rw-r--r--kernel/extable.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/kernel/extable.c b/kernel/extable.c
index 7f8f263f8524..c2d625fcda77 100644
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -72,6 +72,14 @@ int core_kernel_text(unsigned long addr)
return 0;
}
+int core_kernel_data(unsigned long addr)
+{
+ if (addr >= (unsigned long)_sdata &&
+ addr < (unsigned long)_edata)
+ return 1;
+ return 0;
+}
+
int __kernel_text_address(unsigned long addr)
{
if (core_kernel_text(addr))