ftrace: updates for tip
Steven Rostedt
maintainercover ftrace: updates for tip
Ingo,
The following patches are in:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
branch: tip/devel
Steven Rostedt (3):
ftrace: remove condition from ftrace_record_ip
ftrace: disable ftrace on anomalies in trace start and stop
ftrace: do not process freed records
----
kernel/trace/ftrace.c | 91 +++++++++++++++++++++++++++--------------------- 1 files changed, 51 insertions(+), 40 deletions(-)
Steven Rostedt
maintainerPATCH 1/3 ftrace: remove condition from ftrace_record_ip
Impact: let module functions be recorded when dyn ftrace not enabled
When dynamic ftrace had a daemon and a hash to record the locations of mcount callers at run time, the recording needed to stop when ftrace was disabled. But now that the recording is done at compile time and the ftrace_record_ip is only called at boot up and when a module is loaded, we no longer need to check if ftrace_enabled is set. In fact, this breaks module load if it is not set because we skip over module functions.
--- kernel/trace/ftrace.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
kernel/trace/ftrace.c +1 -1
@@ -335,7 +335,7 @@ ftrace_record_ip(unsigned long ip) {struct dyn_ftrace *rec; -if (!ftrace_enabled || ftrace_disabled) +if (ftrace_disabled)return NULL ; rec =ftrace_alloc_dyn_node (ip);
Signature · 3 lines
1.5.6.5 --
Steven Rostedt
maintainerPATCH 2/3 ftrace: disable ftrace on anomalies in trace start and stop
In reply to Steven RostedtImpact: robust feature to disable ftrace on start or stop tracing on error
Currently only the initial conversion to nops will disable ftrace on an anomaly. But if an anomaly happens on start or stopping of the tracer, it will silently fail.
This patch adds a check there too, to disable ftrace and warn if the conversion fails.
--- kernel/trace/ftrace.c | 81 ++++++++++++++++++++++++++---------------------- 1 files changed, 44 insertions(+), 37 deletions(-)
kernel/trace/ftrace.c +44 -37
@@ -349,6 +349,47 @@ ftrace_record_ip(unsigned long ip)return rec; } +static void print_ip_ins (const char *fmt,unsigned char *p) +{ +int i; + +printk (KERN_CONT "%s" , fmt); + +for (i =0 ; i <MCOUNT_INSN_SIZE ; i++) +printk (KERN_CONT "%s%02x" , i ?":" :"" , p[i]); +} + +static void ftrace_bug (int failed,unsigned long ip, +unsigned char *expected, +unsigned char *replace) +{ +switch (failed) { +case -EFAULT : +FTRACE_WARN_ON_ONCE (1 ); +pr_info ("ftrace faulted on modifying " ); +print_ip_sym (ip); +break ; +case -EINVAL : +FTRACE_WARN_ON_ONCE (1 ); +pr_info ("ftrace failed to modify " ); +print_ip_sym (ip); +print_ip_ins (" expected: " , expected); +print_ip_ins (" actual: " , (unsigned char *)ip); +print_ip_ins (" replace: " , replace); +printk (KERN_CONT "\n" ); +break ; +case -EPERM : +FTRACE_WARN_ON_ONCE (1 ); +pr_info ("ftrace faulted on writing " ); +print_ip_sym (ip); +break ; +default : +FTRACE_WARN_ON_ONCE (1 ); +pr_info ("ftrace faulted on unknown error " ); +print_ip_sym (ip); + } +} +#define FTRACE_ADDR ((long)(ftrace_caller)) static int
@@ -466,22 +507,13 @@ static void ftrace_replace_code(int enable)if ((system_state ==SYSTEM_BOOTING ) || !core_kernel_text (rec->ip)) {ftrace_free_rec (rec); - } + }else +ftrace_bug (failed, rec->ip, old, new); } } } } -static void print_ip_ins (const char *fmt,unsigned char *p) -{ -int i; - -printk (KERN_CONT "%s" , fmt); - -for (i =0 ; i <MCOUNT_INSN_SIZE ; i++) -printk (KERN_CONT "%s%02x" , i ?":" :"" , p[i]); -} -static int ftrace_code_disable (struct dyn_ftrace *rec) {
@@ -496,32 +528,7 @@ ftrace_code_disable(struct dyn_ftrace *rec) ret =ftrace_modify_code (ip, call, nop);if (ret) { -switch (ret) { -case -EFAULT : -FTRACE_WARN_ON_ONCE (1 ); -pr_info ("ftrace faulted on modifying " ); -print_ip_sym (ip); -break ; -case -EINVAL : -FTRACE_WARN_ON_ONCE (1 ); -pr_info ("ftrace failed to modify " ); -print_ip_sym (ip); -print_ip_ins (" expected: " , call); -print_ip_ins (" actual: " , (unsigned char *)ip); -print_ip_ins (" replace: " , nop); -printk (KERN_CONT "\n" ); -break ; -case -EPERM : -FTRACE_WARN_ON_ONCE (1 ); -pr_info ("ftrace faulted on writing " ); -print_ip_sym (ip); -break ; -default : -FTRACE_WARN_ON_ONCE (1 ); -pr_info ("ftrace faulted on unknown error " ); -print_ip_sym (ip); - } - +ftrace_bug (ret, ip, call, nop); rec->flags |=FTRACE_FL_FAILED ;return 0 ; }
Signature · 3 lines
1.5.6.5 --
Steven Rostedt
maintainerPATCH 3/3 ftrace: do not process freed records
In reply to Steven RostedtImpact: keep from converting freed records
When the tracer is started or stopped, it converts all code pointed to by the saved records into callers to ftrace or nops. When modules are unloaded, their records are freed, but they still exist within the record pages.
This patch changes the code to skip over freed records.
--- kernel/trace/ftrace.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-)
kernel/trace/ftrace.c +6 -2
@@ -489,8 +489,12 @@ static void ftrace_replace_code(int enable)for (i =0 ; i < pg->index; i++) { rec = &pg->records[i]; -/* don't modify code that has already faulted */ -if (rec->flags &FTRACE_FL_FAILED ) +/* +* Skip over free records and records that have +* failed. +*/ +if (rec->flags &FTRACE_FL_FREE || + rec->flags &FTRACE_FL_FAILED )continue ;/* ignore updates to this record's mcount site */
Signature · 3 lines
1.5.6.5 --