tracing: updates for 2.6.32
Subsystems (3)
Steven Rostedt
maintainerIngo,
Please pull the latest tip/tracing/core tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/tracing/core
Josh Triplett (1):
tracing: Add vim script to enable folding for function_graph traces
Li Zefan (3):
tracing/filters: Add filter_type to struct ftrace_event_field tracing/filters: Add __field_ext() to TRACE_EVENT tracing/filters: Support filtering for char * strings
Steven Rostedt (2):
tracing/sched: show CPU task wakes up on in trace event
tracing: add comments to explain TRACE_EVENT out of protection
Xiao Guangrong (1):
tracing/events: fix the include file dependencies
Zhaolei (1):
ftrace: Move setting of clock-source out of options
----
Documentation/trace/function-graph-fold.vim | 42 ++++++++++++ include/linux/ftrace_event.h | 10 +++- include/linux/tracepoint.h | 12 +++- include/trace/define_trace.h | 1 + include/trace/events/sched.h | 12 +++- include/trace/ftrace.h | 31 +++++++-- kernel/trace/trace.c | 92 ++++++++++++++++++++++----- kernel/trace/trace.h | 9 ++- kernel/trace/trace_events.c | 11 +++- kernel/trace/trace_events_filter.c | 47 ++++++++++---- kernel/trace/trace_export.c | 8 ++- kernel/trace/trace_syscalls.c | 6 +- 12 files changed, 226 insertions(+), 55 deletions(-)
Steven Rostedt
maintainerPATCH 1/8 tracing/sched: show CPU task wakes up on in trace event
From: Steven Rostedt <[email protected]>
While debugging the scheduler push / pull algorithm, I found it very annoying that the sched wake up events did not show the CPU that the task was waking on. In order to analyze the scheduler, I needed that information.
This patch adds recording of the CPU that a task is waking up on.
--- include/trace/events/sched.h | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-)
include/trace/events/sched.h +8 -4
@@ -94,6 +94,7 @@ TRACE_EVENT(sched_wakeup, __field( pid_t, pid ) __field( int, prio ) __field( int, success ) +__field ( int, cpu ) ), TP_fast_assign(
@@ -101,11 +102,12 @@ TRACE_EVENT(sched_wakeup, __entry->pid = p->pid; __entry->prio = p->prio; __entry->success = success; + __entry->cpu =task_cpu (p); ), -TP_printk ("task %s:%d [%d] success=%d" , +TP_printk ("task %s:%d [%d] success=%d [%03d]" , __entry->comm, __entry->pid, __entry->prio, - __entry->success) + __entry->success, __entry->cpu) );/*
@@ -125,6 +127,7 @@ TRACE_EVENT(sched_wakeup_new, __field( pid_t, pid ) __field( int, prio ) __field( int, success ) +__field ( int, cpu ) ), TP_fast_assign(
@@ -132,11 +135,12 @@ TRACE_EVENT(sched_wakeup_new, __entry->pid = p->pid; __entry->prio = p->prio; __entry->success = success; + __entry->cpu =task_cpu (p); ), -TP_printk ("task %s:%d [%d] success=%d" , +TP_printk ("task %s:%d [%d] success=%d [%03d]" , __entry->comm, __entry->pid, __entry->prio, - __entry->success) + __entry->success, __entry->cpu) );/*
Signature · 3 lines
1.6.3.3 --
Steven Rostedt
maintainerPATCH 2/8 tracing: Add vim script to enable folding for function_graph traces
In reply to Steven RostedtFrom: Josh Triplett <[email protected]>
function_graph traces look like nested function calls, complete with braces denoting the start and end of functions. function-graph-fold.vim teaches vim how to fold these functions, to make it more convenient to browse them.
To use, :source function-graph-fold.vim while viewing a function_graph trace, or use "view -S function-graph-fold.vim some-trace" to load it from the command-line together with a trace. You can then use the usual vim fold commands, such as "za", to open and close nested functions. While closed, a fold will show the total time taken for a call, as would normally appear on the line with the closing brace. Folded functions will not include finish_task_switch(), so folding should remain relatively sane even through a context switch.
Note that this will almost certainly only work well with a single-CPU trace (e.g. trace-cmd report --cpu 1). It also takes some time to run (a few seconds for a large trace on my laptop). Nevertheless, I found it very handy to get an overview of a trace and then drill down on problematic calls.
LKML-Reference: <20090806145701.GB7661@feather>
--- Documentation/trace/function-graph-fold.vim | 42 +++++++++++++++++++++++++++ 1 files changed, 42 insertions(+), 0 deletions(-) create mode 100644 Documentation/trace/function-graph-fold.vim
Documentation/trace/function-graph-fold.vim new file +42 -0
@@ -0,0 +1,42 @@ +" Enable folding for ftrace function_graph traces. +" +" To use, :source this file while viewing a function_graph trace, or use vim's +" -S option to load from the command-line together with a trace. You can then +" use the usual vim fold commands, such as "za", to open and close nested +" functions. While closed, a fold will show the total time taken for a call, +" as would normally appear on the line with the closing brace. Folded +" functions will not include finish_task_switch(), so folding should remain +" relatively sane even through a context switch. +" +" Note that this will almost certainly only work well with a +" single-CPU trace (e.g. trace-cmd report --cpu 1). + +function! FunctionGraphFoldExpr(lnum) + let line = getline(a:lnum) + if line[-1:] == '{' + if line =~ 'finish_task_switch() {$' + return '>1' + endif + return 'a1' + elseif line[-1:] == '}' + return 's1' + else + return '=' + endif +endfunction + +function! FunctionGraphFoldText() + let s = split(getline(v:foldstart), '|', 1) + if getline(v:foldend+1) =~ 'finish_task_switch() {$' + let s[2] = ' task switch ' + else + let e = split(getline(v:foldend), '|', 1) + let s[2] = e[2] + endif + return join(s, '|') +endfunction + +setlocal foldexpr=FunctionGraphFoldExpr(v:lnum) +setlocal foldtext=FunctionGraphFoldText() +setlocal foldcolumn=12 +setlocal foldmethod=expr
Signature · 3 lines
1.6.3.3 --
Steven Rostedt
maintainerPATCH 3/8 tracing/filters: Add filter_type to struct ftrace_event_field
In reply to Steven RostedtFrom: Li Zefan <[email protected]>
The type of a field is stored as a string in @type, and here we add @filter_type which is an enum value.
This prepares for later patches, so we can specifically assign different @filter_type for the same @type.
For example normally a "char *" field is treated as a ptr, but we may want it to be treated as a string when doing filting.
LKML-Reference: <[email protected]>
--- kernel/trace/trace.h | 2 ++ kernel/trace/trace_events.c | 2 ++ kernel/trace/trace_events_filter.c | 23 ++++++++++++++--------- 3 files changed, 18 insertions(+), 9 deletions(-)
kernel/trace/trace.h +2 -0
@@ -755,6 +755,7 @@ struct ftrace_event_field {struct list_head link;char *name;char *type; +int filter_type;int offset;int size;int is_signed;
@@ -800,6 +801,7 @@ extern int apply_subsystem_event_filter(struct event_subsystem *system, char *filter_string);extern void print_subsystem_event_filter (struct event_subsystem *system,struct trace_seq *s); +extern int filter_assign_type (const char *type); static inline int filter_check_discard(struct ftrace_event_call *call, void *rec,
kernel/trace/trace_events.c +2 -0
@@ -44,9 +44,11 @@ int trace_define_field(struct ftrace_event_call *call, const char *type,if (!field->type) goto err; + field->filter_type =filter_assign_type (type); field->offset = offset; field->size = size; field->is_signed = is_signed; +list_add (&field->link, &call->fields);return 0 ;
kernel/trace/trace_events_filter.c +14 -9
@@ -476,11 +476,12 @@ static int filter_add_pred_fn(struct filter_parse_state *ps, }enum { -FILTER_STATIC_STRING =1 , -FILTER_DYN_STRING +FILTER_OTHER =0 , +FILTER_STATIC_STRING , +FILTER_DYN_STRING , }; -static int is_string_field (const char *type) +int filter_assign_type (const char *type) {if (strstr (type,"__data_loc" ) &&strstr (type,"char" ))return FILTER_DYN_STRING ;
@@ -488,12 +489,18 @@ static int is_string_field(const char *type)if (strchr (type,'[' ) &&strstr (type,"char" ))return FILTER_STATIC_STRING ; -return 0 ; +return FILTER_OTHER ; +} + +static bool is_string_field (struct ftrace_event_field *field) +{ +return field->filter_type ==FILTER_DYN_STRING || + field->filter_type ==FILTER_STATIC_STRING ; }static int is_legal_op (struct ftrace_event_field *field,int op) { -if (is_string_field (field->type) && (op !=OP_EQ && op !=OP_NE )) +if (is_string_field (field) && (op !=OP_EQ && op !=OP_NE ))return 0 ;return 1 ;
@@ -550,7 +557,6 @@ static int filter_add_pred(struct filter_parse_state *ps,struct ftrace_event_field *field;filter_pred_fn_t fn;unsigned long long val; -int string_type;int ret; pred->fn = filter_pred_none;
@@ -578,9 +584,8 @@ static int filter_add_pred(struct filter_parse_state *ps,return -EINVAL ; } - string_type =is_string_field (field->type); -if (string_type) { -if (string_type ==FILTER_STATIC_STRING ) +if (is_string_field (field)) { +if (field->filter_type ==FILTER_STATIC_STRING ) fn = filter_pred_string;else fn = filter_pred_strloc;
Signature · 3 lines
1.6.3.3 --
Steven Rostedt
maintainerPATCH 4/8 tracing/filters: Add __field_ext() to TRACE_EVENT
In reply to Steven RostedtFrom: Li Zefan <[email protected]>
Add __field_ext(), so a field can be assigned to a specific filter_type, which matches a corresponding filter function.
For example, a later patch will allow this:
__field_ext(const char *, str, FILTER_PTR_STR);
LKML-Reference: <[email protected]>
[
Fixed a -1 to FILTER_OTHER
Forward ported to latest kernel.
]
--- include/linux/ftrace_event.h | 9 ++++++++- include/trace/ftrace.h | 31 ++++++++++++++++++++++++------- kernel/trace/trace_events.c | 11 ++++++++--- kernel/trace/trace_events_filter.c | 6 ------ kernel/trace/trace_export.c | 8 +++++--- kernel/trace/trace_syscalls.c | 6 ++++-- 6 files changed, 49 insertions(+), 22 deletions(-)
include/linux/ftrace_event.h +8 -1
@@ -140,9 +140,16 @@ extern int filter_current_check_discard(struct ftrace_event_call *call,void *rec, struct ring_buffer_event *event); +enum { +FILTER_OTHER =0 , +FILTER_STATIC_STRING , +FILTER_DYN_STRING , +}; +extern int trace_define_field (struct ftrace_event_call *call,const char *type,const char *name, -int offset,int size,int is_signed); +int offset,int size,int is_signed, +int filter_type);extern int trace_define_common_fields (struct ftrace_event_call *call);#define is_signed_type (type) (((type)(-1)) < 0)
include/trace/ftrace.h +24 -7
@@ -21,6 +21,9 @@#undef __field#define __field (type, item) type item; +#undef __field_ext +#define __field_ext (type, item, filter_type) type item; +#undef __array#define __array (type, item, len) type item[len];
@@ -62,7 +65,10 @@*/ #undef __field -#define __field (type, item); +#define __field (type, item) + +#undef __field_ext +#define __field_ext (type, item, filter_type)#undef __array#define __array (type, item, len)
@@ -110,6 +116,9 @@if (!ret) \return 0 ; +#undef __field_ext +#define __field_ext (type, item, filter_type) __field(type, item) +#undef __array#define __array (type, item, len) \ ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
@@ -265,28 +274,33 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \#include TRACE_INCLUDE (TRACE_INCLUDE_FILE ) -#undef __field -#define __field (type, item) \ +#undef __field_ext +#define __field_ext (type, item, filter_type) \ ret = trace_define_field(event_call, #type, #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), is_signed_type(type)); \ + sizeof(field.item), \ + is_signed_type(type), filter_type); \ if (ret) \ return ret; +#undef __field +#define __field (type, item) __field_ext(type, item, FILTER_OTHER) +#undef __array#define __array (type, item, len) \ BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ ret = trace_define_field(event_call, #type "[" #len "]", #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), 0); \ + sizeof(field.item), 0, FILTER_OTHER); \ if (ret) \ return ret;#undef __dynamic_array#define __dynamic_array (type, item, len) \ ret = trace_define_field(event_call, "__data_loc " #type "[]", #item, \ - offsetof(typeof(field), __data_loc_##item), \ - sizeof(field.__data_loc_##item), 0); + offsetof(typeof(field), __data_loc_##item), \ + sizeof(field.__data_loc_##item), 0, \ + FILTER_OTHER);#undef __string#define __string (item, src) __dynamic_array(char, item, -1)
@@ -320,6 +334,9 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \#undef __field#define __field (type, item) +#undef __field_ext +#define __field_ext (type, item, filter_type) +#undef __array#define __array (type, item, len)
kernel/trace/trace_events.c +8 -3
@@ -28,7 +28,8 @@ DEFINE_MUTEX(event_mutex);LIST_HEAD (ftrace_events);int trace_define_field (struct ftrace_event_call *call,const char *type, -const char *name,int offset,int size,int is_signed) +const char *name,int offset,int size,int is_signed, +int filter_type) {struct ftrace_event_field *field;
@@ -44,7 +45,11 @@ int trace_define_field(struct ftrace_event_call *call, const char *type,if (!field->type) goto err; - field->filter_type =filter_assign_type (type); +if (filter_type ==FILTER_OTHER ) + field->filter_type =filter_assign_type (type); +else + field->filter_type = filter_type; + field->offset = offset; field->size = size; field->is_signed = is_signed;
@@ -68,7 +73,7 @@ EXPORT_SYMBOL_GPL(trace_define_field); ret = trace_define_field(call, #type, "common_" #item, \ offsetof(typeof(ent), item), \ sizeof(ent.item), \ - is_signed_type(type)); \ + is_signed_type(type), FILTER_OTHER); \ if (ret) \ return ret;
kernel/trace/trace_events_filter.c +0 -6
@@ -475,12 +475,6 @@ static int filter_add_pred_fn(struct filter_parse_state *ps,return 0 ; } -enum { -FILTER_OTHER =0 , -FILTER_STATIC_STRING , -FILTER_DYN_STRING , -}; -int filter_assign_type (const char *type) {if (strstr (type,"__data_loc" ) &&strstr (type,"char" ))
kernel/trace/trace_export.c +5 -3
@@ -158,7 +158,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \#define TRACE_FIELD (type, item, assign) \ ret = trace_define_field(event_call, #type, #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), is_signed_type(type)); \ + sizeof(field.item), \ + is_signed_type(type), FILTER_OTHER); \ if (ret) \ return ret;
@@ -166,7 +167,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \#define TRACE_FIELD_SPECIAL (type, item, len, cmd) \ ret = trace_define_field(event_call, #type "[" #len "]", #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), 0); \ + sizeof(field.item), 0, FILTER_OTHER); \ if (ret) \ return ret;
@@ -174,7 +175,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \#define TRACE_FIELD_SIGN (type, item, assign, is_signed) \ ret = trace_define_field(event_call, #type, #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), is_signed); \ + sizeof(field.item), is_signed, \ + FILTER_OTHER); \ if (ret) \ return ret;
kernel/trace/trace_syscalls.c +4 -2
@@ -194,7 +194,8 @@ int syscall_enter_define_fields(struct ftrace_event_call *call)for (i =0 ; i < meta->nb_args; i++) { ret =trace_define_field (call, meta->types[i], meta->args[i], offset, -sizeof (unsigned long ),0 ); +sizeof (unsigned long ),0 , +FILTER_OTHER ); offset +=sizeof (unsigned long ); }
@@ -210,7 +211,8 @@ int syscall_exit_define_fields(struct ftrace_event_call *call)if (ret)return ret; - ret = trace_define_field(call, SYSCALL_FIELD(unsigned long, ret), 0); + ret = trace_define_field(call, SYSCALL_FIELD(unsigned long, ret), 0, +FILTER_OTHER );return ret; }
Signature · 3 lines
1.6.3.3 --
Steven Rostedt
maintainerPATCH 5/8 tracing/filters: Support filtering for char patches prog prog2 quilt-mail x strings
In reply to Steven RostedtFrom: Li Zefan <[email protected]>
Usually, char * entries are dangerous in traces because the string can be released whereas a pointer to it can still wait to be read from the ring buffer.
But sometimes we can assume it's safe, like in case of RO data (eg: __file__ or __line__, used in bkl trace event). If these RO data are in a module and so is the call to the trace event, then it's safe, because the ring buffer will be flushed once this module get unloaded.
To allow char * to be treated as a string:
TRACE_EVENT(..., TP_STRUCT__entry( __field_ext(const char *, name, FILTER_PTR_STRING) ... ) ... );
The filtering will not dereference "char *" unless the developer explicitly sets FILTER_PTR_STR in __field_ext.
LKML-Reference: <[email protected]>
--- include/linux/ftrace_event.h | 1 + kernel/trace/trace_events_filter.c | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-)
include/linux/ftrace_event.h +1 -0
@@ -144,6 +144,7 @@ enum {FILTER_OTHER =0 ,FILTER_STATIC_STRING ,FILTER_DYN_STRING , + FILTER_PTR_STRING, }; extern int trace_define_field(struct ftrace_event_call *call,
kernel/trace/trace_events_filter.c +23 -3
@@ -163,6 +163,20 @@ static int filter_pred_string(struct filter_pred *pred, void *event,return match; } +/* Filter predicate for char * pointers */ +static int filter_pred_pchar (struct filter_pred *pred,void *event, +int val1,int val2) +{ +char **addr = (char **)(event + pred->offset); +int cmp, match; + + cmp =strncmp (*addr, pred->str_val, pred->str_len); + + match = (!cmp) ^ pred->not; + +return match; +} +/* * Filter predicate for dynamic sized arrays of characters. * These are implemented through a list of strings at the end
@@ -489,7 +503,8 @@ int filter_assign_type(const char *type)static bool is_string_field (struct ftrace_event_field *field) {return field->filter_type ==FILTER_DYN_STRING || - field->filter_type ==FILTER_STATIC_STRING ; + field->filter_type ==FILTER_STATIC_STRING || + field->filter_type ==FILTER_PTR_STRING ; }static int is_legal_op (struct ftrace_event_field *field,int op)
@@ -579,11 +594,16 @@ static int filter_add_pred(struct filter_parse_state *ps, }if (is_string_field (field)) { + pred->str_len = field->size; +if (field->filter_type ==FILTER_STATIC_STRING ) fn = filter_pred_string; -else +else if (field->filter_type ==FILTER_DYN_STRING ) fn = filter_pred_strloc; - pred->str_len = field->size; +else { + fn = filter_pred_pchar; + pred->str_len =strlen (pred->str_val); + } }else {if (field->is_signed) ret =strict_strtoll (pred->str_val,0 , &val);
Signature · 3 lines
1.6.3.3 --
Steven Rostedt
maintainerPATCH 6/8 ftrace: Move setting of clock-source out of options
In reply to Steven RostedtFrom: Zhaolei <[email protected]>
There are many clock sources for the tracing system but we can only enable/disable one at a time with the trace/options file.
We can move the setting of clock-source out of options and add a separate file for it:
# cat trace_clock [local] global # echo global > trace_clock # cat trace_clock local [global]
LKML-Reference: <[email protected]>
--- kernel/trace/trace.c | 92 ++++++++++++++++++++++++++++++++++++++++--------- kernel/trace/trace.h | 7 ++-- 2 files changed, 79 insertions(+), 20 deletions(-)
kernel/trace/trace.c +75 -17
@@ -323,12 +323,21 @@ static const char *trace_options[] = {"printk-msg-only" ,"context-info" ,"latency-format" , -"global-clock" ,"sleep-time" ,"graph-time" , NULL }; +static struct { +u64 (*func)(void ); +const char *name; +} trace_clocks[] = { + { trace_clock_local,"local" }, + { trace_clock_global,"global" }, +}; + +int trace_clock_id; +/* * ftrace_max_lock is used to protect the swapping of buffers * when taking a max snapshot. The buffers themselves are
@@ -2159,22 +2168,6 @@ static void set_tracer_flags(unsigned int mask, int enabled) trace_flags |= mask; else trace_flags &= ~mask; - -if (mask ==TRACE_ITER_GLOBAL_CLK ) { -u64 (*func)(void); - -if (enabled) - func = trace_clock_global; -else - func = trace_clock_local; - -mutex_lock (&trace_types_lock); -ring_buffer_set_clock (global_trace.buffer, func); - -if (max_tr.buffer) -ring_buffer_set_clock (max_tr.buffer, func); -mutex_unlock (&trace_types_lock); - } } static ssize_t
@@ -3142,6 +3135,62 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,return cnt; } +static ssize_t tracing_clock_read (struct file *filp,char __user *ubuf, +size_t cnt,loff_t *ppos) +{ +char buf[64 ]; +int bufiter =0 ; +int i; + +for (i =0 ; i <ARRAY_SIZE (trace_clocks); i++) + bufiter +=snprintf (buf + bufiter,sizeof (buf) - bufiter, +"%s%s%s%s" , i ?" " :"" , + i == trace_clock_id ?"[" :"" , trace_clocks[i].name, + i == trace_clock_id ?"]" :"" ); + bufiter +=snprintf (buf + bufiter,sizeof (buf) - bufiter,"\n" ); + +return simple_read_from_buffer (ubuf, cnt, ppos, buf, bufiter); +} + +static ssize_t tracing_clock_write (struct file *filp,const char __user *ubuf, +size_t cnt,loff_t *fpos) +{ +char buf[64 ]; +const char *clockstr; +int i; + +if (cnt >=sizeof (buf)) +return -EINVAL ; + +if (copy_from_user (&buf, ubuf, cnt)) +return -EFAULT ; + + buf[cnt] =0 ; + + clockstr =strstrip (buf); + +for (i =0 ; i <ARRAY_SIZE (trace_clocks); i++) { +if (strcmp (trace_clocks[i].name, clockstr) ==0 ) +break ; + } +if (i ==ARRAY_SIZE (trace_clocks)) +return -EINVAL ; + + trace_clock_id = i; + +mutex_lock (&trace_types_lock); + +ring_buffer_set_clock (global_trace.buffer, trace_clocks[i].func); +if (max_tr.buffer) +ring_buffer_set_clock (max_tr.buffer, trace_clocks[i].func); + +mutex_unlock (&trace_types_lock); + + *fpos += cnt; + +return cnt; +} +static const struct file_operations tracing_max_lat_fops = { .open = tracing_open_generic, .read = tracing_max_lat_read,
@@ -3179,6 +3228,12 @@ static const struct file_operations tracing_mark_fops = { .write = tracing_mark_write, }; +static const struct file_operations trace_clock_fops = { + .open = tracing_open_generic, + .read = tracing_clock_read, + .write = tracing_clock_write, +}; +struct ftrace_buffer_info {struct trace_array *tr;void *spare;
@@ -3918,6 +3973,9 @@ static __init int tracer_init_debugfs(void)trace_create_file ("saved_cmdlines" ,0444 , d_tracer,NULL , &tracing_saved_cmdlines_fops); +trace_create_file ("trace_clock" ,0644 , d_tracer,NULL , + &trace_clock_fops); +#ifdef CONFIG_DYNAMIC_FTRACE trace_create_file ("dyn_ftrace_total_info" ,0444 , d_tracer, &ftrace_update_tot_cnt, &tracing_dyn_info_fops);
kernel/trace/trace.h +4 -3
@@ -568,6 +568,8 @@ trace_vprintk(unsigned long ip, const char *fmt, va_list args);extern unsigned long trace_flags; +extern int trace_clock_id; +/* Standard output formatting function used for function return traces */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER extern enum print_line_t print_graph_function (struct trace_iterator *iter);
@@ -656,9 +658,8 @@ enum trace_iterator_flags {TRACE_ITER_PRINTK_MSGONLY =0x10000 ,TRACE_ITER_CONTEXT_INFO =0x20000 ,/* Print pid/cpu/time */ TRACE_ITER_LATENCY_FMT =0x40000 , -TRACE_ITER_GLOBAL_CLK =0x80000 , -TRACE_ITER_SLEEP_TIME =0x100000 , - TRACE_ITER_GRAPH_TIME = 0x200000, +TRACE_ITER_SLEEP_TIME =0x80000 , + TRACE_ITER_GRAPH_TIME = 0x100000, };/*
Signature · 3 lines
1.6.3.3 --
Steven Rostedt
maintainerPATCH 7/8 tracing/events: fix the include file dependencies
In reply to Steven RostedtFrom: Xiao Guangrong <[email protected]>
The TRACE_EVENT depends on the include/linux/tracepoint.h first and include/trace/ftrace.h later, if we include the ftrace.h early, a building error will occur.
Both define TRACE_EVENT in trace_a.h and trace_b.h, if we include those in .c file, like this:
#define CREATE_TRACE_POINTS
include <trace/events/trace_a.h>
include <trace/events/trace_b.h>
The above will not work, because the TRACE_EVENT was re-defined by the previous .h file.
LKML-Reference: <[email protected]>
--- include/linux/tracepoint.h | 3 +-- include/trace/define_trace.h | 1 + 2 files changed, 2 insertions(+), 2 deletions(-)
include/linux/tracepoint.h +1 -2
@@ -180,6 +180,7 @@ static inline void tracepoint_synchronize_unregister(void) } #define PARAMS(args...) args +#endif #ifndef TRACE_EVENT /*
@@ -287,5 +288,3 @@ static inline void tracepoint_synchronize_unregister(void)#define TRACE_EVENT (name, proto, args, struct, assign, print) \ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))#endif - -#endif
include/trace/define_trace.h +1 -0
@@ -56,6 +56,7 @@#include <trace/ftrace.h> #endif +#undef TRACE_EVENT#undef TRACE_HEADER_MULTI_READ/* Only undef what we defined in this file */
Signature · 3 lines
1.6.3.3 --
Steven Rostedt
maintainerPATCH 8/8 tracing: add comments to explain TRACE_EVENT out of protection
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The commit:
commit 5ac35daa9343936038a3c9c4f4d6d3fe6a2a7bd8
Author: Xiao Guangrong <[email protected]> tracing/events: fix the include file dependencies
Moved the TRACE_EVENT out of the ifdef protection of tracepoints.h but uses the define of TRACE_EVENT itself as protection. This patch adds comments to explain why.
--- include/linux/tracepoint.h | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-)
include/linux/tracepoint.h +11 -2
@@ -180,7 +180,15 @@ static inline void tracepoint_synchronize_unregister(void) } #define PARAMS(args...) args -#endif + +#endif /* _LINUX_TRACEPOINT_H */ + +/* +* Note: we keep the TRACE_EVENT outside the include file ifdef protection. +* This is due to the way trace events work. If a file includes two +* trace event headers under one "CREATE_TRACE_POINTS" the first include +* will override the TRACE_EVENT and break the second include. +*/ #ifndef TRACE_EVENT /*
@@ -287,4 +295,5 @@ static inline void tracepoint_synchronize_unregister(void)#define TRACE_EVENT (name, proto, args, struct, assign, print) \ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) -#endif + +#endif /* ifdef TRACE_EVENT (see note above) */
Signature · 3 lines
1.6.3.3 --
Quoted 7 lines · Steven Rostedt
Ingo,
Please pull the latest tip/tracing/core tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/tracing/core
Pulled, thanks a lot Steve!
Ingo