From: Ingo Molnar Date: Sun, 22 Feb 2009 17:12:01 +0000 (+0100) Subject: Merge branch 'tip/x86/ftrace' of git://git.kernel.org/pub/scm/linux/kernel/git/rosted... X-Git-Url: http://git.mmlx.us/?a=commitdiff_plain;h=c478f8786973d6d7552c652ddad3f6fd86b5af28;p=linux-edison.git Merge branch 'tip/x86/ftrace' of git://git./linux/kernel/git/rostedt/linux-2.6-trace into tracing/ftrace Conflicts: include/linux/ftrace.h kernel/trace/ftrace.c --- c478f8786973d6d7552c652ddad3f6fd86b5af28 diff --cc include/linux/ftrace.h index 915f4723fc8,fdb2a89ae54..847bb3c48dd --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@@ -106,30 -99,9 +106,33 @@@ struct ftrace_func_command /* asm/ftrace.h must be defined for archs supporting dynamic ftrace */ #include + int ftrace_arch_code_modify_prepare(void); + int ftrace_arch_code_modify_post_process(void); + +struct seq_file; + +struct ftrace_probe_ops { + void (*func)(unsigned long ip, + unsigned long parent_ip, + void **data); + int (*callback)(unsigned long ip, void **data); + void (*free)(void **data); + int (*print)(struct seq_file *m, + unsigned long ip, + struct ftrace_probe_ops *ops, + void *data); +}; + +extern int +register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + void *data); +extern void +unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + void *data); +extern void +unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops); +extern void unregister_ftrace_function_probe_all(char *glob); + enum { FTRACE_FL_FREE = (1 << 0), FTRACE_FL_FAILED = (1 << 1), diff --cc kernel/trace/ftrace.c index cf59f4c5474,11ad796ca04..5a3a06b21ee --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@@ -530,37 -531,44 +530,40 @@@ __ftrace_replace_code(struct dyn_ftrac static void ftrace_replace_code(int enable) { - int i, failed; struct dyn_ftrace *rec; struct ftrace_page *pg; + int failed; - for (pg = ftrace_pages_start; pg; pg = pg->next) { - for (i = 0; i < pg->index; i++) { - rec = &pg->records[i]; - - /* - * Skip over free records and records that have - * failed. - */ - if (rec->flags & FTRACE_FL_FREE || - rec->flags & FTRACE_FL_FAILED) - continue; + do_for_each_ftrace_rec(pg, rec) { + /* + * 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 */ - if (get_kprobe((void *)rec->ip)) { - freeze_record(rec); - continue; - } else { - unfreeze_record(rec); - } + /* ignore updates to this record's mcount site */ + if (get_kprobe((void *)rec->ip)) { + freeze_record(rec); + continue; + } else { + unfreeze_record(rec); + } - failed = __ftrace_replace_code(rec, enable); - if (failed && (rec->flags & FTRACE_FL_CONVERTED)) { - rec->flags |= FTRACE_FL_FAILED; - if ((system_state == SYSTEM_BOOTING) || - !core_kernel_text(rec->ip)) { - ftrace_free_rec(rec); + failed = __ftrace_replace_code(rec, enable); + if (failed && (rec->flags & FTRACE_FL_CONVERTED)) { + rec->flags |= FTRACE_FL_FAILED; + if ((system_state == SYSTEM_BOOTING) || + !core_kernel_text(rec->ip)) { + ftrace_free_rec(rec); - } else + } else { - ftrace_bug(failed, rec->ip); + ftrace_bug(failed, rec->ip); + /* Stop processing */ + return; + } - } } - } + } while_for_each_ftrace_rec(); } static int