lkml.org 
[lkml]   [2008]   [Oct]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] ftrace: add quick function trace stop

This patch adds a way to disable the function tracer quickly without
the need to run kstop_machine. It adds a new variable called
function_trace_stop which will stop the calls to functions from mcount
when set. This is just an on/off switch and does not handle recursion
like preempt_disable().

It's main purpose is to help other tracers/debuggers start and stop tracing
fuctions without the need to call kstop_machine.

A new file is added to /debug/tracing called function_trace_stop.
Echoing 1 into this file will stop the function tracing and echoing 1
will allow function tracing. Note, this is not the same as the heavy weight
/proc/sys/kernel/ftrace_enabled which calls the kstop_machine to fully
enable or disable ftrace.

ftrace_enabled function_stop_trace

0 0 or 1 - No function tracing at all
1 0 - mcount called but no function is
traced
1 1 - normal function tracing


Note, only x86 architecture has this implemented (for now).

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
arch/x86/kernel/entry_32.S | 6 +++++
arch/x86/kernel/entry_64.S | 5 ++++
include/linux/ftrace.h | 28 ++++++++++++++++++++++++
kernel/trace/ftrace.c | 52 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 91 insertions(+)

Index: linux-tip.git/arch/x86/kernel/entry_32.S
===================================================================
--- linux-tip.git.orig/arch/x86/kernel/entry_32.S 2008-10-06 10:54:50.000000000 -0400
+++ linux-tip.git/arch/x86/kernel/entry_32.S 2008-10-06 11:31:49.000000000 -0400
@@ -1187,6 +1187,9 @@ ENTRY(mcount)
END(mcount)

ENTRY(ftrace_caller)
+ cmpl $0, function_trace_stop
+ jne ftrace_stub
+
pushl %eax
pushl %ecx
pushl %edx
@@ -1210,6 +1213,9 @@ END(ftrace_caller)
#else /* ! CONFIG_DYNAMIC_FTRACE */

ENTRY(mcount)
+ cmpl $0, function_trace_stop
+ jne ftrace_stub
+
cmpl $ftrace_stub, ftrace_trace_function
jnz trace
.globl ftrace_stub
Index: linux-tip.git/arch/x86/kernel/entry_64.S
===================================================================
--- linux-tip.git.orig/arch/x86/kernel/entry_64.S 2008-10-06 10:54:50.000000000 -0400
+++ linux-tip.git/arch/x86/kernel/entry_64.S 2008-10-06 11:31:59.000000000 -0400
@@ -68,6 +68,8 @@ ENTRY(mcount)
END(mcount)

ENTRY(ftrace_caller)
+ cmpl $0, function_trace_stop
+ jne ftrace_stub

/* taken from glibc */
subq $0x38, %rsp
@@ -103,6 +105,9 @@ END(ftrace_caller)

#else /* ! CONFIG_DYNAMIC_FTRACE */
ENTRY(mcount)
+ cmpl $0, function_trace_stop
+ jne ftrace_stub
+
cmpq $ftrace_stub, ftrace_trace_function
jnz trace
.globl ftrace_stub
Index: linux-tip.git/include/linux/ftrace.h
===================================================================
--- linux-tip.git.orig/include/linux/ftrace.h 2008-10-06 10:55:07.000000000 -0400
+++ linux-tip.git/include/linux/ftrace.h 2008-10-06 11:25:26.000000000 -0400
@@ -23,6 +23,34 @@ struct ftrace_ops {
struct ftrace_ops *next;
};

+extern int function_trace_stop;
+
+/**
+ * ftrace_stop - stop function tracer.
+ *
+ * A quick way to stop the function tracer. Note this an on off switch,
+ * it is not something that is recursive like preempt_disable.
+ * This does not disable the calling of mcount, it only stops the
+ * calling of functions from mcount.
+ */
+static inline void ftrace_stop(void)
+{
+ function_trace_stop = 1;
+}
+
+/**
+ * ftrace_start - start the function tracer.
+ *
+ * This function is the inverse of ftrace_stop. This does not enable
+ * the function tracing if the function tracer is disabled. This only
+ * sets the function tracer flag to contiune calling the functions
+ * from mcount.
+ */
+static inline void ftrace_start(void)
+{
+ function_trace_stop = 0;
+}
+
/*
* The ftrace_ops must be a static and should also
* be read_mostly. These functions do modify read_mostly variables
Index: linux-tip.git/kernel/trace/ftrace.c
===================================================================
--- linux-tip.git.orig/kernel/trace/ftrace.c 2008-09-29 20:13:37.000000000 -0400
+++ linux-tip.git/kernel/trace/ftrace.c 2008-10-06 12:33:40.000000000 -0400
@@ -36,6 +36,9 @@
int ftrace_enabled __read_mostly;
static int last_ftrace_enabled;

+/* Quick disabling of function tracer. */
+int function_trace_stop;
+
/*
* ftrace_disabled is set when an anomaly is discovered.
* ftrace_disabled is much stronger than ftrace_enabled.
@@ -1480,6 +1483,46 @@ ftraced_write(struct file *filp, const c
return cnt;
}

+static ssize_t
+ftrace_stop_read(struct file *filp, char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ /* don't worry about races */
+ char *buf = function_trace_stop ? "1\n" : "0\n";
+ int r = strlen(buf);
+
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static ssize_t
+ftrace_stop_write(struct file *filp, const char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ long val;
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+
+ buf[cnt] = 0;
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ val = !!val;
+
+ function_trace_stop = !!val;
+
+ filp->f_pos += cnt;
+
+ return cnt;
+}
+
static struct file_operations ftrace_avail_fops = {
.open = ftrace_avail_open,
.read = seq_read,
@@ -1516,6 +1559,12 @@ static struct file_operations ftraced_fo
.write = ftraced_write,
};

+static struct file_operations ftrace_stop_fops = {
+ .open = tracing_open_generic,
+ .read = ftrace_stop_read,
+ .write = ftrace_stop_write,
+};
+
/**
* ftrace_force_update - force an update to all recording ftrace functions
*/
@@ -1593,6 +1642,9 @@ static __init int ftrace_init_debugfs(vo
if (!entry)
pr_warning("Could not create debugfs "
"'ftraced_enabled' entry\n");
+
+ entry = debugfs_create_file("function_trace_stop", 0644, d_tracer,
+ NULL, &ftrace_stop_fops);
return 0;
}



\
 
 \ /
  Last update: 2008-10-06 18:55    [W:0.048 / U:0.252 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site