* [PATCH 0/8] [GIT PULL] TRACE_EVENT for modules
@ 2009-04-14 17:23 Steven Rostedt
2009-04-14 17:23 ` [PATCH 1/8] tracing: consolidate trace and trace_event headers Steven Rostedt
` (10 more replies)
0 siblings, 11 replies; 60+ messages in thread
From: Steven Rostedt @ 2009-04-14 17:23 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra,
Frederic Weisbecker, Theodore Tso, Arjan van de Ven,
Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge,
Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro,
Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang,
Michael Rubin, Martin Bligh
Ingo,
This is the long awaited TRACE_EVENT for modules patch series.
Not only does it allow for modules to use the TRACE_EVENT infrastructure,
but it also cleans up the way TRACE_EVENTS are used in core kernel code.
Some of the clean ups are:
Removal of the two headers per trace system. No need to have
include/trace/sched.h and include/linux/sched_event_types.h
All the changes go into include/trace/sched.h. But note that how that
file is made is important. One could look at the sched.h file, or
skb.h, lockdep.h and kmem.h as an example.
Another clean up is that I got rid of the need to add these files
into include/trace/trace_events.h and include/trace/trace_event_types.h.
Those files have been deleted.
Another clean up is that we do not need to do the DEFINE_TRACE(name)
for every TRACE_EVENT (or TRACE_FORMAT and DECLARE_TRACE) in the
include/trace/ header. One only needs to define a CREATE_TRACE_POINTS
in one C file to do the work for them:
#define CREATE_TRACE_POINTS
#inlude <trace/sched.h>
That will do the DEFINE_TRACE for every defined trace item in sched.h.
I also removed the trace_events_stage_X.h files and combined them
into a include/trace/ftrace.h file.
I made sure that each stage did not break the code. Well, I tested
kmem at each level. kmem seems to be the most complex of the trace events.
At the end I made a module and tested it out as well. I even removed
the module as the trace was running. Note, if you remove the file
and view the trace, you will get something like:
<...>-4197 [002] 205.524992: Unknown type 47
<...>-4197 [002] 206.523325: Unknown type 47
<...>-4197 [002] 207.521665: Unknown type 47
<...>-4197 [002] 208.520118: Unknown type 47
The unknown type will appear. This is because the format to print the
string is in the module itself. When the code is removed, ftrace has
no way of knowing how to print that string out. But if you had a user
space tool that read the format file first, it could still parse the binary
data just fine.
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
Steven Rostedt (8):
tracing: consolidate trace and trace_event headers
tracing: create automated trace defines
tracing: make trace_seq operations available for core kernel
tracing/events: move declarations from trace directory to core include
tracing/events: move the ftrace event tracing code to core
tracing/events: convert event call sites to use a link list
tracing/events: add export symbols for trace events in modules
tracing/events: add support for modules to TRACE_EVENT
----
include/linux/ftrace_event.h | 150 +++++++++++
include/linux/module.h | 4 +
include/linux/trace_seq.h | 91 +++++++
include/linux/tracepoint.h | 9 +-
include/trace/define_trace.h | 79 ++++++
include/trace/ftrace.h | 493 +++++++++++++++++++++++++++++++++++
include/trace/irq.h | 56 ++++-
include/trace/irq_event_types.h | 55 ----
include/trace/kmem.h | 189 +++++++++++++-
include/trace/lockdep.h | 55 ++++-
include/trace/lockdep_event_types.h | 57 ----
include/trace/sched.h | 336 +++++++++++++++++++++++-
include/trace/sched_event_types.h | 337 ------------------------
include/trace/skb.h | 39 +++-
include/trace/skb_event_types.h | 38 ---
include/trace/trace_event_types.h | 7 -
include/trace/trace_events.h | 7 -
kernel/exit.c | 4 -
kernel/fork.c | 2 -
kernel/irq/handle.c | 7 +-
kernel/kthread.c | 3 -
kernel/lockdep.c | 12 +-
kernel/module.c | 7 +
kernel/sched.c | 10 +-
kernel/signal.c | 2 -
kernel/softirq.c | 3 -
kernel/trace/Makefile | 1 -
kernel/trace/events.c | 14 -
kernel/trace/trace.c | 3 +
kernel/trace/trace.h | 148 +----------
kernel/trace/trace_event_profile.c | 4 +-
kernel/trace/trace_events.c | 170 +++++++++----
kernel/trace/trace_events_filter.c | 10 +-
kernel/trace/trace_events_stage_1.h | 39 ---
kernel/trace/trace_events_stage_2.h | 170 ------------
kernel/trace/trace_events_stage_3.h | 279 --------------------
kernel/trace/trace_output.c | 3 +
kernel/trace/trace_output.h | 30 +--
mm/util.c | 11 +-
net/core/net-traces.c | 4 +-
40 files changed, 1648 insertions(+), 1290 deletions(-)
--
^ permalink raw reply [flat|nested] 60+ messages in thread* [PATCH 1/8] tracing: consolidate trace and trace_event headers 2009-04-14 17:23 [PATCH 0/8] [GIT PULL] TRACE_EVENT for modules Steven Rostedt @ 2009-04-14 17:23 ` Steven Rostedt 2009-04-14 21:51 ` Frederic Weisbecker 2009-04-14 17:23 ` [PATCH 2/8] tracing: create automated trace defines Steven Rostedt ` (9 subsequent siblings) 10 siblings, 1 reply; 60+ messages in thread From: Steven Rostedt @ 2009-04-14 17:23 UTC (permalink / raw) To: linux-kernel Cc: Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Jason Baron, Mathieu Desnoyers [-- Attachment #1: 0001-tracing-consolidate-trace-and-trace_event-headers.patch --] [-- Type: text/plain, Size: 34614 bytes --] From: Steven Rostedt <srostedt@redhat.com> Impact: clean up Neil Horman (et. al.) criticized the way the trace events were broken up into two files. The reason for that was that ftrace needed to separate out the declarations from where the #include <linux/tracepoint.h> was used. It then dawned on me that the tracepoint.h header only needs to define the TRACE_EVENT macro if it is not already defined. The solution is simply to test if TRACE_EVENT is defined, and if it is not then the linux/tracepoint.h header can define it. This change consolidates all the <traces>.h and <traces>_event_types.h into the <traces>.h file. Reported-by: Neil Horman <nhorman@tuxdriver.com> Reported-by: Theodore Tso <tytso@mit.edu> Reported-by: Jiaying Zhang <jiayingz@google.com> Cc: Zhaolei <zhaolei@cn.fujitsu.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Jason Baron <jbaron@redhat.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- include/linux/tracepoint.h | 9 +- include/trace/irq.h | 51 +++++- include/trace/irq_event_types.h | 55 ------ include/trace/kmem.h | 189 +++++++++++++++++++- include/trace/lockdep.h | 52 +++++- include/trace/lockdep_event_types.h | 57 ------ include/trace/sched.h | 333 ++++++++++++++++++++++++++++++++++- include/trace/sched_event_types.h | 337 ----------------------------------- include/trace/skb.h | 36 ++++- include/trace/skb_event_types.h | 38 ---- include/trace/trace_event_types.h | 7 - kernel/trace/events.c | 1 + kernel/trace/trace_events_stage_1.h | 4 +- kernel/trace/trace_events_stage_2.h | 8 +- kernel/trace/trace_events_stage_3.h | 4 +- 15 files changed, 663 insertions(+), 518 deletions(-) delete mode 100644 include/trace/irq_event_types.h delete mode 100644 include/trace/lockdep_event_types.h delete mode 100644 include/trace/sched_event_types.h delete mode 100644 include/trace/skb_event_types.h delete mode 100644 include/trace/trace_event_types.h diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index d35a7ee..4353f3f 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -31,6 +31,8 @@ struct tracepoint { * Keep in sync with vmlinux.lds.h. */ +#ifndef DECLARE_TRACE + #define TP_PROTO(args...) args #define TP_ARGS(args...) args @@ -114,6 +116,7 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end) { } #endif /* CONFIG_TRACEPOINTS */ +#endif /* DECLARE_TRACE */ /* * Connect a probe to a tracepoint. @@ -154,10 +157,13 @@ static inline void tracepoint_synchronize_unregister(void) } #define PARAMS(args...) args + +#ifndef TRACE_FORMAT #define TRACE_FORMAT(name, proto, args, fmt) \ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) +#endif - +#ifndef TRACE_EVENT /* * For use with the TRACE_EVENT macro: * @@ -262,5 +268,6 @@ 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 diff --git a/include/trace/irq.h b/include/trace/irq.h index ff5d449..04ab4c6 100644 --- a/include/trace/irq.h +++ b/include/trace/irq.h @@ -1,9 +1,54 @@ -#ifndef _TRACE_IRQ_H +#if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_IRQ_H -#include <linux/interrupt.h> #include <linux/tracepoint.h> +#include <linux/interrupt.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM irq + +/* + * Tracepoint for entry of interrupt handler: + */ +TRACE_FORMAT(irq_handler_entry, + TP_PROTO(int irq, struct irqaction *action), + TP_ARGS(irq, action), + TP_FMT("irq=%d handler=%s", irq, action->name) + ); + +/* + * Tracepoint for return of an interrupt handler: + */ +TRACE_EVENT(irq_handler_exit, + + TP_PROTO(int irq, struct irqaction *action, int ret), + + TP_ARGS(irq, action, ret), + + TP_STRUCT__entry( + __field( int, irq ) + __field( int, ret ) + ), + + TP_fast_assign( + __entry->irq = irq; + __entry->ret = ret; + ), + + TP_printk("irq=%d return=%s", + __entry->irq, __entry->ret ? "handled" : "unhandled") +); + +TRACE_FORMAT(softirq_entry, + TP_PROTO(struct softirq_action *h, struct softirq_action *vec), + TP_ARGS(h, vec), + TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) + ); -#include <trace/irq_event_types.h> +TRACE_FORMAT(softirq_exit, + TP_PROTO(struct softirq_action *h, struct softirq_action *vec), + TP_ARGS(h, vec), + TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) + ); #endif diff --git a/include/trace/irq_event_types.h b/include/trace/irq_event_types.h deleted file mode 100644 index 85964eb..0000000 --- a/include/trace/irq_event_types.h +++ /dev/null @@ -1,55 +0,0 @@ - -/* use <trace/irq.h> instead */ -#ifndef TRACE_FORMAT -# error Do not include this file directly. -# error Unless you know what you are doing. -#endif - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM irq - -/* - * Tracepoint for entry of interrupt handler: - */ -TRACE_FORMAT(irq_handler_entry, - TP_PROTO(int irq, struct irqaction *action), - TP_ARGS(irq, action), - TP_FMT("irq=%d handler=%s", irq, action->name) - ); - -/* - * Tracepoint for return of an interrupt handler: - */ -TRACE_EVENT(irq_handler_exit, - - TP_PROTO(int irq, struct irqaction *action, int ret), - - TP_ARGS(irq, action, ret), - - TP_STRUCT__entry( - __field( int, irq ) - __field( int, ret ) - ), - - TP_fast_assign( - __entry->irq = irq; - __entry->ret = ret; - ), - - TP_printk("irq=%d return=%s", - __entry->irq, __entry->ret ? "handled" : "unhandled") -); - -TRACE_FORMAT(softirq_entry, - TP_PROTO(struct softirq_action *h, struct softirq_action *vec), - TP_ARGS(h, vec), - TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) - ); - -TRACE_FORMAT(softirq_exit, - TP_PROTO(struct softirq_action *h, struct softirq_action *vec), - TP_ARGS(h, vec), - TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) - ); - -#undef TRACE_SYSTEM diff --git a/include/trace/kmem.h b/include/trace/kmem.h index 46efc24..d7d1218 100644 --- a/include/trace/kmem.h +++ b/include/trace/kmem.h @@ -1,9 +1,192 @@ -#ifndef _TRACE_KMEM_H +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_KMEM_H #include <linux/types.h> #include <linux/tracepoint.h> -#include <trace/kmem_event_types.h> +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kmem -#endif /* _TRACE_KMEM_H */ +TRACE_EVENT(kmalloc, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + __entry->bytes_req = bytes_req; + __entry->bytes_alloc = bytes_alloc; + __entry->gfp_flags = gfp_flags; + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + __entry->gfp_flags) +); + +TRACE_EVENT(kmem_cache_alloc, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + __entry->bytes_req = bytes_req; + __entry->bytes_alloc = bytes_alloc; + __entry->gfp_flags = gfp_flags; + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + __entry->gfp_flags) +); + +TRACE_EVENT(kmalloc_node, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags, + int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + __field( int, node ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + __entry->bytes_req = bytes_req; + __entry->bytes_alloc = bytes_alloc; + __entry->gfp_flags = gfp_flags; + __entry->node = node; + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x node=%d", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + __entry->gfp_flags, + __entry->node) +); + +TRACE_EVENT(kmem_cache_alloc_node, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags, + int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + __field( int, node ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + __entry->bytes_req = bytes_req; + __entry->bytes_alloc = bytes_alloc; + __entry->gfp_flags = gfp_flags; + __entry->node = node; + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x node=%d", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + __entry->gfp_flags, + __entry->node) +); + +TRACE_EVENT(kfree, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + ), + + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) +); + +TRACE_EVENT(kmem_cache_free, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + ), + + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) +); + +#endif diff --git a/include/trace/lockdep.h b/include/trace/lockdep.h index 5ca67df..8ee7900 100644 --- a/include/trace/lockdep.h +++ b/include/trace/lockdep.h @@ -1,9 +1,57 @@ -#ifndef _TRACE_LOCKDEP_H +#if !defined(_TRACE_LOCKDEP_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_LOCKDEP_H #include <linux/lockdep.h> #include <linux/tracepoint.h> -#include <trace/lockdep_event_types.h> +#undef TRACE_SYSTEM +#define TRACE_SYSTEM lock + +#ifdef CONFIG_LOCKDEP + +TRACE_FORMAT(lock_acquire, + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, + int trylock, int read, int check, + struct lockdep_map *next_lock, unsigned long ip), + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), + TP_FMT("%s%s%s", trylock ? "try " : "", + read ? "read " : "", lock->name) + ); + +TRACE_FORMAT(lock_release, + TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip), + TP_ARGS(lock, nested, ip), + TP_FMT("%s", lock->name) + ); + +#ifdef CONFIG_LOCK_STAT + +TRACE_FORMAT(lock_contended, + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + TP_ARGS(lock, ip), + TP_FMT("%s", lock->name) + ); + +TRACE_EVENT(lock_acquired, + TP_PROTO(struct lockdep_map *lock, unsigned long ip, s64 waittime), + + TP_ARGS(lock, ip, waittime), + + TP_STRUCT__entry( + __field(const char *, name) + __field(unsigned long, wait_usec) + __field(unsigned long, wait_nsec_rem) + ), + TP_fast_assign( + __entry->name = lock->name; + __entry->wait_nsec_rem = do_div(waittime, NSEC_PER_USEC); + __entry->wait_usec = (unsigned long) waittime; + ), + TP_printk("%s (%lu.%03lu us)", __entry->name, __entry->wait_usec, + __entry->wait_nsec_rem) +); #endif +#endif + +#endif /* _TRACE_LOCKDEP_H */ diff --git a/include/trace/lockdep_event_types.h b/include/trace/lockdep_event_types.h deleted file mode 100644 index 863f1e4..0000000 --- a/include/trace/lockdep_event_types.h +++ /dev/null @@ -1,57 +0,0 @@ - -#ifndef TRACE_FORMAT -# error Do not include this file directly. -# error Unless you know what you are doing. -#endif - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM lock - -#ifdef CONFIG_LOCKDEP - -TRACE_FORMAT(lock_acquire, - TP_PROTO(struct lockdep_map *lock, unsigned int subclass, - int trylock, int read, int check, - struct lockdep_map *next_lock, unsigned long ip), - TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), - TP_FMT("%s%s%s", trylock ? "try " : "", - read ? "read " : "", lock->name) - ); - -TRACE_FORMAT(lock_release, - TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip), - TP_ARGS(lock, nested, ip), - TP_FMT("%s", lock->name) - ); - -#ifdef CONFIG_LOCK_STAT - -TRACE_FORMAT(lock_contended, - TP_PROTO(struct lockdep_map *lock, unsigned long ip), - TP_ARGS(lock, ip), - TP_FMT("%s", lock->name) - ); - -TRACE_EVENT(lock_acquired, - TP_PROTO(struct lockdep_map *lock, unsigned long ip, s64 waittime), - - TP_ARGS(lock, ip, waittime), - - TP_STRUCT__entry( - __field(const char *, name) - __field(unsigned long, wait_usec) - __field(unsigned long, wait_nsec_rem) - ), - TP_fast_assign( - __entry->name = lock->name; - __entry->wait_nsec_rem = do_div(waittime, NSEC_PER_USEC); - __entry->wait_usec = (unsigned long) waittime; - ), - TP_printk("%s (%lu.%03lu us)", __entry->name, __entry->wait_usec, - __entry->wait_nsec_rem) -); - -#endif -#endif - -#undef TRACE_SYSTEM diff --git a/include/trace/sched.h b/include/trace/sched.h index 4e372a1..5b1cf4a 100644 --- a/include/trace/sched.h +++ b/include/trace/sched.h @@ -1,9 +1,336 @@ -#ifndef _TRACE_SCHED_H +#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_SCHED_H #include <linux/sched.h> #include <linux/tracepoint.h> -#include <trace/sched_event_types.h> +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sched -#endif +/* + * Tracepoint for calling kthread_stop, performed to end a kthread: + */ +TRACE_EVENT(sched_kthread_stop, + + TP_PROTO(struct task_struct *t), + + TP_ARGS(t), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + ), + + TP_fast_assign( + memcpy(__entry->comm, t->comm, TASK_COMM_LEN); + __entry->pid = t->pid; + ), + + TP_printk("task %s:%d", __entry->comm, __entry->pid) +); + +/* + * Tracepoint for the return value of the kthread stopping: + */ +TRACE_EVENT(sched_kthread_stop_ret, + + TP_PROTO(int ret), + + TP_ARGS(ret), + + TP_STRUCT__entry( + __field( int, ret ) + ), + + TP_fast_assign( + __entry->ret = ret; + ), + + TP_printk("ret %d", __entry->ret) +); + +/* + * Tracepoint for waiting on task to unschedule: + * + * (NOTE: the 'rq' argument is not used by generic trace events, + * but used by the latency tracer plugin. ) + */ +TRACE_EVENT(sched_wait_task, + + TP_PROTO(struct rq *rq, struct task_struct *p), + + TP_ARGS(rq, p), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + ), + + TP_printk("task %s:%d [%d]", + __entry->comm, __entry->pid, __entry->prio) +); + +/* + * Tracepoint for waking up a task: + * + * (NOTE: the 'rq' argument is not used by generic trace events, + * but used by the latency tracer plugin. ) + */ +TRACE_EVENT(sched_wakeup, + + TP_PROTO(struct rq *rq, struct task_struct *p, int success), + + TP_ARGS(rq, p, success), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + __field( int, success ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + __entry->success = success; + ), + + TP_printk("task %s:%d [%d] success=%d", + __entry->comm, __entry->pid, __entry->prio, + __entry->success) +); + +/* + * Tracepoint for waking up a new task: + * + * (NOTE: the 'rq' argument is not used by generic trace events, + * but used by the latency tracer plugin. ) + */ +TRACE_EVENT(sched_wakeup_new, + + TP_PROTO(struct rq *rq, struct task_struct *p, int success), + + TP_ARGS(rq, p, success), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + __field( int, success ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + __entry->success = success; + ), + + TP_printk("task %s:%d [%d] success=%d", + __entry->comm, __entry->pid, __entry->prio, + __entry->success) +); + +/* + * Tracepoint for task switches, performed by the scheduler: + * + * (NOTE: the 'rq' argument is not used by generic trace events, + * but used by the latency tracer plugin. ) + */ +TRACE_EVENT(sched_switch, + + TP_PROTO(struct rq *rq, struct task_struct *prev, + struct task_struct *next), + + TP_ARGS(rq, prev, next), + + TP_STRUCT__entry( + __array( char, prev_comm, TASK_COMM_LEN ) + __field( pid_t, prev_pid ) + __field( int, prev_prio ) + __array( char, next_comm, TASK_COMM_LEN ) + __field( pid_t, next_pid ) + __field( int, next_prio ) + ), + + TP_fast_assign( + memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); + __entry->prev_pid = prev->pid; + __entry->prev_prio = prev->prio; + memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); + __entry->next_pid = next->pid; + __entry->next_prio = next->prio; + ), + + TP_printk("task %s:%d [%d] ==> %s:%d [%d]", + __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, + __entry->next_comm, __entry->next_pid, __entry->next_prio) +); + +/* + * Tracepoint for a task being migrated: + */ +TRACE_EVENT(sched_migrate_task, + + TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu), + + TP_ARGS(p, orig_cpu, dest_cpu), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + __field( int, orig_cpu ) + __field( int, dest_cpu ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + __entry->orig_cpu = orig_cpu; + __entry->dest_cpu = dest_cpu; + ), + + TP_printk("task %s:%d [%d] from: %d to: %d", + __entry->comm, __entry->pid, __entry->prio, + __entry->orig_cpu, __entry->dest_cpu) +); + +/* + * Tracepoint for freeing a task: + */ +TRACE_EVENT(sched_process_free, + + TP_PROTO(struct task_struct *p), + + TP_ARGS(p), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + ), + + TP_printk("task %s:%d [%d]", + __entry->comm, __entry->pid, __entry->prio) +); + +/* + * Tracepoint for a task exiting: + */ +TRACE_EVENT(sched_process_exit, + + TP_PROTO(struct task_struct *p), + + TP_ARGS(p), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + ), + + TP_printk("task %s:%d [%d]", + __entry->comm, __entry->pid, __entry->prio) +); + +/* + * Tracepoint for a waiting task: + */ +TRACE_EVENT(sched_process_wait, + + TP_PROTO(struct pid *pid), + + TP_ARGS(pid), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + ), + + TP_fast_assign( + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + __entry->pid = pid_nr(pid); + __entry->prio = current->prio; + ), + + TP_printk("task %s:%d [%d]", + __entry->comm, __entry->pid, __entry->prio) +); + +/* + * Tracepoint for do_fork: + */ +TRACE_EVENT(sched_process_fork, + + TP_PROTO(struct task_struct *parent, struct task_struct *child), + + TP_ARGS(parent, child), + + TP_STRUCT__entry( + __array( char, parent_comm, TASK_COMM_LEN ) + __field( pid_t, parent_pid ) + __array( char, child_comm, TASK_COMM_LEN ) + __field( pid_t, child_pid ) + ), + + TP_fast_assign( + memcpy(__entry->parent_comm, parent->comm, TASK_COMM_LEN); + __entry->parent_pid = parent->pid; + memcpy(__entry->child_comm, child->comm, TASK_COMM_LEN); + __entry->child_pid = child->pid; + ), + + TP_printk("parent %s:%d child %s:%d", + __entry->parent_comm, __entry->parent_pid, + __entry->child_comm, __entry->child_pid) +); + +/* + * Tracepoint for sending a signal: + */ +TRACE_EVENT(sched_signal_send, + + TP_PROTO(int sig, struct task_struct *p), + + TP_ARGS(sig, p), + + TP_STRUCT__entry( + __field( int, sig ) + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->sig = sig; + ), + + TP_printk("sig: %d task %s:%d", + __entry->sig, __entry->comm, __entry->pid) +); + +#endif /* _TRACE_SCHED_H */ diff --git a/include/trace/sched_event_types.h b/include/trace/sched_event_types.h deleted file mode 100644 index 63547dc..0000000 --- a/include/trace/sched_event_types.h +++ /dev/null @@ -1,337 +0,0 @@ - -/* use <trace/sched.h> instead */ -#ifndef TRACE_EVENT -# error Do not include this file directly. -# error Unless you know what you are doing. -#endif - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM sched - -/* - * Tracepoint for calling kthread_stop, performed to end a kthread: - */ -TRACE_EVENT(sched_kthread_stop, - - TP_PROTO(struct task_struct *t), - - TP_ARGS(t), - - TP_STRUCT__entry( - __array( char, comm, TASK_COMM_LEN ) - __field( pid_t, pid ) - ), - - TP_fast_assign( - memcpy(__entry->comm, t->comm, TASK_COMM_LEN); - __entry->pid = t->pid; - ), - - TP_printk("task %s:%d", __entry->comm, __entry->pid) -); - -/* - * Tracepoint for the return value of the kthread stopping: - */ -TRACE_EVENT(sched_kthread_stop_ret, - - TP_PROTO(int ret), - - TP_ARGS(ret), - - TP_STRUCT__entry( - __field( int, ret ) - ), - - TP_fast_assign( - __entry->ret = ret; - ), - - TP_printk("ret %d", __entry->ret) -); - -/* - * Tracepoint for waiting on task to unschedule: - * - * (NOTE: the 'rq' argument is not used by generic trace events, - * but used by the latency tracer plugin. ) - */ -TRACE_EVENT(sched_wait_task, - - TP_PROTO(struct rq *rq, struct task_struct *p), - - TP_ARGS(rq, p), - - TP_STRUCT__entry( - __array( char, comm, TASK_COMM_LEN ) - __field( pid_t, pid ) - __field( int, prio ) - ), - - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; - __entry->prio = p->prio; - ), - - TP_printk("task %s:%d [%d]", - __entry->comm, __entry->pid, __entry->prio) -); - -/* - * Tracepoint for waking up a task: - * - * (NOTE: the 'rq' argument is not used by generic trace events, - * but used by the latency tracer plugin. ) - */ -TRACE_EVENT(sched_wakeup, - - TP_PROTO(struct rq *rq, struct task_struct *p, int success), - - TP_ARGS(rq, p, success), - - TP_STRUCT__entry( - __array( char, comm, TASK_COMM_LEN ) - __field( pid_t, pid ) - __field( int, prio ) - __field( int, success ) - ), - - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; - __entry->prio = p->prio; - __entry->success = success; - ), - - TP_printk("task %s:%d [%d] success=%d", - __entry->comm, __entry->pid, __entry->prio, - __entry->success) -); - -/* - * Tracepoint for waking up a new task: - * - * (NOTE: the 'rq' argument is not used by generic trace events, - * but used by the latency tracer plugin. ) - */ -TRACE_EVENT(sched_wakeup_new, - - TP_PROTO(struct rq *rq, struct task_struct *p, int success), - - TP_ARGS(rq, p, success), - - TP_STRUCT__entry( - __array( char, comm, TASK_COMM_LEN ) - __field( pid_t, pid ) - __field( int, prio ) - __field( int, success ) - ), - - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; - __entry->prio = p->prio; - __entry->success = success; - ), - - TP_printk("task %s:%d [%d] success=%d", - __entry->comm, __entry->pid, __entry->prio, - __entry->success) -); - -/* - * Tracepoint for task switches, performed by the scheduler: - * - * (NOTE: the 'rq' argument is not used by generic trace events, - * but used by the latency tracer plugin. ) - */ -TRACE_EVENT(sched_switch, - - TP_PROTO(struct rq *rq, struct task_struct *prev, - struct task_struct *next), - - TP_ARGS(rq, prev, next), - - TP_STRUCT__entry( - __array( char, prev_comm, TASK_COMM_LEN ) - __field( pid_t, prev_pid ) - __field( int, prev_prio ) - __array( char, next_comm, TASK_COMM_LEN ) - __field( pid_t, next_pid ) - __field( int, next_prio ) - ), - - TP_fast_assign( - memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); - __entry->prev_pid = prev->pid; - __entry->prev_prio = prev->prio; - memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); - __entry->next_pid = next->pid; - __entry->next_prio = next->prio; - ), - - TP_printk("task %s:%d [%d] ==> %s:%d [%d]", - __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, - __entry->next_comm, __entry->next_pid, __entry->next_prio) -); - -/* - * Tracepoint for a task being migrated: - */ -TRACE_EVENT(sched_migrate_task, - - TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu), - - TP_ARGS(p, orig_cpu, dest_cpu), - - TP_STRUCT__entry( - __array( char, comm, TASK_COMM_LEN ) - __field( pid_t, pid ) - __field( int, prio ) - __field( int, orig_cpu ) - __field( int, dest_cpu ) - ), - - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; - __entry->prio = p->prio; - __entry->orig_cpu = orig_cpu; - __entry->dest_cpu = dest_cpu; - ), - - TP_printk("task %s:%d [%d] from: %d to: %d", - __entry->comm, __entry->pid, __entry->prio, - __entry->orig_cpu, __entry->dest_cpu) -); - -/* - * Tracepoint for freeing a task: - */ -TRACE_EVENT(sched_process_free, - - TP_PROTO(struct task_struct *p), - - TP_ARGS(p), - - TP_STRUCT__entry( - __array( char, comm, TASK_COMM_LEN ) - __field( pid_t, pid ) - __field( int, prio ) - ), - - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; - __entry->prio = p->prio; - ), - - TP_printk("task %s:%d [%d]", - __entry->comm, __entry->pid, __entry->prio) -); - -/* - * Tracepoint for a task exiting: - */ -TRACE_EVENT(sched_process_exit, - - TP_PROTO(struct task_struct *p), - - TP_ARGS(p), - - TP_STRUCT__entry( - __array( char, comm, TASK_COMM_LEN ) - __field( pid_t, pid ) - __field( int, prio ) - ), - - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; - __entry->prio = p->prio; - ), - - TP_printk("task %s:%d [%d]", - __entry->comm, __entry->pid, __entry->prio) -); - -/* - * Tracepoint for a waiting task: - */ -TRACE_EVENT(sched_process_wait, - - TP_PROTO(struct pid *pid), - - TP_ARGS(pid), - - TP_STRUCT__entry( - __array( char, comm, TASK_COMM_LEN ) - __field( pid_t, pid ) - __field( int, prio ) - ), - - TP_fast_assign( - memcpy(__entry->comm, current->comm, TASK_COMM_LEN); - __entry->pid = pid_nr(pid); - __entry->prio = current->prio; - ), - - TP_printk("task %s:%d [%d]", - __entry->comm, __entry->pid, __entry->prio) -); - -/* - * Tracepoint for do_fork: - */ -TRACE_EVENT(sched_process_fork, - - TP_PROTO(struct task_struct *parent, struct task_struct *child), - - TP_ARGS(parent, child), - - TP_STRUCT__entry( - __array( char, parent_comm, TASK_COMM_LEN ) - __field( pid_t, parent_pid ) - __array( char, child_comm, TASK_COMM_LEN ) - __field( pid_t, child_pid ) - ), - - TP_fast_assign( - memcpy(__entry->parent_comm, parent->comm, TASK_COMM_LEN); - __entry->parent_pid = parent->pid; - memcpy(__entry->child_comm, child->comm, TASK_COMM_LEN); - __entry->child_pid = child->pid; - ), - - TP_printk("parent %s:%d child %s:%d", - __entry->parent_comm, __entry->parent_pid, - __entry->child_comm, __entry->child_pid) -); - -/* - * Tracepoint for sending a signal: - */ -TRACE_EVENT(sched_signal_send, - - TP_PROTO(int sig, struct task_struct *p), - - TP_ARGS(sig, p), - - TP_STRUCT__entry( - __field( int, sig ) - __array( char, comm, TASK_COMM_LEN ) - __field( pid_t, pid ) - ), - - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; - __entry->sig = sig; - ), - - TP_printk("sig: %d task %s:%d", - __entry->sig, __entry->comm, __entry->pid) -); - -#undef TRACE_SYSTEM diff --git a/include/trace/skb.h b/include/trace/skb.h index d2de717..e6fd281 100644 --- a/include/trace/skb.h +++ b/include/trace/skb.h @@ -1,9 +1,37 @@ -#ifndef _TRACE_SKB_H_ -#define _TRACE_SKB_H_ +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SKB_H #include <linux/skbuff.h> #include <linux/tracepoint.h> -#include <trace/skb_event_types.h> +#undef TRACE_SYSTEM +#define TRACE_SYSTEM skb -#endif +/* + * Tracepoint for free an sk_buff: + */ +TRACE_EVENT(kfree_skb, + + TP_PROTO(struct sk_buff *skb, void *location), + + TP_ARGS(skb, location), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( unsigned short, protocol ) + __field( void *, location ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + if (skb) { + __entry->protocol = ntohs(skb->protocol); + } + __entry->location = location; + ), + + TP_printk("skbaddr=%p protocol=%u location=%p", + __entry->skbaddr, __entry->protocol, __entry->location) +); + +#endif /* _TRACE_SKB_H */ diff --git a/include/trace/skb_event_types.h b/include/trace/skb_event_types.h deleted file mode 100644 index 4a1c504..0000000 --- a/include/trace/skb_event_types.h +++ /dev/null @@ -1,38 +0,0 @@ - -/* use <trace/skb.h> instead */ -#ifndef TRACE_EVENT -# error Do not include this file directly. -# error Unless you know what you are doing. -#endif - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM skb - -/* - * Tracepoint for free an sk_buff: - */ -TRACE_EVENT(kfree_skb, - - TP_PROTO(struct sk_buff *skb, void *location), - - TP_ARGS(skb, location), - - TP_STRUCT__entry( - __field( void *, skbaddr ) - __field( unsigned short, protocol ) - __field( void *, location ) - ), - - TP_fast_assign( - __entry->skbaddr = skb; - if (skb) { - __entry->protocol = ntohs(skb->protocol); - } - __entry->location = location; - ), - - TP_printk("skbaddr=%p protocol=%u location=%p", - __entry->skbaddr, __entry->protocol, __entry->location) -); - -#undef TRACE_SYSTEM diff --git a/include/trace/trace_event_types.h b/include/trace/trace_event_types.h deleted file mode 100644 index 552a50e..0000000 --- a/include/trace/trace_event_types.h +++ /dev/null @@ -1,7 +0,0 @@ -/* trace/<type>_event_types.h here */ - -#include <trace/sched_event_types.h> -#include <trace/irq_event_types.h> -#include <trace/lockdep_event_types.h> -#include <trace/skb_event_types.h> -#include <trace/kmem_event_types.h> diff --git a/kernel/trace/events.c b/kernel/trace/events.c index 246f2aa..5a35a91 100644 --- a/kernel/trace/events.c +++ b/kernel/trace/events.c @@ -8,6 +8,7 @@ #include "trace_output.h" +#define TRACE_HEADER_MULTI_READ #include "trace_events_stage_1.h" #include "trace_events_stage_2.h" #include "trace_events_stage_3.h" diff --git a/kernel/trace/trace_events_stage_1.h b/kernel/trace/trace_events_stage_1.h index 38985f9..475f46a 100644 --- a/kernel/trace/trace_events_stage_1.h +++ b/kernel/trace/trace_events_stage_1.h @@ -1,7 +1,7 @@ /* * Stage 1 of the trace events. * - * Override the macros in <trace/trace_event_types.h> to include the following: + * Override the macros in <trace/trace_events.h> to include the following: * * struct ftrace_raw_<call> { * struct trace_entry ent; @@ -36,4 +36,4 @@ }; \ static struct ftrace_event_call event_##name -#include <trace/trace_event_types.h> +#include <trace/trace_events.h> diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h index 59cfd7d..aa4a67a 100644 --- a/kernel/trace/trace_events_stage_2.h +++ b/kernel/trace/trace_events_stage_2.h @@ -1,7 +1,7 @@ /* * Stage 2 of the trace events. * - * Override the macros in <trace/trace_event_types.h> to include the following: + * Override the macros in <trace/trace_events.h> to include the following: * * enum print_line_t * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags) @@ -64,7 +64,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ return TRACE_TYPE_HANDLED; \ } -#include <trace/trace_event_types.h> +#include <trace/trace_events.h> /* * Setup the showing format of trace point. @@ -128,7 +128,7 @@ ftrace_format_##call(struct trace_seq *s) \ return ret; \ } -#include <trace/trace_event_types.h> +#include <trace/trace_events.h> #undef __field #define __field(type, item) \ @@ -167,4 +167,4 @@ ftrace_define_fields_##call(void) \ return ret; \ } -#include <trace/trace_event_types.h> +#include <trace/trace_events.h> diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h index 5bb1b7f..45c04e1 100644 --- a/kernel/trace/trace_events_stage_3.h +++ b/kernel/trace/trace_events_stage_3.h @@ -1,7 +1,7 @@ /* * Stage 3 of the trace events. * - * Override the macros in <trace/trace_event_types.h> to include the following: + * Override the macros in <trace/trace_events.h> to include the following: * * static void ftrace_event_<call>(proto) * { @@ -272,7 +272,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ _TRACE_PROFILE_INIT(call) \ } -#include <trace/trace_event_types.h> +#include <trace/trace_events.h> #undef _TRACE_PROFILE #undef _TRACE_PROFILE_INIT -- 1.6.2.1 -- ^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [PATCH 1/8] tracing: consolidate trace and trace_event headers 2009-04-14 17:23 ` [PATCH 1/8] tracing: consolidate trace and trace_event headers Steven Rostedt @ 2009-04-14 21:51 ` Frederic Weisbecker 2009-04-14 22:04 ` Steven Rostedt 0 siblings, 1 reply; 60+ messages in thread From: Frederic Weisbecker @ 2009-04-14 21:51 UTC (permalink / raw) To: Steven Rostedt Cc: linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Jason Baron, Mathieu Desnoyers On Tue, Apr 14, 2009 at 01:23:38PM -0400, Steven Rostedt wrote: > From: Steven Rostedt <srostedt@redhat.com> > > Impact: clean up > > Neil Horman (et. al.) criticized the way the trace events were broken up > into two files. The reason for that was that ftrace needed to separate out > the declarations from where the #include <linux/tracepoint.h> was used. > It then dawned on me that the tracepoint.h header only needs to define the > TRACE_EVENT macro if it is not already defined. > > The solution is simply to test if TRACE_EVENT is defined, and if it is not > then the linux/tracepoint.h header can define it. This change consolidates > all the <traces>.h and <traces>_event_types.h into the <traces>.h file. > > Reported-by: Neil Horman <nhorman@tuxdriver.com> > Reported-by: Theodore Tso <tytso@mit.edu> > Reported-by: Jiaying Zhang <jiayingz@google.com> > Cc: Zhaolei <zhaolei@cn.fujitsu.com> > Cc: Frederic Weisbecker <fweisbec@gmail.com> > Cc: Peter Zijlstra <peterz@infradead.org> > Cc: Jason Baron <jbaron@redhat.com> > Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> > Signed-off-by: Steven Rostedt <rostedt@goodmis.org> > --- > include/linux/tracepoint.h | 9 +- > include/trace/irq.h | 51 +++++- > include/trace/irq_event_types.h | 55 ------ > include/trace/kmem.h | 189 +++++++++++++++++++- > include/trace/lockdep.h | 52 +++++- > include/trace/lockdep_event_types.h | 57 ------ > include/trace/sched.h | 333 ++++++++++++++++++++++++++++++++++- > include/trace/sched_event_types.h | 337 ----------------------------------- > include/trace/skb.h | 36 ++++- > include/trace/skb_event_types.h | 38 ---- > include/trace/trace_event_types.h | 7 - > kernel/trace/events.c | 1 + > kernel/trace/trace_events_stage_1.h | 4 +- > kernel/trace/trace_events_stage_2.h | 8 +- > kernel/trace/trace_events_stage_3.h | 4 +- > 15 files changed, 663 insertions(+), 518 deletions(-) > delete mode 100644 include/trace/irq_event_types.h > delete mode 100644 include/trace/lockdep_event_types.h > delete mode 100644 include/trace/sched_event_types.h > delete mode 100644 include/trace/skb_event_types.h > delete mode 100644 include/trace/trace_event_types.h I don't know if you use git-format-patch without -M or something else specific to git pull request. But it looks like the renames are not detected here, so it's a bit hard to know what have been actually happened or deleted in the end result. Thanks, Frederic. > diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h > index d35a7ee..4353f3f 100644 > --- a/include/linux/tracepoint.h > +++ b/include/linux/tracepoint.h > @@ -31,6 +31,8 @@ struct tracepoint { > * Keep in sync with vmlinux.lds.h. > */ > > +#ifndef DECLARE_TRACE > + > #define TP_PROTO(args...) args > #define TP_ARGS(args...) args > > @@ -114,6 +116,7 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin, > struct tracepoint *end) > { } > #endif /* CONFIG_TRACEPOINTS */ > +#endif /* DECLARE_TRACE */ > > /* > * Connect a probe to a tracepoint. > @@ -154,10 +157,13 @@ static inline void tracepoint_synchronize_unregister(void) > } > > #define PARAMS(args...) args > + > +#ifndef TRACE_FORMAT > #define TRACE_FORMAT(name, proto, args, fmt) \ > DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) > +#endif > > - > +#ifndef TRACE_EVENT > /* > * For use with the TRACE_EVENT macro: > * > @@ -262,5 +268,6 @@ 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 > diff --git a/include/trace/irq.h b/include/trace/irq.h > index ff5d449..04ab4c6 100644 > --- a/include/trace/irq.h > +++ b/include/trace/irq.h > @@ -1,9 +1,54 @@ > -#ifndef _TRACE_IRQ_H > +#if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ) > #define _TRACE_IRQ_H > > -#include <linux/interrupt.h> > #include <linux/tracepoint.h> > +#include <linux/interrupt.h> > + > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM irq > + > +/* > + * Tracepoint for entry of interrupt handler: > + */ > +TRACE_FORMAT(irq_handler_entry, > + TP_PROTO(int irq, struct irqaction *action), > + TP_ARGS(irq, action), > + TP_FMT("irq=%d handler=%s", irq, action->name) > + ); > + > +/* > + * Tracepoint for return of an interrupt handler: > + */ > +TRACE_EVENT(irq_handler_exit, > + > + TP_PROTO(int irq, struct irqaction *action, int ret), > + > + TP_ARGS(irq, action, ret), > + > + TP_STRUCT__entry( > + __field( int, irq ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + __entry->irq = irq; > + __entry->ret = ret; > + ), > + > + TP_printk("irq=%d return=%s", > + __entry->irq, __entry->ret ? "handled" : "unhandled") > +); > + > +TRACE_FORMAT(softirq_entry, > + TP_PROTO(struct softirq_action *h, struct softirq_action *vec), > + TP_ARGS(h, vec), > + TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) > + ); > > -#include <trace/irq_event_types.h> > +TRACE_FORMAT(softirq_exit, > + TP_PROTO(struct softirq_action *h, struct softirq_action *vec), > + TP_ARGS(h, vec), > + TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) > + ); > > #endif > diff --git a/include/trace/irq_event_types.h b/include/trace/irq_event_types.h > deleted file mode 100644 > index 85964eb..0000000 > --- a/include/trace/irq_event_types.h > +++ /dev/null > @@ -1,55 +0,0 @@ > - > -/* use <trace/irq.h> instead */ > -#ifndef TRACE_FORMAT > -# error Do not include this file directly. > -# error Unless you know what you are doing. > -#endif > - > -#undef TRACE_SYSTEM > -#define TRACE_SYSTEM irq > - > -/* > - * Tracepoint for entry of interrupt handler: > - */ > -TRACE_FORMAT(irq_handler_entry, > - TP_PROTO(int irq, struct irqaction *action), > - TP_ARGS(irq, action), > - TP_FMT("irq=%d handler=%s", irq, action->name) > - ); > - > -/* > - * Tracepoint for return of an interrupt handler: > - */ > -TRACE_EVENT(irq_handler_exit, > - > - TP_PROTO(int irq, struct irqaction *action, int ret), > - > - TP_ARGS(irq, action, ret), > - > - TP_STRUCT__entry( > - __field( int, irq ) > - __field( int, ret ) > - ), > - > - TP_fast_assign( > - __entry->irq = irq; > - __entry->ret = ret; > - ), > - > - TP_printk("irq=%d return=%s", > - __entry->irq, __entry->ret ? "handled" : "unhandled") > -); > - > -TRACE_FORMAT(softirq_entry, > - TP_PROTO(struct softirq_action *h, struct softirq_action *vec), > - TP_ARGS(h, vec), > - TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) > - ); > - > -TRACE_FORMAT(softirq_exit, > - TP_PROTO(struct softirq_action *h, struct softirq_action *vec), > - TP_ARGS(h, vec), > - TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) > - ); > - > -#undef TRACE_SYSTEM > diff --git a/include/trace/kmem.h b/include/trace/kmem.h > index 46efc24..d7d1218 100644 > --- a/include/trace/kmem.h > +++ b/include/trace/kmem.h > @@ -1,9 +1,192 @@ > -#ifndef _TRACE_KMEM_H > +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) > #define _TRACE_KMEM_H > > #include <linux/types.h> > #include <linux/tracepoint.h> > > -#include <trace/kmem_event_types.h> > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM kmem > > -#endif /* _TRACE_KMEM_H */ > +TRACE_EVENT(kmalloc, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + __entry->bytes_req = bytes_req; > + __entry->bytes_alloc = bytes_alloc; > + __entry->gfp_flags = gfp_flags; > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + __entry->gfp_flags) > +); > + > +TRACE_EVENT(kmem_cache_alloc, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + __entry->bytes_req = bytes_req; > + __entry->bytes_alloc = bytes_alloc; > + __entry->gfp_flags = gfp_flags; > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + __entry->gfp_flags) > +); > + > +TRACE_EVENT(kmalloc_node, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags, > + int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + __field( int, node ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + __entry->bytes_req = bytes_req; > + __entry->bytes_alloc = bytes_alloc; > + __entry->gfp_flags = gfp_flags; > + __entry->node = node; > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x node=%d", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + __entry->gfp_flags, > + __entry->node) > +); > + > +TRACE_EVENT(kmem_cache_alloc_node, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags, > + int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + __field( int, node ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + __entry->bytes_req = bytes_req; > + __entry->bytes_alloc = bytes_alloc; > + __entry->gfp_flags = gfp_flags; > + __entry->node = node; > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x node=%d", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + __entry->gfp_flags, > + __entry->node) > +); > + > +TRACE_EVENT(kfree, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + ), > + > + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) > +); > + > +TRACE_EVENT(kmem_cache_free, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + ), > + > + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) > +); > + > +#endif > diff --git a/include/trace/lockdep.h b/include/trace/lockdep.h > index 5ca67df..8ee7900 100644 > --- a/include/trace/lockdep.h > +++ b/include/trace/lockdep.h > @@ -1,9 +1,57 @@ > -#ifndef _TRACE_LOCKDEP_H > +#if !defined(_TRACE_LOCKDEP_H) || defined(TRACE_HEADER_MULTI_READ) > #define _TRACE_LOCKDEP_H > > #include <linux/lockdep.h> > #include <linux/tracepoint.h> > > -#include <trace/lockdep_event_types.h> > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM lock > + > +#ifdef CONFIG_LOCKDEP > + > +TRACE_FORMAT(lock_acquire, > + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, > + int trylock, int read, int check, > + struct lockdep_map *next_lock, unsigned long ip), > + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), > + TP_FMT("%s%s%s", trylock ? "try " : "", > + read ? "read " : "", lock->name) > + ); > + > +TRACE_FORMAT(lock_release, > + TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip), > + TP_ARGS(lock, nested, ip), > + TP_FMT("%s", lock->name) > + ); > + > +#ifdef CONFIG_LOCK_STAT > + > +TRACE_FORMAT(lock_contended, > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + TP_ARGS(lock, ip), > + TP_FMT("%s", lock->name) > + ); > + > +TRACE_EVENT(lock_acquired, > + TP_PROTO(struct lockdep_map *lock, unsigned long ip, s64 waittime), > + > + TP_ARGS(lock, ip, waittime), > + > + TP_STRUCT__entry( > + __field(const char *, name) > + __field(unsigned long, wait_usec) > + __field(unsigned long, wait_nsec_rem) > + ), > + TP_fast_assign( > + __entry->name = lock->name; > + __entry->wait_nsec_rem = do_div(waittime, NSEC_PER_USEC); > + __entry->wait_usec = (unsigned long) waittime; > + ), > + TP_printk("%s (%lu.%03lu us)", __entry->name, __entry->wait_usec, > + __entry->wait_nsec_rem) > +); > > #endif > +#endif > + > +#endif /* _TRACE_LOCKDEP_H */ > diff --git a/include/trace/lockdep_event_types.h b/include/trace/lockdep_event_types.h > deleted file mode 100644 > index 863f1e4..0000000 > --- a/include/trace/lockdep_event_types.h > +++ /dev/null > @@ -1,57 +0,0 @@ > - > -#ifndef TRACE_FORMAT > -# error Do not include this file directly. > -# error Unless you know what you are doing. > -#endif > - > -#undef TRACE_SYSTEM > -#define TRACE_SYSTEM lock > - > -#ifdef CONFIG_LOCKDEP > - > -TRACE_FORMAT(lock_acquire, > - TP_PROTO(struct lockdep_map *lock, unsigned int subclass, > - int trylock, int read, int check, > - struct lockdep_map *next_lock, unsigned long ip), > - TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), > - TP_FMT("%s%s%s", trylock ? "try " : "", > - read ? "read " : "", lock->name) > - ); > - > -TRACE_FORMAT(lock_release, > - TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip), > - TP_ARGS(lock, nested, ip), > - TP_FMT("%s", lock->name) > - ); > - > -#ifdef CONFIG_LOCK_STAT > - > -TRACE_FORMAT(lock_contended, > - TP_PROTO(struct lockdep_map *lock, unsigned long ip), > - TP_ARGS(lock, ip), > - TP_FMT("%s", lock->name) > - ); > - > -TRACE_EVENT(lock_acquired, > - TP_PROTO(struct lockdep_map *lock, unsigned long ip, s64 waittime), > - > - TP_ARGS(lock, ip, waittime), > - > - TP_STRUCT__entry( > - __field(const char *, name) > - __field(unsigned long, wait_usec) > - __field(unsigned long, wait_nsec_rem) > - ), > - TP_fast_assign( > - __entry->name = lock->name; > - __entry->wait_nsec_rem = do_div(waittime, NSEC_PER_USEC); > - __entry->wait_usec = (unsigned long) waittime; > - ), > - TP_printk("%s (%lu.%03lu us)", __entry->name, __entry->wait_usec, > - __entry->wait_nsec_rem) > -); > - > -#endif > -#endif > - > -#undef TRACE_SYSTEM > diff --git a/include/trace/sched.h b/include/trace/sched.h > index 4e372a1..5b1cf4a 100644 > --- a/include/trace/sched.h > +++ b/include/trace/sched.h > @@ -1,9 +1,336 @@ > -#ifndef _TRACE_SCHED_H > +#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ) > #define _TRACE_SCHED_H > > #include <linux/sched.h> > #include <linux/tracepoint.h> > > -#include <trace/sched_event_types.h> > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM sched > > -#endif > +/* > + * Tracepoint for calling kthread_stop, performed to end a kthread: > + */ > +TRACE_EVENT(sched_kthread_stop, > + > + TP_PROTO(struct task_struct *t), > + > + TP_ARGS(t), > + > + TP_STRUCT__entry( > + __array( char, comm, TASK_COMM_LEN ) > + __field( pid_t, pid ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->comm, t->comm, TASK_COMM_LEN); > + __entry->pid = t->pid; > + ), > + > + TP_printk("task %s:%d", __entry->comm, __entry->pid) > +); > + > +/* > + * Tracepoint for the return value of the kthread stopping: > + */ > +TRACE_EVENT(sched_kthread_stop_ret, > + > + TP_PROTO(int ret), > + > + TP_ARGS(ret), > + > + TP_STRUCT__entry( > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + __entry->ret = ret; > + ), > + > + TP_printk("ret %d", __entry->ret) > +); > + > +/* > + * Tracepoint for waiting on task to unschedule: > + * > + * (NOTE: the 'rq' argument is not used by generic trace events, > + * but used by the latency tracer plugin. ) > + */ > +TRACE_EVENT(sched_wait_task, > + > + TP_PROTO(struct rq *rq, struct task_struct *p), > + > + TP_ARGS(rq, p), > + > + TP_STRUCT__entry( > + __array( char, comm, TASK_COMM_LEN ) > + __field( pid_t, pid ) > + __field( int, prio ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > + __entry->pid = p->pid; > + __entry->prio = p->prio; > + ), > + > + TP_printk("task %s:%d [%d]", > + __entry->comm, __entry->pid, __entry->prio) > +); > + > +/* > + * Tracepoint for waking up a task: > + * > + * (NOTE: the 'rq' argument is not used by generic trace events, > + * but used by the latency tracer plugin. ) > + */ > +TRACE_EVENT(sched_wakeup, > + > + TP_PROTO(struct rq *rq, struct task_struct *p, int success), > + > + TP_ARGS(rq, p, success), > + > + TP_STRUCT__entry( > + __array( char, comm, TASK_COMM_LEN ) > + __field( pid_t, pid ) > + __field( int, prio ) > + __field( int, success ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > + __entry->pid = p->pid; > + __entry->prio = p->prio; > + __entry->success = success; > + ), > + > + TP_printk("task %s:%d [%d] success=%d", > + __entry->comm, __entry->pid, __entry->prio, > + __entry->success) > +); > + > +/* > + * Tracepoint for waking up a new task: > + * > + * (NOTE: the 'rq' argument is not used by generic trace events, > + * but used by the latency tracer plugin. ) > + */ > +TRACE_EVENT(sched_wakeup_new, > + > + TP_PROTO(struct rq *rq, struct task_struct *p, int success), > + > + TP_ARGS(rq, p, success), > + > + TP_STRUCT__entry( > + __array( char, comm, TASK_COMM_LEN ) > + __field( pid_t, pid ) > + __field( int, prio ) > + __field( int, success ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > + __entry->pid = p->pid; > + __entry->prio = p->prio; > + __entry->success = success; > + ), > + > + TP_printk("task %s:%d [%d] success=%d", > + __entry->comm, __entry->pid, __entry->prio, > + __entry->success) > +); > + > +/* > + * Tracepoint for task switches, performed by the scheduler: > + * > + * (NOTE: the 'rq' argument is not used by generic trace events, > + * but used by the latency tracer plugin. ) > + */ > +TRACE_EVENT(sched_switch, > + > + TP_PROTO(struct rq *rq, struct task_struct *prev, > + struct task_struct *next), > + > + TP_ARGS(rq, prev, next), > + > + TP_STRUCT__entry( > + __array( char, prev_comm, TASK_COMM_LEN ) > + __field( pid_t, prev_pid ) > + __field( int, prev_prio ) > + __array( char, next_comm, TASK_COMM_LEN ) > + __field( pid_t, next_pid ) > + __field( int, next_prio ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); > + __entry->prev_pid = prev->pid; > + __entry->prev_prio = prev->prio; > + memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); > + __entry->next_pid = next->pid; > + __entry->next_prio = next->prio; > + ), > + > + TP_printk("task %s:%d [%d] ==> %s:%d [%d]", > + __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, > + __entry->next_comm, __entry->next_pid, __entry->next_prio) > +); > + > +/* > + * Tracepoint for a task being migrated: > + */ > +TRACE_EVENT(sched_migrate_task, > + > + TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu), > + > + TP_ARGS(p, orig_cpu, dest_cpu), > + > + TP_STRUCT__entry( > + __array( char, comm, TASK_COMM_LEN ) > + __field( pid_t, pid ) > + __field( int, prio ) > + __field( int, orig_cpu ) > + __field( int, dest_cpu ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > + __entry->pid = p->pid; > + __entry->prio = p->prio; > + __entry->orig_cpu = orig_cpu; > + __entry->dest_cpu = dest_cpu; > + ), > + > + TP_printk("task %s:%d [%d] from: %d to: %d", > + __entry->comm, __entry->pid, __entry->prio, > + __entry->orig_cpu, __entry->dest_cpu) > +); > + > +/* > + * Tracepoint for freeing a task: > + */ > +TRACE_EVENT(sched_process_free, > + > + TP_PROTO(struct task_struct *p), > + > + TP_ARGS(p), > + > + TP_STRUCT__entry( > + __array( char, comm, TASK_COMM_LEN ) > + __field( pid_t, pid ) > + __field( int, prio ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > + __entry->pid = p->pid; > + __entry->prio = p->prio; > + ), > + > + TP_printk("task %s:%d [%d]", > + __entry->comm, __entry->pid, __entry->prio) > +); > + > +/* > + * Tracepoint for a task exiting: > + */ > +TRACE_EVENT(sched_process_exit, > + > + TP_PROTO(struct task_struct *p), > + > + TP_ARGS(p), > + > + TP_STRUCT__entry( > + __array( char, comm, TASK_COMM_LEN ) > + __field( pid_t, pid ) > + __field( int, prio ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > + __entry->pid = p->pid; > + __entry->prio = p->prio; > + ), > + > + TP_printk("task %s:%d [%d]", > + __entry->comm, __entry->pid, __entry->prio) > +); > + > +/* > + * Tracepoint for a waiting task: > + */ > +TRACE_EVENT(sched_process_wait, > + > + TP_PROTO(struct pid *pid), > + > + TP_ARGS(pid), > + > + TP_STRUCT__entry( > + __array( char, comm, TASK_COMM_LEN ) > + __field( pid_t, pid ) > + __field( int, prio ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); > + __entry->pid = pid_nr(pid); > + __entry->prio = current->prio; > + ), > + > + TP_printk("task %s:%d [%d]", > + __entry->comm, __entry->pid, __entry->prio) > +); > + > +/* > + * Tracepoint for do_fork: > + */ > +TRACE_EVENT(sched_process_fork, > + > + TP_PROTO(struct task_struct *parent, struct task_struct *child), > + > + TP_ARGS(parent, child), > + > + TP_STRUCT__entry( > + __array( char, parent_comm, TASK_COMM_LEN ) > + __field( pid_t, parent_pid ) > + __array( char, child_comm, TASK_COMM_LEN ) > + __field( pid_t, child_pid ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->parent_comm, parent->comm, TASK_COMM_LEN); > + __entry->parent_pid = parent->pid; > + memcpy(__entry->child_comm, child->comm, TASK_COMM_LEN); > + __entry->child_pid = child->pid; > + ), > + > + TP_printk("parent %s:%d child %s:%d", > + __entry->parent_comm, __entry->parent_pid, > + __entry->child_comm, __entry->child_pid) > +); > + > +/* > + * Tracepoint for sending a signal: > + */ > +TRACE_EVENT(sched_signal_send, > + > + TP_PROTO(int sig, struct task_struct *p), > + > + TP_ARGS(sig, p), > + > + TP_STRUCT__entry( > + __field( int, sig ) > + __array( char, comm, TASK_COMM_LEN ) > + __field( pid_t, pid ) > + ), > + > + TP_fast_assign( > + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > + __entry->pid = p->pid; > + __entry->sig = sig; > + ), > + > + TP_printk("sig: %d task %s:%d", > + __entry->sig, __entry->comm, __entry->pid) > +); > + > +#endif /* _TRACE_SCHED_H */ > diff --git a/include/trace/sched_event_types.h b/include/trace/sched_event_types.h > deleted file mode 100644 > index 63547dc..0000000 > --- a/include/trace/sched_event_types.h > +++ /dev/null > @@ -1,337 +0,0 @@ > - > -/* use <trace/sched.h> instead */ > -#ifndef TRACE_EVENT > -# error Do not include this file directly. > -# error Unless you know what you are doing. > -#endif > - > -#undef TRACE_SYSTEM > -#define TRACE_SYSTEM sched > - > -/* > - * Tracepoint for calling kthread_stop, performed to end a kthread: > - */ > -TRACE_EVENT(sched_kthread_stop, > - > - TP_PROTO(struct task_struct *t), > - > - TP_ARGS(t), > - > - TP_STRUCT__entry( > - __array( char, comm, TASK_COMM_LEN ) > - __field( pid_t, pid ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->comm, t->comm, TASK_COMM_LEN); > - __entry->pid = t->pid; > - ), > - > - TP_printk("task %s:%d", __entry->comm, __entry->pid) > -); > - > -/* > - * Tracepoint for the return value of the kthread stopping: > - */ > -TRACE_EVENT(sched_kthread_stop_ret, > - > - TP_PROTO(int ret), > - > - TP_ARGS(ret), > - > - TP_STRUCT__entry( > - __field( int, ret ) > - ), > - > - TP_fast_assign( > - __entry->ret = ret; > - ), > - > - TP_printk("ret %d", __entry->ret) > -); > - > -/* > - * Tracepoint for waiting on task to unschedule: > - * > - * (NOTE: the 'rq' argument is not used by generic trace events, > - * but used by the latency tracer plugin. ) > - */ > -TRACE_EVENT(sched_wait_task, > - > - TP_PROTO(struct rq *rq, struct task_struct *p), > - > - TP_ARGS(rq, p), > - > - TP_STRUCT__entry( > - __array( char, comm, TASK_COMM_LEN ) > - __field( pid_t, pid ) > - __field( int, prio ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > - __entry->pid = p->pid; > - __entry->prio = p->prio; > - ), > - > - TP_printk("task %s:%d [%d]", > - __entry->comm, __entry->pid, __entry->prio) > -); > - > -/* > - * Tracepoint for waking up a task: > - * > - * (NOTE: the 'rq' argument is not used by generic trace events, > - * but used by the latency tracer plugin. ) > - */ > -TRACE_EVENT(sched_wakeup, > - > - TP_PROTO(struct rq *rq, struct task_struct *p, int success), > - > - TP_ARGS(rq, p, success), > - > - TP_STRUCT__entry( > - __array( char, comm, TASK_COMM_LEN ) > - __field( pid_t, pid ) > - __field( int, prio ) > - __field( int, success ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > - __entry->pid = p->pid; > - __entry->prio = p->prio; > - __entry->success = success; > - ), > - > - TP_printk("task %s:%d [%d] success=%d", > - __entry->comm, __entry->pid, __entry->prio, > - __entry->success) > -); > - > -/* > - * Tracepoint for waking up a new task: > - * > - * (NOTE: the 'rq' argument is not used by generic trace events, > - * but used by the latency tracer plugin. ) > - */ > -TRACE_EVENT(sched_wakeup_new, > - > - TP_PROTO(struct rq *rq, struct task_struct *p, int success), > - > - TP_ARGS(rq, p, success), > - > - TP_STRUCT__entry( > - __array( char, comm, TASK_COMM_LEN ) > - __field( pid_t, pid ) > - __field( int, prio ) > - __field( int, success ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > - __entry->pid = p->pid; > - __entry->prio = p->prio; > - __entry->success = success; > - ), > - > - TP_printk("task %s:%d [%d] success=%d", > - __entry->comm, __entry->pid, __entry->prio, > - __entry->success) > -); > - > -/* > - * Tracepoint for task switches, performed by the scheduler: > - * > - * (NOTE: the 'rq' argument is not used by generic trace events, > - * but used by the latency tracer plugin. ) > - */ > -TRACE_EVENT(sched_switch, > - > - TP_PROTO(struct rq *rq, struct task_struct *prev, > - struct task_struct *next), > - > - TP_ARGS(rq, prev, next), > - > - TP_STRUCT__entry( > - __array( char, prev_comm, TASK_COMM_LEN ) > - __field( pid_t, prev_pid ) > - __field( int, prev_prio ) > - __array( char, next_comm, TASK_COMM_LEN ) > - __field( pid_t, next_pid ) > - __field( int, next_prio ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); > - __entry->prev_pid = prev->pid; > - __entry->prev_prio = prev->prio; > - memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); > - __entry->next_pid = next->pid; > - __entry->next_prio = next->prio; > - ), > - > - TP_printk("task %s:%d [%d] ==> %s:%d [%d]", > - __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, > - __entry->next_comm, __entry->next_pid, __entry->next_prio) > -); > - > -/* > - * Tracepoint for a task being migrated: > - */ > -TRACE_EVENT(sched_migrate_task, > - > - TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu), > - > - TP_ARGS(p, orig_cpu, dest_cpu), > - > - TP_STRUCT__entry( > - __array( char, comm, TASK_COMM_LEN ) > - __field( pid_t, pid ) > - __field( int, prio ) > - __field( int, orig_cpu ) > - __field( int, dest_cpu ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > - __entry->pid = p->pid; > - __entry->prio = p->prio; > - __entry->orig_cpu = orig_cpu; > - __entry->dest_cpu = dest_cpu; > - ), > - > - TP_printk("task %s:%d [%d] from: %d to: %d", > - __entry->comm, __entry->pid, __entry->prio, > - __entry->orig_cpu, __entry->dest_cpu) > -); > - > -/* > - * Tracepoint for freeing a task: > - */ > -TRACE_EVENT(sched_process_free, > - > - TP_PROTO(struct task_struct *p), > - > - TP_ARGS(p), > - > - TP_STRUCT__entry( > - __array( char, comm, TASK_COMM_LEN ) > - __field( pid_t, pid ) > - __field( int, prio ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > - __entry->pid = p->pid; > - __entry->prio = p->prio; > - ), > - > - TP_printk("task %s:%d [%d]", > - __entry->comm, __entry->pid, __entry->prio) > -); > - > -/* > - * Tracepoint for a task exiting: > - */ > -TRACE_EVENT(sched_process_exit, > - > - TP_PROTO(struct task_struct *p), > - > - TP_ARGS(p), > - > - TP_STRUCT__entry( > - __array( char, comm, TASK_COMM_LEN ) > - __field( pid_t, pid ) > - __field( int, prio ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > - __entry->pid = p->pid; > - __entry->prio = p->prio; > - ), > - > - TP_printk("task %s:%d [%d]", > - __entry->comm, __entry->pid, __entry->prio) > -); > - > -/* > - * Tracepoint for a waiting task: > - */ > -TRACE_EVENT(sched_process_wait, > - > - TP_PROTO(struct pid *pid), > - > - TP_ARGS(pid), > - > - TP_STRUCT__entry( > - __array( char, comm, TASK_COMM_LEN ) > - __field( pid_t, pid ) > - __field( int, prio ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->comm, current->comm, TASK_COMM_LEN); > - __entry->pid = pid_nr(pid); > - __entry->prio = current->prio; > - ), > - > - TP_printk("task %s:%d [%d]", > - __entry->comm, __entry->pid, __entry->prio) > -); > - > -/* > - * Tracepoint for do_fork: > - */ > -TRACE_EVENT(sched_process_fork, > - > - TP_PROTO(struct task_struct *parent, struct task_struct *child), > - > - TP_ARGS(parent, child), > - > - TP_STRUCT__entry( > - __array( char, parent_comm, TASK_COMM_LEN ) > - __field( pid_t, parent_pid ) > - __array( char, child_comm, TASK_COMM_LEN ) > - __field( pid_t, child_pid ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->parent_comm, parent->comm, TASK_COMM_LEN); > - __entry->parent_pid = parent->pid; > - memcpy(__entry->child_comm, child->comm, TASK_COMM_LEN); > - __entry->child_pid = child->pid; > - ), > - > - TP_printk("parent %s:%d child %s:%d", > - __entry->parent_comm, __entry->parent_pid, > - __entry->child_comm, __entry->child_pid) > -); > - > -/* > - * Tracepoint for sending a signal: > - */ > -TRACE_EVENT(sched_signal_send, > - > - TP_PROTO(int sig, struct task_struct *p), > - > - TP_ARGS(sig, p), > - > - TP_STRUCT__entry( > - __field( int, sig ) > - __array( char, comm, TASK_COMM_LEN ) > - __field( pid_t, pid ) > - ), > - > - TP_fast_assign( > - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); > - __entry->pid = p->pid; > - __entry->sig = sig; > - ), > - > - TP_printk("sig: %d task %s:%d", > - __entry->sig, __entry->comm, __entry->pid) > -); > - > -#undef TRACE_SYSTEM > diff --git a/include/trace/skb.h b/include/trace/skb.h > index d2de717..e6fd281 100644 > --- a/include/trace/skb.h > +++ b/include/trace/skb.h > @@ -1,9 +1,37 @@ > -#ifndef _TRACE_SKB_H_ > -#define _TRACE_SKB_H_ > +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SKB_H > > #include <linux/skbuff.h> > #include <linux/tracepoint.h> > > -#include <trace/skb_event_types.h> > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM skb > > -#endif > +/* > + * Tracepoint for free an sk_buff: > + */ > +TRACE_EVENT(kfree_skb, > + > + TP_PROTO(struct sk_buff *skb, void *location), > + > + TP_ARGS(skb, location), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( unsigned short, protocol ) > + __field( void *, location ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + if (skb) { > + __entry->protocol = ntohs(skb->protocol); > + } > + __entry->location = location; > + ), > + > + TP_printk("skbaddr=%p protocol=%u location=%p", > + __entry->skbaddr, __entry->protocol, __entry->location) > +); > + > +#endif /* _TRACE_SKB_H */ > diff --git a/include/trace/skb_event_types.h b/include/trace/skb_event_types.h > deleted file mode 100644 > index 4a1c504..0000000 > --- a/include/trace/skb_event_types.h > +++ /dev/null > @@ -1,38 +0,0 @@ > - > -/* use <trace/skb.h> instead */ > -#ifndef TRACE_EVENT > -# error Do not include this file directly. > -# error Unless you know what you are doing. > -#endif > - > -#undef TRACE_SYSTEM > -#define TRACE_SYSTEM skb > - > -/* > - * Tracepoint for free an sk_buff: > - */ > -TRACE_EVENT(kfree_skb, > - > - TP_PROTO(struct sk_buff *skb, void *location), > - > - TP_ARGS(skb, location), > - > - TP_STRUCT__entry( > - __field( void *, skbaddr ) > - __field( unsigned short, protocol ) > - __field( void *, location ) > - ), > - > - TP_fast_assign( > - __entry->skbaddr = skb; > - if (skb) { > - __entry->protocol = ntohs(skb->protocol); > - } > - __entry->location = location; > - ), > - > - TP_printk("skbaddr=%p protocol=%u location=%p", > - __entry->skbaddr, __entry->protocol, __entry->location) > -); > - > -#undef TRACE_SYSTEM > diff --git a/include/trace/trace_event_types.h b/include/trace/trace_event_types.h > deleted file mode 100644 > index 552a50e..0000000 > --- a/include/trace/trace_event_types.h > +++ /dev/null > @@ -1,7 +0,0 @@ > -/* trace/<type>_event_types.h here */ > - > -#include <trace/sched_event_types.h> > -#include <trace/irq_event_types.h> > -#include <trace/lockdep_event_types.h> > -#include <trace/skb_event_types.h> > -#include <trace/kmem_event_types.h> > diff --git a/kernel/trace/events.c b/kernel/trace/events.c > index 246f2aa..5a35a91 100644 > --- a/kernel/trace/events.c > +++ b/kernel/trace/events.c > @@ -8,6 +8,7 @@ > > #include "trace_output.h" > > +#define TRACE_HEADER_MULTI_READ > #include "trace_events_stage_1.h" > #include "trace_events_stage_2.h" > #include "trace_events_stage_3.h" > diff --git a/kernel/trace/trace_events_stage_1.h b/kernel/trace/trace_events_stage_1.h > index 38985f9..475f46a 100644 > --- a/kernel/trace/trace_events_stage_1.h > +++ b/kernel/trace/trace_events_stage_1.h > @@ -1,7 +1,7 @@ > /* > * Stage 1 of the trace events. > * > - * Override the macros in <trace/trace_event_types.h> to include the following: > + * Override the macros in <trace/trace_events.h> to include the following: > * > * struct ftrace_raw_<call> { > * struct trace_entry ent; > @@ -36,4 +36,4 @@ > }; \ > static struct ftrace_event_call event_##name > > -#include <trace/trace_event_types.h> > +#include <trace/trace_events.h> > diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h > index 59cfd7d..aa4a67a 100644 > --- a/kernel/trace/trace_events_stage_2.h > +++ b/kernel/trace/trace_events_stage_2.h > @@ -1,7 +1,7 @@ > /* > * Stage 2 of the trace events. > * > - * Override the macros in <trace/trace_event_types.h> to include the following: > + * Override the macros in <trace/trace_events.h> to include the following: > * > * enum print_line_t > * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags) > @@ -64,7 +64,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ > return TRACE_TYPE_HANDLED; \ > } > > -#include <trace/trace_event_types.h> > +#include <trace/trace_events.h> > > /* > * Setup the showing format of trace point. > @@ -128,7 +128,7 @@ ftrace_format_##call(struct trace_seq *s) \ > return ret; \ > } > > -#include <trace/trace_event_types.h> > +#include <trace/trace_events.h> > > #undef __field > #define __field(type, item) \ > @@ -167,4 +167,4 @@ ftrace_define_fields_##call(void) \ > return ret; \ > } > > -#include <trace/trace_event_types.h> > +#include <trace/trace_events.h> > diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h > index 5bb1b7f..45c04e1 100644 > --- a/kernel/trace/trace_events_stage_3.h > +++ b/kernel/trace/trace_events_stage_3.h > @@ -1,7 +1,7 @@ > /* > * Stage 3 of the trace events. > * > - * Override the macros in <trace/trace_event_types.h> to include the following: > + * Override the macros in <trace/trace_events.h> to include the following: > * > * static void ftrace_event_<call>(proto) > * { > @@ -272,7 +272,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ > _TRACE_PROFILE_INIT(call) \ > } > > -#include <trace/trace_event_types.h> > +#include <trace/trace_events.h> > > #undef _TRACE_PROFILE > #undef _TRACE_PROFILE_INIT > -- > 1.6.2.1 > > -- ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 1/8] tracing: consolidate trace and trace_event headers 2009-04-14 21:51 ` Frederic Weisbecker @ 2009-04-14 22:04 ` Steven Rostedt 0 siblings, 0 replies; 60+ messages in thread From: Steven Rostedt @ 2009-04-14 22:04 UTC (permalink / raw) To: Frederic Weisbecker Cc: linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Jason Baron, Mathieu Desnoyers On Tue, 14 Apr 2009, Frederic Weisbecker wrote: > On Tue, Apr 14, 2009 at 01:23:38PM -0400, Steven Rostedt wrote: > > From: Steven Rostedt <srostedt@redhat.com> > > > > Impact: clean up > > > > Neil Horman (et. al.) criticized the way the trace events were broken up > > into two files. The reason for that was that ftrace needed to separate out > > the declarations from where the #include <linux/tracepoint.h> was used. > > It then dawned on me that the tracepoint.h header only needs to define the > > TRACE_EVENT macro if it is not already defined. > > > > The solution is simply to test if TRACE_EVENT is defined, and if it is not > > then the linux/tracepoint.h header can define it. This change consolidates > > all the <traces>.h and <traces>_event_types.h into the <traces>.h file. > > > > Reported-by: Neil Horman <nhorman@tuxdriver.com> > > Reported-by: Theodore Tso <tytso@mit.edu> > > Reported-by: Jiaying Zhang <jiayingz@google.com> > > Cc: Zhaolei <zhaolei@cn.fujitsu.com> > > Cc: Frederic Weisbecker <fweisbec@gmail.com> > > Cc: Peter Zijlstra <peterz@infradead.org> > > Cc: Jason Baron <jbaron@redhat.com> > > Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> > > Signed-off-by: Steven Rostedt <rostedt@goodmis.org> > > --- > > include/linux/tracepoint.h | 9 +- > > include/trace/irq.h | 51 +++++- > > include/trace/irq_event_types.h | 55 ------ > > include/trace/kmem.h | 189 +++++++++++++++++++- > > include/trace/lockdep.h | 52 +++++- > > include/trace/lockdep_event_types.h | 57 ------ > > include/trace/sched.h | 333 ++++++++++++++++++++++++++++++++++- > > include/trace/sched_event_types.h | 337 ----------------------------------- > > include/trace/skb.h | 36 ++++- > > include/trace/skb_event_types.h | 38 ---- > > include/trace/trace_event_types.h | 7 - > > kernel/trace/events.c | 1 + > > kernel/trace/trace_events_stage_1.h | 4 +- > > kernel/trace/trace_events_stage_2.h | 8 +- > > kernel/trace/trace_events_stage_3.h | 4 +- > > 15 files changed, 663 insertions(+), 518 deletions(-) > > delete mode 100644 include/trace/irq_event_types.h > > delete mode 100644 include/trace/lockdep_event_types.h > > delete mode 100644 include/trace/sched_event_types.h > > delete mode 100644 include/trace/skb_event_types.h > > delete mode 100644 include/trace/trace_event_types.h > > > > I don't know if you use git-format-patch without -M or > something else specific to git pull request. But it looks > like the renames are not detected here, so it's a bit > hard to know what have been actually happened or deleted > in the end result. > Hmm, good point. I use git format-patch with no options and then use quilt to send the emair. I always want the patches to work with quilt, thus I avoid anything git specific. My repo is public, so anyone can still look at it and run any git command they want. -- Steve ^ permalink raw reply [flat|nested] 60+ messages in thread
* [PATCH 2/8] tracing: create automated trace defines 2009-04-14 17:23 [PATCH 0/8] [GIT PULL] TRACE_EVENT for modules Steven Rostedt 2009-04-14 17:23 ` [PATCH 1/8] tracing: consolidate trace and trace_event headers Steven Rostedt @ 2009-04-14 17:23 ` Steven Rostedt 2009-04-14 23:44 ` Jeremy Fitzhardinge 2009-04-15 7:04 ` Zhaolei 2009-04-14 17:23 ` [PATCH 3/8] tracing: make trace_seq operations available for core kernel Steven Rostedt ` (8 subsequent siblings) 10 siblings, 2 replies; 60+ messages in thread From: Steven Rostedt @ 2009-04-14 17:23 UTC (permalink / raw) To: linux-kernel Cc: Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg [-- Attachment #1: 0002-tracing-create-automated-trace-defines.patch --] [-- Type: text/plain, Size: 12376 bytes --] From: Steven Rostedt <srostedt@redhat.com> This patch lowers the number of places a developer must modify to add new tracepoints. The current method to add a new tracepoint into an existing system is to write the trace point macro in the trace header with one of the macros TRACE_EVENT, TRACE_FORMAT or DECLARE_TRACE, then they must add the same named item into the C file with the macro DEFINE_TRACE(name) and then add the trace point. This change cuts out the needing to add the DEFINE_TRACE(name). Every file that uses the tracepoint must still include the trace/<type>.h file, but the one C file must also add a define before the including of that file. #define CREATE_TRACE_POINTS #include <trace/mytrace.h> This will cause the trace/mytrace.h file to also produce the C code necessary to implement the trace point. Note, if more than one trace/<type>.h is used to create the C code it is best to list them all together. #define CREATE_TRACE_POINTS #include <trace/foo.h> #include <trace/bar.h> #include <trace/fido.h> Thanks to Mathieu Desnoyers and Christoph Hellwig for coming up with the cleaner solution of the define above the includes over my first design to have the C code include a "special" header. This patch converts sched, irq and lockdep and skb to use this new method. Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Neil Horman <nhorman@tuxdriver.com> Cc: Zhao Lei <zhaolei@cn.fujitsu.com> Cc: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro> Cc: Pekka Enberg <penberg@cs.helsinki.fi> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- include/trace/define_trace.h | 75 ++++++++++++++++++++++++++++++++++++++++++ include/trace/irq.h | 5 ++- include/trace/kmem.h | 4 ++- include/trace/lockdep.h | 3 ++ include/trace/sched.h | 3 ++ include/trace/skb.h | 3 ++ kernel/exit.c | 4 -- kernel/fork.c | 2 - kernel/irq/handle.c | 7 ++-- kernel/kthread.c | 3 -- kernel/lockdep.c | 12 ++----- kernel/sched.c | 10 ++---- kernel/signal.c | 2 - kernel/softirq.c | 3 -- mm/util.c | 11 ++---- net/core/net-traces.c | 4 +- 16 files changed, 105 insertions(+), 46 deletions(-) create mode 100644 include/trace/define_trace.h diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h new file mode 100644 index 0000000..de9dc7d --- /dev/null +++ b/include/trace/define_trace.h @@ -0,0 +1,75 @@ +/* + * Trace files that want to automate creationg of all tracepoints defined + * in their file should include this file. The following are macros that the + * trace file may define: + * + * TRACE_SYSTEM defines the system the tracepoint is for + * + * TRACE_INCLUDE_FILE if the file name is something other than TRACE_SYSTEM.h + * This macro may be defined to tell define_trace.h what file to include. + * Note, leave off the ".h". + * + * TRACE_INCLUDE_PATH if the path is something other than core kernel include/trace + * then this macro can define the path to use. Note, the path is relative to + * define_trace.h, not the file including it. Full path names for out of tree + * modules must be used. + */ + +#ifdef CREATE_TRACE_POINTS + +/* Prevent recursion */ +#undef CREATE_TRACE_POINTS + +#include <linux/stringify.h> + +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ + DEFINE_TRACE(name) + +#undef TRACE_FORMAT +#define TRACE_FORMAT(name, proto, args, print) \ + DEFINE_TRACE(name) + +#undef DECLARE_TRACE +#define DECLARE_TRACE(name, proto, args) \ + DEFINE_TRACE(name) + +#undef TRACE_INCLUDE +#undef __TRACE_INCLUDE + +#ifndef TRACE_INCLUDE_FILE +# define TRACE_INCLUDE_FILE TRACE_SYSTEM +# define UNDEF_TRACE_INCLUDE_FILE +#endif + +#ifndef TRACE_INCLUDE_PATH +# define __TRACE_INCLUDE(system) <trace/system.h> +# define UNDEF_TRACE_INCLUDE_FILE +#else +# define __TRACE_INCLUDE(system) __stringify(TRACE_INCLUDE_PATH/system.h) +#endif + +# define TRACE_INCLUDE(system) __TRACE_INCLUDE(system) + +/* Let the trace headers be reread */ +#define TRACE_HEADER_MULTI_READ + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +#undef TRACE_HEADER_MULTI_READ + +/* Only undef what we defined in this file */ +#ifdef UNDEF_TRACE_INCLUDE_FILE +# undef TRACE_INCLUDE_PATH +# undef UNDEF_TRACE_INCLUDE_FILE +#endif + +#ifdef UNDEF_TRACE_INCLUDE_FILE +# undef TRACE_INCLUDE_PATH +# undef UNDEF_TRACE_INCLUDE_FILE +#endif + +/* We may be processing more files */ +#define CREATE_TRACE_POINTS + +#endif /* CREATE_TRACE_POINTS */ diff --git a/include/trace/irq.h b/include/trace/irq.h index 04ab4c6..75e3468 100644 --- a/include/trace/irq.h +++ b/include/trace/irq.h @@ -51,4 +51,7 @@ TRACE_FORMAT(softirq_exit, TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) ); -#endif +#endif /* _TRACE_IRQ_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/include/trace/kmem.h b/include/trace/kmem.h index d7d1218..c22c42f 100644 --- a/include/trace/kmem.h +++ b/include/trace/kmem.h @@ -188,5 +188,7 @@ TRACE_EVENT(kmem_cache_free, TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) ); +#endif /* _TRACE_KMEM_H */ -#endif +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/include/trace/lockdep.h b/include/trace/lockdep.h index 8ee7900..4d301e7 100644 --- a/include/trace/lockdep.h +++ b/include/trace/lockdep.h @@ -55,3 +55,6 @@ TRACE_EVENT(lock_acquired, #endif #endif /* _TRACE_LOCKDEP_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/include/trace/sched.h b/include/trace/sched.h index 5b1cf4a..ffa1cab 100644 --- a/include/trace/sched.h +++ b/include/trace/sched.h @@ -334,3 +334,6 @@ TRACE_EVENT(sched_signal_send, ); #endif /* _TRACE_SCHED_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/include/trace/skb.h b/include/trace/skb.h index e6fd281..1e8fabb 100644 --- a/include/trace/skb.h +++ b/include/trace/skb.h @@ -35,3 +35,6 @@ TRACE_EVENT(kfree_skb, ); #endif /* _TRACE_SKB_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/kernel/exit.c b/kernel/exit.c index abf9cf3..2fe9d2c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -56,10 +56,6 @@ #include <asm/mmu_context.h> #include "cred-internals.h" -DEFINE_TRACE(sched_process_free); -DEFINE_TRACE(sched_process_exit); -DEFINE_TRACE(sched_process_wait); - static void exit_mm(struct task_struct * tsk); static void __unhash_process(struct task_struct *p) diff --git a/kernel/fork.c b/kernel/fork.c index b9e2edd..4bebf26 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -83,8 +83,6 @@ DEFINE_PER_CPU(unsigned long, process_counts) = 0; __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ -DEFINE_TRACE(sched_process_fork); - int nr_processes(void) { int cpu; diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index d82142b..983d8be 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -17,9 +17,11 @@ #include <linux/kernel_stat.h> #include <linux/rculist.h> #include <linux/hash.h> -#include <trace/irq.h> #include <linux/bootmem.h> +#define CREATE_TRACE_POINTS +#include <trace/irq.h> + #include "internals.h" /* @@ -348,9 +350,6 @@ static void warn_no_thread(unsigned int irq, struct irqaction *action) "but no thread function available.", irq, action->name); } -DEFINE_TRACE(irq_handler_entry); -DEFINE_TRACE(irq_handler_exit); - /** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number diff --git a/kernel/kthread.c b/kernel/kthread.c index 4ebaf85..e1c7692 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -21,9 +21,6 @@ static DEFINE_SPINLOCK(kthread_create_lock); static LIST_HEAD(kthread_create_list); struct task_struct *kthreadd_task; -DEFINE_TRACE(sched_kthread_stop); -DEFINE_TRACE(sched_kthread_stop_ret); - struct kthread_create_info { /* Information passed to kthread() from kthreadd. */ diff --git a/kernel/lockdep.c b/kernel/lockdep.c index c4582a6..257f21a 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -42,12 +42,14 @@ #include <linux/hash.h> #include <linux/ftrace.h> #include <linux/stringify.h> -#include <trace/lockdep.h> #include <asm/sections.h> #include "lockdep_internals.h" +#define CREATE_TRACE_POINTS +#include <trace/lockdep.h> + #ifdef CONFIG_PROVE_LOCKING int prove_locking = 1; module_param(prove_locking, int, 0644); @@ -2929,8 +2931,6 @@ void lock_set_class(struct lockdep_map *lock, const char *name, } EXPORT_SYMBOL_GPL(lock_set_class); -DEFINE_TRACE(lock_acquire); - /* * We are not always called with irqs disabled - do that here, * and also avoid lockdep recursion: @@ -2957,8 +2957,6 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, } EXPORT_SYMBOL_GPL(lock_acquire); -DEFINE_TRACE(lock_release); - void lock_release(struct lockdep_map *lock, int nested, unsigned long ip) { @@ -3061,8 +3059,6 @@ found_it: put_lock_stats(stats); } -DEFINE_TRACE(lock_acquired); - static void __lock_acquired(struct lockdep_map *lock, unsigned long ip) { @@ -3118,8 +3114,6 @@ found_it: lock->ip = ip; } -DEFINE_TRACE(lock_contended); - void lock_contended(struct lockdep_map *lock, unsigned long ip) { unsigned long flags; diff --git a/kernel/sched.c b/kernel/sched.c index 5724508..e6d4518 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -72,13 +72,15 @@ #include <linux/debugfs.h> #include <linux/ctype.h> #include <linux/ftrace.h> -#include <trace/sched.h> #include <asm/tlb.h> #include <asm/irq_regs.h> #include "sched_cpupri.h" +#define CREATE_TRACE_POINTS +#include <trace/sched.h> + /* * Convert user-nice values [ -20 ... 0 ... 19 ] * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], @@ -118,12 +120,6 @@ */ #define RUNTIME_INF ((u64)~0ULL) -DEFINE_TRACE(sched_wait_task); -DEFINE_TRACE(sched_wakeup); -DEFINE_TRACE(sched_wakeup_new); -DEFINE_TRACE(sched_switch); -DEFINE_TRACE(sched_migrate_task); - #ifdef CONFIG_SMP static void double_rq_lock(struct rq *rq1, struct rq *rq2); diff --git a/kernel/signal.c b/kernel/signal.c index d803473..1d5703f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -41,8 +41,6 @@ static struct kmem_cache *sigqueue_cachep; -DEFINE_TRACE(sched_signal_send); - static void __user *sig_handler(struct task_struct *t, int sig) { return t->sighand->action[sig - 1].sa.sa_handler; diff --git a/kernel/softirq.c b/kernel/softirq.c index 2fecefa..a2d9b45 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -186,9 +186,6 @@ EXPORT_SYMBOL(local_bh_enable_ip); */ #define MAX_SOFTIRQ_RESTART 10 -DEFINE_TRACE(softirq_entry); -DEFINE_TRACE(softirq_exit); - asmlinkage void __do_softirq(void) { struct softirq_action *h; diff --git a/mm/util.c b/mm/util.c index 2599e83..0e74a22 100644 --- a/mm/util.c +++ b/mm/util.c @@ -4,9 +4,11 @@ #include <linux/module.h> #include <linux/err.h> #include <linux/sched.h> -#include <linux/tracepoint.h> #include <asm/uaccess.h> +#define CREATE_TRACE_POINTS +#include <trace/kmem.h> + /** * kstrdup - allocate space for and copy an existing string * @s: the string to duplicate @@ -239,13 +241,6 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start, EXPORT_SYMBOL_GPL(get_user_pages_fast); /* Tracepoints definitions. */ -DEFINE_TRACE(kmalloc); -DEFINE_TRACE(kmem_cache_alloc); -DEFINE_TRACE(kmalloc_node); -DEFINE_TRACE(kmem_cache_alloc_node); -DEFINE_TRACE(kfree); -DEFINE_TRACE(kmem_cache_free); - EXPORT_TRACEPOINT_SYMBOL(kmalloc); EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc); EXPORT_TRACEPOINT_SYMBOL(kmalloc_node); diff --git a/net/core/net-traces.c b/net/core/net-traces.c index c8fb456..8017720 100644 --- a/net/core/net-traces.c +++ b/net/core/net-traces.c @@ -19,11 +19,11 @@ #include <linux/workqueue.h> #include <linux/netlink.h> #include <linux/net_dropmon.h> -#include <trace/skb.h> #include <asm/unaligned.h> #include <asm/bitops.h> +#define CREATE_TRACE_POINTS +#include <trace/skb.h> -DEFINE_TRACE(kfree_skb); EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb); -- 1.6.2.1 -- ^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-14 17:23 ` [PATCH 2/8] tracing: create automated trace defines Steven Rostedt @ 2009-04-14 23:44 ` Jeremy Fitzhardinge 2009-04-15 1:45 ` Mathieu Desnoyers 2009-04-15 7:04 ` Zhaolei 1 sibling, 1 reply; 60+ messages in thread From: Jeremy Fitzhardinge @ 2009-04-14 23:44 UTC (permalink / raw) To: Steven Rostedt Cc: linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg How about something like this: >From f7fa71c046bc383706bf58503c4b75e05e252152 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Date: Tue, 14 Apr 2009 16:41:18 -0700 Subject: [PATCH] tracing: move __DO_TRACE out of line Mainly simplify linux/tracepoint.h's include dependencies (removes rcupdate.h), but it can't help with icache locality, since it definitely moves the code out of line, rather than relying on gcc to do it. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 4353f3f..1052e33 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -15,7 +15,6 @@ */ #include <linux/types.h> -#include <linux/rcupdate.h> struct module; struct tracepoint; @@ -42,19 +41,20 @@ struct tracepoint { * it_func[0] is never NULL because there is at least one element in the array * when the array itself is non NULL. */ -#define __DO_TRACE(tp, proto, args) \ - do { \ +#define DEFINE_DO_TRACE(name, proto, args) \ + void __do_trace_##name(struct tracepoint *tp, TP_PROTO(proto)) \ + { \ void **it_func; \ \ rcu_read_lock_sched_notrace(); \ - it_func = rcu_dereference((tp)->funcs); \ + it_func = rcu_dereference(tp->funcs); \ if (it_func) { \ do { \ ((void(*)(proto))(*it_func))(args); \ } while (*(++it_func)); \ } \ rcu_read_unlock_sched_notrace(); \ - } while (0) + } /* * Make sure the alignment of the structure in the __tracepoints section will @@ -63,11 +63,13 @@ struct tracepoint { */ #define DECLARE_TRACE(name, proto, args) \ extern struct tracepoint __tracepoint_##name; \ + extern void __do_trace_##name(struct tracepoint *tp, \ + TP_PROTO(proto)); \ static inline void trace_##name(proto) \ { \ if (unlikely(__tracepoint_##name.state)) \ - __DO_TRACE(&__tracepoint_##name, \ - TP_PROTO(proto), TP_ARGS(args)); \ + __do_trace_##name(&__tracepoint_##name, \ + TP_ARGS(args)); \ } \ static inline int register_trace_##name(void (*probe)(proto)) \ { \ @@ -151,10 +153,7 @@ extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, * probe unregistration and the end of module exit to make sure there is no * caller executing a probe when it is freed. */ -static inline void tracepoint_synchronize_unregister(void) -{ - synchronize_sched(); -} +extern void tracepoint_synchronize_unregister(void); #define PARAMS(args...) args diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h index 980eb66..1a0502e 100644 --- a/include/trace/define_trace.h +++ b/include/trace/define_trace.h @@ -24,14 +24,17 @@ #undef TRACE_EVENT #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ + DEFINE_DO_TRACE(name, TP_PROTO(proto), TP_ARGS(args)) \ DEFINE_TRACE(name) #undef TRACE_FORMAT -#define TRACE_FORMAT(name, proto, args, print) \ +#define TRACE_FORMAT(name, proto, args, print) \ + DEFINE_DO_TRACE(name, TP_PROTO(proto), TP_ARGS(args)) \ DEFINE_TRACE(name) #undef DECLARE_TRACE -#define DECLARE_TRACE(name, proto, args) \ +#define DECLARE_TRACE(name, proto, args) \ + DEFINE_DO_TRACE(name, TP_PROTO(proto), TP_ARGS(args)) \ DEFINE_TRACE(name) #undef TRACE_INCLUDE diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 1ef5d3a..6ac1f48 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c @@ -545,6 +545,12 @@ void tracepoint_iter_reset(struct tracepoint_iter *iter) } EXPORT_SYMBOL_GPL(tracepoint_iter_reset); +void tracepoint_synchronize_unregister(void) +{ + synchronize_sched(); +} +EXPORT_SYMBOL_GPL(tracepoint_synchronize_unregister); + #ifdef CONFIG_MODULES int tracepoint_module_notify(struct notifier_block *self, ^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-14 23:44 ` Jeremy Fitzhardinge @ 2009-04-15 1:45 ` Mathieu Desnoyers 2009-04-15 16:07 ` Jeremy Fitzhardinge 0 siblings, 1 reply; 60+ messages in thread From: Mathieu Desnoyers @ 2009-04-15 1:45 UTC (permalink / raw) To: Jeremy Fitzhardinge Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg * Jeremy Fitzhardinge (jeremy@goop.org) wrote: > How about something like this: > > From f7fa71c046bc383706bf58503c4b75e05e252152 Mon Sep 17 00:00:00 2001 > From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > Date: Tue, 14 Apr 2009 16:41:18 -0700 > Subject: [PATCH] tracing: move __DO_TRACE out of line > > Mainly simplify linux/tracepoint.h's include dependencies (removes > rcupdate.h), but it can't help with icache locality, since it > definitely moves the code out of line, rather than relying on gcc > to do it. > > Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > > diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h > index 4353f3f..1052e33 100644 > --- a/include/linux/tracepoint.h > +++ b/include/linux/tracepoint.h > @@ -15,7 +15,6 @@ > */ > > #include <linux/types.h> > -#include <linux/rcupdate.h> > > struct module; > struct tracepoint; > @@ -42,19 +41,20 @@ struct tracepoint { > * it_func[0] is never NULL because there is at least one element in the array > * when the array itself is non NULL. > */ > -#define __DO_TRACE(tp, proto, args) \ > - do { \ > +#define DEFINE_DO_TRACE(name, proto, args) \ > + void __do_trace_##name(struct tracepoint *tp, TP_PROTO(proto)) \ I fear that won't work with "void" prototype. If we need this kind of flexibility, we will need to create a special case for empty prototype. Mathieu > + { \ > void **it_func; \ > \ > rcu_read_lock_sched_notrace(); \ > - it_func = rcu_dereference((tp)->funcs); \ > + it_func = rcu_dereference(tp->funcs); \ > if (it_func) { \ > do { \ > ((void(*)(proto))(*it_func))(args); \ > } while (*(++it_func)); \ > } \ > rcu_read_unlock_sched_notrace(); \ > - } while (0) > + } > > /* > * Make sure the alignment of the structure in the __tracepoints section will > @@ -63,11 +63,13 @@ struct tracepoint { > */ > #define DECLARE_TRACE(name, proto, args) \ > extern struct tracepoint __tracepoint_##name; \ > + extern void __do_trace_##name(struct tracepoint *tp, \ > + TP_PROTO(proto)); \ > static inline void trace_##name(proto) \ > { \ > if (unlikely(__tracepoint_##name.state)) \ > - __DO_TRACE(&__tracepoint_##name, \ > - TP_PROTO(proto), TP_ARGS(args)); \ > + __do_trace_##name(&__tracepoint_##name, \ > + TP_ARGS(args)); \ > } \ > static inline int register_trace_##name(void (*probe)(proto)) \ > { \ > @@ -151,10 +153,7 @@ extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, > * probe unregistration and the end of module exit to make sure there is no > * caller executing a probe when it is freed. > */ > -static inline void tracepoint_synchronize_unregister(void) > -{ > - synchronize_sched(); > -} > +extern void tracepoint_synchronize_unregister(void); > > #define PARAMS(args...) args > > diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h > index 980eb66..1a0502e 100644 > --- a/include/trace/define_trace.h > +++ b/include/trace/define_trace.h > @@ -24,14 +24,17 @@ > > #undef TRACE_EVENT > #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ > + DEFINE_DO_TRACE(name, TP_PROTO(proto), TP_ARGS(args)) \ > DEFINE_TRACE(name) > > #undef TRACE_FORMAT > -#define TRACE_FORMAT(name, proto, args, print) \ > +#define TRACE_FORMAT(name, proto, args, print) \ > + DEFINE_DO_TRACE(name, TP_PROTO(proto), TP_ARGS(args)) \ > DEFINE_TRACE(name) > > #undef DECLARE_TRACE > -#define DECLARE_TRACE(name, proto, args) \ > +#define DECLARE_TRACE(name, proto, args) \ > + DEFINE_DO_TRACE(name, TP_PROTO(proto), TP_ARGS(args)) \ > DEFINE_TRACE(name) > > #undef TRACE_INCLUDE > diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c > index 1ef5d3a..6ac1f48 100644 > --- a/kernel/tracepoint.c > +++ b/kernel/tracepoint.c > @@ -545,6 +545,12 @@ void tracepoint_iter_reset(struct tracepoint_iter *iter) > } > EXPORT_SYMBOL_GPL(tracepoint_iter_reset); > > +void tracepoint_synchronize_unregister(void) > +{ > + synchronize_sched(); > +} > +EXPORT_SYMBOL_GPL(tracepoint_synchronize_unregister); > + > #ifdef CONFIG_MODULES > > int tracepoint_module_notify(struct notifier_block *self, > > -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-15 1:45 ` Mathieu Desnoyers @ 2009-04-15 16:07 ` Jeremy Fitzhardinge 2009-04-16 2:34 ` Mathieu Desnoyers 0 siblings, 1 reply; 60+ messages in thread From: Jeremy Fitzhardinge @ 2009-04-15 16:07 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg Mathieu Desnoyers wrote: > * Jeremy Fitzhardinge (jeremy@goop.org) wrote: >> -#define __DO_TRACE(tp, proto, args) \ >> - do { \ >> +#define DEFINE_DO_TRACE(name, proto, args) \ >> + void __do_trace_##name(struct tracepoint *tp, TP_PROTO(proto)) \ >> > > I fear that won't work with "void" prototype. If we need this kind of > flexibility, we will need to create a special case for empty prototype. > Yes, that has been a bit awkward. I couldn't find a way to create a no-param tracepoint, and so ended up passing a dummy arg. Stupid C syntax. On the other hand, I can get something that actually compiles this way... J ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-15 16:07 ` Jeremy Fitzhardinge @ 2009-04-16 2:34 ` Mathieu Desnoyers 2009-04-16 2:56 ` Jeremy Fitzhardinge 0 siblings, 1 reply; 60+ messages in thread From: Mathieu Desnoyers @ 2009-04-16 2:34 UTC (permalink / raw) To: Jeremy Fitzhardinge Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg * Jeremy Fitzhardinge (jeremy@goop.org) wrote: > Mathieu Desnoyers wrote: >> * Jeremy Fitzhardinge (jeremy@goop.org) wrote: >>> -#define __DO_TRACE(tp, proto, args) \ >>> - do { \ >>> +#define DEFINE_DO_TRACE(name, proto, args) \ >>> + void __do_trace_##name(struct tracepoint *tp, TP_PROTO(proto)) \ >>> >> >> I fear that won't work with "void" prototype. If we need this kind of >> flexibility, we will need to create a special case for empty prototype. >> > > Yes, that has been a bit awkward. I couldn't find a way to create a > no-param tracepoint, and so ended up passing a dummy arg. Stupid C > syntax. > > On the other hand, I can get something that actually compiles this way... > > J Is your only problem the fact that tracepoints include rcupdate.h ? This can easily be solved by moving rcu_read_(un)lock_sched_notrace to a rcu-update-<insert meaningful name here> and include this header in rcupdate.h and tracepoint.h. We could keep the indirection layer you proposed for synchronize_sched() though, even if it adds an unnecessary function call. It's a slow path anyway. If by doing these modifications we succeed in keeping the "void" parameters working _and_ make your stuff to compile, I think we would have done something great. :-) Mathieu -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-16 2:34 ` Mathieu Desnoyers @ 2009-04-16 2:56 ` Jeremy Fitzhardinge 2009-04-16 23:44 ` Mathieu Desnoyers 0 siblings, 1 reply; 60+ messages in thread From: Jeremy Fitzhardinge @ 2009-04-16 2:56 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg Mathieu Desnoyers wrote: > Is your only problem the fact that tracepoints include rcupdate.h ? No. That was the first roadblock, which caused massive cyclic dependencies between includes and consequent failure to define everything required. I solved that by pushing __DO_TRACE out of line. Everything since then is a separate issue. > This > can easily be solved by moving rcu_read_(un)lock_sched_notrace to a > rcu-update-<insert meaningful name here> and include this header in > rcupdate.h and tracepoint.h. > I suppose, but I think pushing __do_trace_##name out of line is cleaner anyway. And I think it's very important that tracepoint.h have a *absolutely minimal* #include set, so that it can be safely included in as many contexts as possible. asm/paravirt.h is complex enough as it is, and I really don't want tracepoint bringing in any extra headers at all. linux/types.h is about the only acceptable one. > If by doing these modifications we succeed in keeping the "void" > parameters working _and_ make your stuff to compile, I think we would > have done something great. :-) > The void issue is irritating, but relatively minor compared to the rest. If everything else gets solved except for the need to pass a dummy param to no-arg tracepoints, then I think it'll be a generally useful facility. J ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-16 2:56 ` Jeremy Fitzhardinge @ 2009-04-16 23:44 ` Mathieu Desnoyers 2009-04-17 0:03 ` Jeremy Fitzhardinge 2009-04-20 7:12 ` [PATCH 2/8] tracing: create automated trace defines Andi Kleen 0 siblings, 2 replies; 60+ messages in thread From: Mathieu Desnoyers @ 2009-04-16 23:44 UTC (permalink / raw) To: Jeremy Fitzhardinge Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg * Jeremy Fitzhardinge (jeremy@goop.org) wrote: > Mathieu Desnoyers wrote: >> Is your only problem the fact that tracepoints include rcupdate.h ? > > No. That was the first roadblock, which caused massive cyclic > dependencies between includes and consequent failure to define > everything required. I solved that by pushing __DO_TRACE out of line. > Everything since then is a separate issue. > >> This >> can easily be solved by moving rcu_read_(un)lock_sched_notrace to a >> rcu-update-<insert meaningful name here> and include this header in >> rcupdate.h and tracepoint.h. >> > I suppose, but I think pushing __do_trace_##name out of line is cleaner > anyway. And I think it's very important that tracepoint.h have a > *absolutely minimal* #include set, so that it can be safely included in > as many contexts as possible. asm/paravirt.h is complex enough as it > is, and I really don't want tracepoint bringing in any extra headers at > all. linux/types.h is about the only acceptable one. > >> If by doing these modifications we succeed in keeping the "void" >> parameters working _and_ make your stuff to compile, I think we would >> have done something great. :-) >> > > The void issue is irritating, but relatively minor compared to the rest. > If everything else gets solved except for the need to pass a dummy param > to no-arg tracepoints, then I think it'll be a generally useful facility. > The other point I dislike about the out-of-line approach is that the tracer will suffer from a pointless supplementary function call at each event. Given how slow function calls are, at least on x86, I'd prefer leaving the handler call chain inline, unless there is a very strong reason not to do so. I'll come up with a patch that leaves the tracepoint inline, but fixes the header dependency. Mathieu > J > -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-16 23:44 ` Mathieu Desnoyers @ 2009-04-17 0:03 ` Jeremy Fitzhardinge 2009-04-17 0:13 ` Mathieu Desnoyers 2009-04-20 7:12 ` [PATCH 2/8] tracing: create automated trace defines Andi Kleen 1 sibling, 1 reply; 60+ messages in thread From: Jeremy Fitzhardinge @ 2009-04-17 0:03 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg Mathieu Desnoyers wrote: > The other point I dislike about the out-of-line approach is that the > tracer will suffer from a pointless supplementary function call at each > event. Given how slow function calls are, at least on x86, I'd prefer > leaving the handler call chain inline, unless there is a very strong > reason not to do so. > Are they? They're generally considered to be "free", because the call and return are predicted 100% accurately. > I'll come up with a patch that leaves the tracepoint inline, but fixes > the header dependency. > OK. J ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-17 0:03 ` Jeremy Fitzhardinge @ 2009-04-17 0:13 ` Mathieu Desnoyers 2009-04-17 0:18 ` Jeremy Fitzhardinge 0 siblings, 1 reply; 60+ messages in thread From: Mathieu Desnoyers @ 2009-04-17 0:13 UTC (permalink / raw) To: Jeremy Fitzhardinge Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg * Jeremy Fitzhardinge (jeremy@goop.org) wrote: > Mathieu Desnoyers wrote: >> The other point I dislike about the out-of-line approach is that the >> tracer will suffer from a pointless supplementary function call at each >> event. Given how slow function calls are, at least on x86, I'd prefer >> leaving the handler call chain inline, unless there is a very strong >> reason not to do so. >> > > Are they? They're generally considered to be "free", because the call > and return are predicted 100% accurately. > Adding a simple function call within the tracer fast path, in LTTng, has a very measurable performance impact on the tbench workload. This is why I don't use any function call-based trace clocks in LTTng, but rather my own inline trace clock. Mathieu >> I'll come up with a patch that leaves the tracepoint inline, but fixes >> the header dependency. >> > OK. > > J > -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-17 0:13 ` Mathieu Desnoyers @ 2009-04-17 0:18 ` Jeremy Fitzhardinge 2009-04-17 0:28 ` Mathieu Desnoyers 0 siblings, 1 reply; 60+ messages in thread From: Jeremy Fitzhardinge @ 2009-04-17 0:18 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg Mathieu Desnoyers wrote: >> Are they? They're generally considered to be "free", because the call >> and return are predicted 100% accurately. >> >> > > Adding a simple function call within the tracer fast path, in LTTng, has > a very measurable performance impact on the tbench workload. This is why > I don't use any function call-based trace clocks in LTTng, but rather my > own inline trace clock. I'm a bit concerned about all the code that tracing puts inline though. It seems it would put quite a lot of icache overhead on the codepath when the tracepoint is disabled, not least because its duplicated in every instance of the tracepoint. And if the compiler decides to put the unlikely() branch code out of line, then that's the same as making it a function call (except that if it is a function call, all the tracepoints will share the same code, and get a higher likelihood of getting icache hits). J ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-17 0:18 ` Jeremy Fitzhardinge @ 2009-04-17 0:28 ` Mathieu Desnoyers 2009-04-17 0:43 ` Jeremy Fitzhardinge 0 siblings, 1 reply; 60+ messages in thread From: Mathieu Desnoyers @ 2009-04-17 0:28 UTC (permalink / raw) To: Jeremy Fitzhardinge Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg * Jeremy Fitzhardinge (jeremy@goop.org) wrote: > Mathieu Desnoyers wrote: >>> Are they? They're generally considered to be "free", because the >>> call and return are predicted 100% accurately. >>> >>> >> >> Adding a simple function call within the tracer fast path, in LTTng, has >> a very measurable performance impact on the tbench workload. This is why >> I don't use any function call-based trace clocks in LTTng, but rather my >> own inline trace clock. > > I'm a bit concerned about all the code that tracing puts inline though. > It seems it would put quite a lot of icache overhead on the codepath > when the tracepoint is disabled, not least because its duplicated in > every instance of the tracepoint. And if the compiler decides to put > the unlikely() branch code out of line, then that's the same as making > it a function call (except that if it is a function call, all the > tracepoints will share the same code, and get a higher likelihood of > getting icache hits). > "all this code" is actually : rcu_read_lock_sched_notrace(); \ it_func = rcu_dereference((tp)->funcs); \ if (it_func) { \ do { \ ((void(*)(proto))(*it_func))(args); \ } while (*(++it_func)); \ } \ rcu_read_unlock_sched_notrace(); \ Which does nothing more than disabling preemption and a for loop to call all the tracepoint handlers. I don't see the big win in laying out the stack to call this code out-of-line; we would just remove the preempt disable and the loop, which are minimal compared to most call stacks. So basically, tracepoints are already just doing a function call, with a few more bytes for preempt disable and multiple handler support. About the compiler deciding to put the unlikely branch out-of-line, I've never seen any function calls generated just for the sake of saving those few bytes, that would be crazy of the part of the compiler. However, it can (and should) freely put the stack setup in the coldest cache-lines possible, which are reachable by a near jump. Mathieu > > J > -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-17 0:28 ` Mathieu Desnoyers @ 2009-04-17 0:43 ` Jeremy Fitzhardinge 2009-04-17 3:05 ` [PATCH] tracepoints : let subsystem nop-out the tracepoints at build time Mathieu Desnoyers 0 siblings, 1 reply; 60+ messages in thread From: Jeremy Fitzhardinge @ 2009-04-17 0:43 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg Mathieu Desnoyers wrote: > "all this code" is actually : > > rcu_read_lock_sched_notrace(); \ > it_func = rcu_dereference((tp)->funcs); \ > if (it_func) { \ > do { \ > ((void(*)(proto))(*it_func))(args); \ > } while (*(++it_func)); \ > } \ > rcu_read_unlock_sched_notrace(); \ > > Which does nothing more than disabling preemption and a for loop to > call all the tracepoint handlers. I don't see the big win in laying out > the stack to call this code out-of-line; we would just remove the > preempt disable and the loop, which are minimal compared to most > call stacks. > Well, look at it from my perspective: Ingo has been repeatedly beating me up for the overhead pvops adds to a native kernel, where it really is just a (direct) function call. I want to instrument each pvop site with a tracepoint so I can actually work out which calls are being called how frequently to look for new optimisation opportunities. I would guess the tracepoint code sequence is going to increase the impact of each pvop call site by a fair bit, and that's not counting the effects the extra register pressure will have. That's a pile of code to add. And frankly, that's fine by me, because I would expect this degree of introspection to have some performance hit. But it does make the need for per-subsystem tracing Kconfig entries fairly important, because I don't think this would be acceptable to ship in a non-debug-everything kernel build, even though other tracepoints might be. > So basically, tracepoints are already just doing a function call, with a > few more bytes for preempt disable and multiple handler support. > > About the compiler deciding to put the unlikely branch out-of-line, I've > never seen any function calls generated just for the sake of saving > those few bytes, that would be crazy of the part of the compiler. > However, it can (and should) freely put the stack setup in the coldest > cache-lines possible, which are reachable by a near jump. > No, it wouldn't generate a call. But if its going to put the code out of line into cold cache-lines, then it may as well generate a call. Anyway, the important point from my perspective is that tracepoint.h have no #include dependencies beyond linux/types.h (compiler.h, etc). J ^ permalink raw reply [flat|nested] 60+ messages in thread
* [PATCH] tracepoints : let subsystem nop-out the tracepoints at build time 2009-04-17 0:43 ` Jeremy Fitzhardinge @ 2009-04-17 3:05 ` Mathieu Desnoyers 0 siblings, 0 replies; 60+ messages in thread From: Mathieu Desnoyers @ 2009-04-17 3:05 UTC (permalink / raw) To: Jeremy Fitzhardinge Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg * Jeremy Fitzhardinge (jeremy@goop.org) wrote: > Mathieu Desnoyers wrote: >> "all this code" is actually : >> >> rcu_read_lock_sched_notrace(); \ >> it_func = rcu_dereference((tp)->funcs); \ >> if (it_func) { \ >> do { \ >> ((void(*)(proto))(*it_func))(args); \ >> } while (*(++it_func)); \ >> } \ >> rcu_read_unlock_sched_notrace(); \ >> >> Which does nothing more than disabling preemption and a for loop to >> call all the tracepoint handlers. I don't see the big win in laying out >> the stack to call this code out-of-line; we would just remove the >> preempt disable and the loop, which are minimal compared to most >> call stacks. >> > > Well, look at it from my perspective: Ingo has been repeatedly beating > me up for the overhead pvops adds to a native kernel, where it really is > just a (direct) function call. I want to instrument each pvop site with > a tracepoint so I can actually work out which calls are being called how > frequently to look for new optimisation opportunities. > > I would guess the tracepoint code sequence is going to increase the > impact of each pvop call site by a fair bit, and that's not counting the > effects the extra register pressure will have. That's a pile of code to > add. > > And frankly, that's fine by me, because I would expect this degree of > introspection to have some performance hit. But it does make the need > for per-subsystem tracing Kconfig entries fairly important, because I > don't think this would be acceptable to ship in a non-debug-everything > kernel build, even though other tracepoints might be. > Agreed. Tracepoints might change the code surrounding the pvops in a similar fashion as the pvops themselves would change the code. Therefore, it makes sense to have a Kconfig option to enable the pvops tracepoints. In terms of tracepoints (with the DECLARE_TRACE/DEFINE_TRACE semantic), we could have something like : in include/trace/pvops.h : #include <linux/tracepoint.h> #ifdef CONFIG_PVOPS_TRACEPOINTS #define DECLARE_PVOPS_TRACE DECLARE_TRACE #define DEFINE_PVOPS_TRACE DEFINE_TRACE #define EXPORT_PVOPS_TRACEPOINT_SYMBOL_GPL EXPORT_TRACEPOINT_SYMBOL_GPL #define EXPORT_PVOPS_TRACEPOINT_SYMBOL EXPORT_TRACEPOINT_SYMBOL #else /* !CONFIG_PVOPS_TRACEPOINTS */ #define DECLARE_PVOPS_TRACE DECLARE_TRACE_NOP #define DEFINE_PVOPS_TRACE DEFINE_TRACE_NOP #define EXPORT_PVOPS_TRACEPOINT_SYMBOL_GPL EXPORT_TRACEPOINT_SYMBOL_GPL_NOP #define EXPORT_PVOPS_TRACEPOINT_SYMBOL EXPORT_TRACEPOINT_SYMBOL_NOP #endif /* CONFIG_PVOPS_TRACEPOINTS */ And then do the declarations/definitions using the new DECLARE_PVOPS_TRACE / DEFINE_PVOPS_TRACE. For that you'll need the patch I am attaching below. I'll let Steven figure out how to tweak TRACE_EVENT() to support this new tracepoint feature. >> So basically, tracepoints are already just doing a function call, with a >> few more bytes for preempt disable and multiple handler support. >> >> About the compiler deciding to put the unlikely branch out-of-line, I've >> never seen any function calls generated just for the sake of saving >> those few bytes, that would be crazy of the part of the compiler. >> However, it can (and should) freely put the stack setup in the coldest >> cache-lines possible, which are reachable by a near jump. >> > > No, it wouldn't generate a call. But if its going to put the code out > of line into cold cache-lines, then it may as well generate a call. > Jumping out-of-line was somewhat faster than calling a function if I recall well my performance tests. But that's all been done long ago. And note that whenever the tracer becomes active, the out-of-line code of busy tracepoints becomes cache-hot, which means that there is no more cache line fetch to perform, which leaves the stack setup and other overhead of function call/return vs 2*jump very measurable. > Anyway, the important point from my perspective is that tracepoint.h > have no #include dependencies beyond linux/types.h (compiler.h, etc). > Is preempt.h a problem ? Here is the patch. Mathieu tracepoints : let subsystem nop-out the tracepoints at build time Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> CC: Jeremy Fitzhardinge <jeremy@goop.org> CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> CC: Steven Rostedt <rostedt@goodmis.org> CC: Ingo Molnar <mingo@elte.hu> CC: Andrew Morton <akpm@linux-foundation.org> CC: Christoph Hellwig <hch@lst.de> --- include/linux/tracepoint.h | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) Index: linux.trees.git/include/linux/tracepoint.h =================================================================== --- linux.trees.git.orig/include/linux/tracepoint.h 2009-04-16 22:40:26.000000000 -0400 +++ linux.trees.git/include/linux/tracepoint.h 2009-04-16 22:40:33.000000000 -0400 @@ -37,6 +37,24 @@ struct tracepoint { #define TP_PROTO(args...) args #define TP_ARGS(args...) args +#define DECLARE_TRACE_NOP(name, proto, args) \ + static inline void _do_trace_##name(struct tracepoint *tp, proto) \ + { } \ + static inline void trace_##name(proto) \ + { } \ + static inline int register_trace_##name(void (*probe)(proto)) \ + { \ + return -ENOSYS; \ + } \ + static inline int unregister_trace_##name(void (*probe)(proto)) \ + { \ + return -ENOSYS; \ + } + +#define DEFINE_TRACE_NOP(name) +#define EXPORT_TRACEPOINT_SYMBOL_GPL_NOP(name) +#define EXPORT_TRACEPOINT_SYMBOL_NOP(name) + #ifdef CONFIG_TRACEPOINTS /* @@ -95,23 +113,11 @@ extern void tracepoint_update_probe_rang struct tracepoint *end); #else /* !CONFIG_TRACEPOINTS */ -#define DECLARE_TRACE(name, proto, args) \ - static inline void _do_trace_##name(struct tracepoint *tp, proto) \ - { } \ - static inline void trace_##name(proto) \ - { } \ - static inline int register_trace_##name(void (*probe)(proto)) \ - { \ - return -ENOSYS; \ - } \ - static inline int unregister_trace_##name(void (*probe)(proto)) \ - { \ - return -ENOSYS; \ - } -#define DEFINE_TRACE(name) -#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) -#define EXPORT_TRACEPOINT_SYMBOL(name) +#define DECLARE_TRACE DECLARE_TRACE_NOP +#define DEFINE_TRACE DEFINE_TRACE_NOP +#define EXPORT_TRACEPOINT_SYMBOL_GPL EXPORT_TRACEPOINT_SYMBOL_GPL_NOP +#define EXPORT_TRACEPOINT_SYMBOL EXPORT_TRACEPOINT_SYMBOL_NOP static inline void tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end) -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-16 23:44 ` Mathieu Desnoyers 2009-04-17 0:03 ` Jeremy Fitzhardinge @ 2009-04-20 7:12 ` Andi Kleen 2009-04-21 15:51 ` Mathieu Desnoyers 1 sibling, 1 reply; 60+ messages in thread From: Andi Kleen @ 2009-04-20 7:12 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Jeremy Fitzhardinge, Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Mathieu Desnoyers <compudj@krystal.dyndns.org> writes: > Given how slow function calls are, at least on x86, That was with frame pointers right? Frame pointers tend to make function calls slow. -Andi -- ak@linux.intel.com -- Speaking for myself only. ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-20 7:12 ` [PATCH 2/8] tracing: create automated trace defines Andi Kleen @ 2009-04-21 15:51 ` Mathieu Desnoyers 2009-04-21 17:18 ` Jeremy Fitzhardinge 0 siblings, 1 reply; 60+ messages in thread From: Mathieu Desnoyers @ 2009-04-21 15:51 UTC (permalink / raw) To: Andi Kleen Cc: Jeremy Fitzhardinge, Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka * Andi Kleen (andi@firstfloor.org) wrote: > Mathieu Desnoyers <compudj@krystal.dyndns.org> writes: > > > Given how slow function calls are, at least on x86, > > That was with frame pointers right? Frame pointers tend to make > function calls slow. > Looking at my .config, CONFIG_FRAME_POINTER is disabled here. So we should probably expect an even worse performance impact if we enable them. Mathieu > -Andi > -- > ak@linux.intel.com -- Speaking for myself only. > -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-21 15:51 ` Mathieu Desnoyers @ 2009-04-21 17:18 ` Jeremy Fitzhardinge 2009-04-21 17:21 ` Steven Rostedt 0 siblings, 1 reply; 60+ messages in thread From: Jeremy Fitzhardinge @ 2009-04-21 17:18 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Andi Kleen, Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Mathieu Desnoyers wrote: > * Andi Kleen (andi@firstfloor.org) wrote: > >> Mathieu Desnoyers <compudj@krystal.dyndns.org> writes: >> >> >>> Given how slow function calls are, at least on x86, >>> >> That was with frame pointers right? Frame pointers tend to make >> function calls slow. >> >> > > Looking at my .config, CONFIG_FRAME_POINTER is disabled here. So we > should probably expect an even worse performance impact if we enable > them. I tried disabling frame pointers, but it looked to me like tracing selects them. Did I misread, or perhaps it was some other config option doing it... J ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-21 17:18 ` Jeremy Fitzhardinge @ 2009-04-21 17:21 ` Steven Rostedt 2009-04-21 17:43 ` Jeremy Fitzhardinge 2009-04-21 20:28 ` Andi Kleen 0 siblings, 2 replies; 60+ messages in thread From: Steven Rostedt @ 2009-04-21 17:21 UTC (permalink / raw) To: Jeremy Fitzhardinge Cc: Mathieu Desnoyers, Andi Kleen, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka On Tue, 21 Apr 2009, Jeremy Fitzhardinge wrote: > Mathieu Desnoyers wrote: > > * Andi Kleen (andi@firstfloor.org) wrote: > > > > > Mathieu Desnoyers <compudj@krystal.dyndns.org> writes: > > > > > > > > > > Given how slow function calls are, at least on x86, > > > > > > > That was with frame pointers right? Frame pointers tend to make > > > function calls slow. > > > > > > > > > > Looking at my .config, CONFIG_FRAME_POINTER is disabled here. So we > > should probably expect an even worse performance impact if we enable > > them. > > I tried disabling frame pointers, but it looked to me like tracing selects > them. Did I misread, or perhaps it was some other config option doing it... It is needed for the function tracer (gcc -pg wont work without it). It is the only tracer that selects it. -- Steve ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-21 17:21 ` Steven Rostedt @ 2009-04-21 17:43 ` Jeremy Fitzhardinge 2009-04-21 20:28 ` Andi Kleen 1 sibling, 0 replies; 60+ messages in thread From: Jeremy Fitzhardinge @ 2009-04-21 17:43 UTC (permalink / raw) To: Steven Rostedt Cc: Mathieu Desnoyers, Andi Kleen, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Steven Rostedt wrote: > >> I tried disabling frame pointers, but it looked to me like tracing selects >> them. Did I misread, or perhaps it was some other config option doing it... >> > > It is needed for the function tracer (gcc -pg wont work without it). It is > the only tracer that selects it. > Ah, right. I'm never sure what all the trace options actually control, so I tend to enable them a bit indescriminately. J ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-21 17:21 ` Steven Rostedt 2009-04-21 17:43 ` Jeremy Fitzhardinge @ 2009-04-21 20:28 ` Andi Kleen 2009-04-21 21:17 ` Steven Rostedt 1 sibling, 1 reply; 60+ messages in thread From: Andi Kleen @ 2009-04-21 20:28 UTC (permalink / raw) To: Steven Rostedt Cc: Jeremy Fitzhardinge, Mathieu Desnoyers, Andi Kleen, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka > It is needed for the function tracer (gcc -pg wont work without it). It is > the only tracer that selects it. FWIW i still have gcc patches to fix that. They were first stalled on copyright assignment and then on gcc's merge window being closed, but now with 4.5 open for game I hope to resubmit them soon again. With that you can use -pg without frame pointer, but you have to supply a special mcount function that expects the different stack layout. -Andi -- ak@linux.intel.com -- Speaking for myself only. ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-21 20:28 ` Andi Kleen @ 2009-04-21 21:17 ` Steven Rostedt 2009-04-21 21:23 ` Frank Ch. Eigler 2009-04-22 6:07 ` Andi Kleen 0 siblings, 2 replies; 60+ messages in thread From: Steven Rostedt @ 2009-04-21 21:17 UTC (permalink / raw) To: Andi Kleen Cc: Jeremy Fitzhardinge, Mathieu Desnoyers, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka On Tue, 21 Apr 2009, Andi Kleen wrote: > > It is needed for the function tracer (gcc -pg wont work without it). It is > > the only tracer that selects it. > > FWIW i still have gcc patches to fix that. They were first stalled > on copyright assignment and then on gcc's merge window being closed, > but now with 4.5 open for game I hope to resubmit them soon > again. > > With that you can use -pg without frame pointer, but you have > to supply a special mcount function that expects the different > stack layout. I think it was Ingo that let out the idea, and I'm starting to like it. Perhaps we should fork off gcc and ship Linux with its own compiler. This way we can optimize it for the kernel and not worry about any userland optimizations. I would like to do something like: if (unlikely(err)) { __section__(".error_sect") { /* put error code here */ } } And have gcc in the error section (if it is big enough perhaps) do: jmp .L123 .L124 [...] and in the section ".error_sect" we would have: .L123 /* error code here */ jmp .L124 We could do the same for trace points. That is, any part of code that really would happen once in a while (error handling for one) we can move off to its own section and keep hot paths hot. -- Steve ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-21 21:17 ` Steven Rostedt @ 2009-04-21 21:23 ` Frank Ch. Eigler 2009-04-21 21:33 ` Steven Rostedt 2009-04-22 6:07 ` Andi Kleen 1 sibling, 1 reply; 60+ messages in thread From: Frank Ch. Eigler @ 2009-04-21 21:23 UTC (permalink / raw) To: Steven Rostedt Cc: Andi Kleen, Jeremy Fitzhardinge, Mathieu Desnoyers, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Hi - On Tue, Apr 21, 2009 at 05:17:17PM -0400, Steven Rostedt wrote: > [...] Perhaps we should fork off gcc and ship Linux with its own > compiler. This way we can optimize it for the kernel and not worry > about any userland optimizations. In this regard, kernel land does not seem that unlike user land. > if (unlikely(err)) { > __section__(".error_sect") { > /* put error code here */ > } > } > > And have gcc in the error section (if it is big enough perhaps) do: > jmp .L123 > .L124 [...] > [...] > jmp .L124 > We could do the same for trace points. That is, any part of code that > really would happen once in a while (error handling for one) we can move > off to its own section and keep hot paths hot. This is called -freorder-blocks or -freorder-blocks-and-partition (depending on how far you would like gcc to move unlikely blocks). - FChE ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-21 21:23 ` Frank Ch. Eigler @ 2009-04-21 21:33 ` Steven Rostedt 2009-04-22 5:47 ` Mathieu Desnoyers 0 siblings, 1 reply; 60+ messages in thread From: Steven Rostedt @ 2009-04-21 21:33 UTC (permalink / raw) To: Frank Ch. Eigler Cc: Andi Kleen, Jeremy Fitzhardinge, Mathieu Desnoyers, LKML, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu [ removed Pekka@firstfloor.org due to mail errors ] On Tue, 21 Apr 2009, Frank Ch. Eigler wrote: > Hi - > > On Tue, Apr 21, 2009 at 05:17:17PM -0400, Steven Rostedt wrote: > > > [...] Perhaps we should fork off gcc and ship Linux with its own > > compiler. This way we can optimize it for the kernel and not worry > > about any userland optimizations. > > In this regard, kernel land does not seem that unlike user land. > > > if (unlikely(err)) { > > __section__(".error_sect") { > > /* put error code here */ > > } > > } > > > > And have gcc in the error section (if it is big enough perhaps) do: > > jmp .L123 > > .L124 [...] > > [...] > > jmp .L124 > > > We could do the same for trace points. That is, any part of code that > > really would happen once in a while (error handling for one) we can move > > off to its own section and keep hot paths hot. > > This is called -freorder-blocks or -freorder-blocks-and-partition > (depending on how far you would like gcc to move unlikely blocks). That does not let us pick and choose what and where to put the code. But still, a fork of gcc would let us optimize it for the kernel, and not for generic programs. /me has been sitting too close to the furnace and must have been taking up some of those fumes, to be considering a fork of gcc a good idea ;-) -- Steve ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-21 21:33 ` Steven Rostedt @ 2009-04-22 5:47 ` Mathieu Desnoyers 0 siblings, 0 replies; 60+ messages in thread From: Mathieu Desnoyers @ 2009-04-22 5:47 UTC (permalink / raw) To: Steven Rostedt Cc: Frank Ch. Eigler, Andi Kleen, Jeremy Fitzhardinge, LKML, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu * Steven Rostedt (rostedt@goodmis.org) wrote: > > [ removed Pekka@firstfloor.org due to mail errors ] > > On Tue, 21 Apr 2009, Frank Ch. Eigler wrote: > > > Hi - > > > > On Tue, Apr 21, 2009 at 05:17:17PM -0400, Steven Rostedt wrote: > > > > > [...] Perhaps we should fork off gcc and ship Linux with its own > > > compiler. This way we can optimize it for the kernel and not worry > > > about any userland optimizations. > > > > In this regard, kernel land does not seem that unlike user land. > > > > > if (unlikely(err)) { > > > __section__(".error_sect") { > > > /* put error code here */ > > > } > > > } > > > > > > And have gcc in the error section (if it is big enough perhaps) do: > > > jmp .L123 > > > .L124 [...] > > > [...] > > > jmp .L124 > > > > > We could do the same for trace points. That is, any part of code that > > > really would happen once in a while (error handling for one) we can move > > > off to its own section and keep hot paths hot. > > > > This is called -freorder-blocks or -freorder-blocks-and-partition > > (depending on how far you would like gcc to move unlikely blocks). > > That does not let us pick and choose what and where to put the code. > > But still, a fork of gcc would let us optimize it for the kernel, and not > for generic programs. > > /me has been sitting too close to the furnace and must have been taking > up some of those fumes, to be considering a fork of gcc a good idea ;-) > I guess we should have been sitting near the same furnace then. I'm unsure how different from the current gcc this can go, but it could be a very interesting exercise. Just removing unneeded front ends could probably help adding features much faster than if we have to support Fortran, Java, etc. Mathieu > -- Steve > -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-21 21:17 ` Steven Rostedt 2009-04-21 21:23 ` Frank Ch. Eigler @ 2009-04-22 6:07 ` Andi Kleen 2009-04-22 6:24 ` Steven Rostedt 1 sibling, 1 reply; 60+ messages in thread From: Andi Kleen @ 2009-04-22 6:07 UTC (permalink / raw) To: Steven Rostedt Cc: Andi Kleen, Jeremy Fitzhardinge, Mathieu Desnoyers, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka > I think it was Ingo that let out the idea, and I'm starting to like it. > > Perhaps we should fork off gcc and ship Linux with its own compiler. This > way we can optimize it for the kernel and not worry about any userland > optimizations. > > I would like to do something like: > > if (unlikely(err)) { > __section__(".error_sect") { gcc already supports that, you don't need to fork anything. It's called hot/cold partitioning. Basically it splits functions into hot and cold and unlikely parts and all the cold/unlikely parts go into a separate sections. I think it's normally not enabled by default on x86 though, probably because it doesn't help too much. By default (unless you specify -fno-reorder-blocks) it does the same without sections, just moving unlikely code out of line. -Andi -- ak@linux.intel.com -- Speaking for myself only. ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-22 6:07 ` Andi Kleen @ 2009-04-22 6:24 ` Steven Rostedt 2009-04-22 7:26 ` Andi Kleen 0 siblings, 1 reply; 60+ messages in thread From: Steven Rostedt @ 2009-04-22 6:24 UTC (permalink / raw) To: Andi Kleen Cc: Jeremy Fitzhardinge, Mathieu Desnoyers, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka On Wed, 22 Apr 2009, Andi Kleen wrote: > > I think it was Ingo that let out the idea, and I'm starting to like it. > > > > Perhaps we should fork off gcc and ship Linux with its own compiler. This > > way we can optimize it for the kernel and not worry about any userland > > optimizations. > > > > I would like to do something like: > > > > if (unlikely(err)) { > > __section__(".error_sect") { > > > gcc already supports that, you don't need to fork anything. It's called > hot/cold partitioning. Basically it splits functions into hot and cold > and unlikely parts and all the cold/unlikely parts go into a separate > sections. > > I think it's normally not enabled by default on x86 though, probably because > it doesn't help too much. > > By default (unless you specify -fno-reorder-blocks) it does the same > without sections, just moving unlikely code out of line. The unlikely code does not always get moved out that far. It still sits inside a function, and looking at the tracepoint code it did not move it far enough. If you have a bunch of functions that each with an unlikely statement, those unlikely sections will still be interleaved within the function code. In the case of tracepoints, it would be nice to move all the code that sets up the function call out of the hot paths. If we could move it to its own section, that would be much better. Having all "unlikely"s go into a separate section would not help much, since according to the branch profiler there are a lot of "unlikely"s in the kernel that are not too unlikely. If gcc can indeed move "unlikely" code completely out of the fast path, and put it into its own sections, then I think we should go through the kernel and start removing all "likely" and "unlikely"s that are not 99% accurate. Then we can enable the separate section cold paths and perhaps see a performance benefit. -- Steve ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-22 6:24 ` Steven Rostedt @ 2009-04-22 7:26 ` Andi Kleen 0 siblings, 0 replies; 60+ messages in thread From: Andi Kleen @ 2009-04-22 7:26 UTC (permalink / raw) To: Steven Rostedt Cc: Andi Kleen, Jeremy Fitzhardinge, Mathieu Desnoyers, linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka On Wed, Apr 22, 2009 at 02:24:17AM -0400, Steven Rostedt wrote: > > On Wed, 22 Apr 2009, Andi Kleen wrote: > > > > I think it was Ingo that let out the idea, and I'm starting to like it. > > > > > > Perhaps we should fork off gcc and ship Linux with its own compiler. This > > > way we can optimize it for the kernel and not worry about any userland > > > optimizations. > > > > > > I would like to do something like: > > > > > > if (unlikely(err)) { > > > __section__(".error_sect") { > > > > > > gcc already supports that, you don't need to fork anything. It's called > > hot/cold partitioning. Basically it splits functions into hot and cold > > and unlikely parts and all the cold/unlikely parts go into a separate > > sections. > > > > I think it's normally not enabled by default on x86 though, probably because > > it doesn't help too much. > > > > By default (unless you specify -fno-reorder-blocks) it does the same > > without sections, just moving unlikely code out of line. > > The unlikely code does not always get moved out that far. It still sits > inside a function, and looking at the tracepoint code it did not move it > far enough. That's because you didn't enable the hot/cold partioning as I wrote. These are separate options. By default it doesn't use partitions on x86, but it can. > If gcc can indeed move "unlikely" code completely out of the fast path, > and put it into its own sections, then I think we should go through the > kernel and start removing all "likely" and "unlikely"s that are not 99% > accurate. Then we can enable the separate section cold paths and perhaps > see a performance benefit. iirc there wasn't much for using separate partitions with the usual user space benchmarks (SpecCPU etc.) on x86. It helped a bit on POWER apparently though. -Andi -- ak@linux.intel.com -- Speaking for myself only. ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 2/8] tracing: create automated trace defines 2009-04-14 17:23 ` [PATCH 2/8] tracing: create automated trace defines Steven Rostedt 2009-04-14 23:44 ` Jeremy Fitzhardinge @ 2009-04-15 7:04 ` Zhaolei 1 sibling, 0 replies; 60+ messages in thread From: Zhaolei @ 2009-04-15 7:04 UTC (permalink / raw) To: Steven Rostedt Cc: linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh, Peter Zijlstra, Neil Horman, Eduard - Gabriel Munteanu, Pekka Enberg Steven Rostedt wrote: > From: Steven Rostedt <srostedt@redhat.com> > > This patch lowers the number of places a developer must modify to add > new tracepoints. The current method to add a new tracepoint > into an existing system is to write the trace point macro in the > trace header with one of the macros TRACE_EVENT, TRACE_FORMAT or > DECLARE_TRACE, then they must add the same named item into the C file > with the macro DEFINE_TRACE(name) and then add the trace point. > > This change cuts out the needing to add the DEFINE_TRACE(name). > Every file that uses the tracepoint must still include the trace/<type>.h > file, but the one C file must also add a define before the including > of that file. > > #define CREATE_TRACE_POINTS > #include <trace/mytrace.h> > > This will cause the trace/mytrace.h file to also produce the C code > necessary to implement the trace point. > > Note, if more than one trace/<type>.h is used to create the C code > it is best to list them all together. > > #define CREATE_TRACE_POINTS > #include <trace/foo.h> > #include <trace/bar.h> > #include <trace/fido.h> > > Thanks to Mathieu Desnoyers and Christoph Hellwig for coming up with > the cleaner solution of the define above the includes over my first > design to have the C code include a "special" header. > > This patch converts sched, irq and lockdep and skb to use this new > method. > > Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Neil Horman <nhorman@tuxdriver.com> > Cc: Zhao Lei <zhaolei@cn.fujitsu.com> > Cc: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro> > Cc: Pekka Enberg <penberg@cs.helsinki.fi> > Signed-off-by: Steven Rostedt <rostedt@goodmis.org> > --- > include/trace/define_trace.h | 75 ++++++++++++++++++++++++++++++++++++++++++ > include/trace/irq.h | 5 ++- > include/trace/kmem.h | 4 ++- > include/trace/lockdep.h | 3 ++ > include/trace/sched.h | 3 ++ > include/trace/skb.h | 3 ++ > kernel/exit.c | 4 -- > kernel/fork.c | 2 - > kernel/irq/handle.c | 7 ++-- > kernel/kthread.c | 3 -- > kernel/lockdep.c | 12 ++----- > kernel/sched.c | 10 ++---- > kernel/signal.c | 2 - > kernel/softirq.c | 3 -- > mm/util.c | 11 ++---- > net/core/net-traces.c | 4 +- > 16 files changed, 105 insertions(+), 46 deletions(-) > create mode 100644 include/trace/define_trace.h > > diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h > new file mode 100644 > index 0000000..de9dc7d > --- /dev/null > +++ b/include/trace/define_trace.h > @@ -0,0 +1,75 @@ > +/* > + * Trace files that want to automate creationg of all tracepoints defined > + * in their file should include this file. The following are macros that the > + * trace file may define: > + * > + * TRACE_SYSTEM defines the system the tracepoint is for > + * > + * TRACE_INCLUDE_FILE if the file name is something other than TRACE_SYSTEM.h > + * This macro may be defined to tell define_trace.h what file to include. > + * Note, leave off the ".h". > + * > + * TRACE_INCLUDE_PATH if the path is something other than core kernel include/trace > + * then this macro can define the path to use. Note, the path is relative to > + * define_trace.h, not the file including it. Full path names for out of tree > + * modules must be used. > + */ > + > +#ifdef CREATE_TRACE_POINTS > + > +/* Prevent recursion */ > +#undef CREATE_TRACE_POINTS > + > +#include <linux/stringify.h> > + > +#undef TRACE_EVENT > +#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ > + DEFINE_TRACE(name) > + > +#undef TRACE_FORMAT > +#define TRACE_FORMAT(name, proto, args, print) \ > + DEFINE_TRACE(name) > + > +#undef DECLARE_TRACE > +#define DECLARE_TRACE(name, proto, args) \ > + DEFINE_TRACE(name) > + > +#undef TRACE_INCLUDE > +#undef __TRACE_INCLUDE > + > +#ifndef TRACE_INCLUDE_FILE > +# define TRACE_INCLUDE_FILE TRACE_SYSTEM > +# define UNDEF_TRACE_INCLUDE_FILE > +#endif > + > +#ifndef TRACE_INCLUDE_PATH > +# define __TRACE_INCLUDE(system) <trace/system.h> > +# define UNDEF_TRACE_INCLUDE_FILE > +#else > +# define __TRACE_INCLUDE(system) __stringify(TRACE_INCLUDE_PATH/system.h) > +#endif > + > +# define TRACE_INCLUDE(system) __TRACE_INCLUDE(system) > + > +/* Let the trace headers be reread */ > +#define TRACE_HEADER_MULTI_READ > + > +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) Hello, Steven Include header file again is a power trap full of imagination. It is great... but maybe we can choose a stupid way if we have. And, TRACE_SYSTEM must be same as header file name if we use current way. How about just #define TRACE_EVENT(name, proto, args, fmt) \ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) \ DEFINE_TRACE(name) in tracepoint.h? It means we always define both whether for tracepoint provider or for tracepoint user.(and make compiler a bit slow) Thanks Zhaolei > + > +#undef TRACE_HEADER_MULTI_READ > + > +/* Only undef what we defined in this file */ > +#ifdef UNDEF_TRACE_INCLUDE_FILE > +# undef TRACE_INCLUDE_PATH > +# undef UNDEF_TRACE_INCLUDE_FILE > +#endif > + > +#ifdef UNDEF_TRACE_INCLUDE_FILE > +# undef TRACE_INCLUDE_PATH > +# undef UNDEF_TRACE_INCLUDE_FILE > +#endif > + > +/* We may be processing more files */ > +#define CREATE_TRACE_POINTS > + > +#endif /* CREATE_TRACE_POINTS */ > diff --git a/include/trace/irq.h b/include/trace/irq.h > index 04ab4c6..75e3468 100644 > --- a/include/trace/irq.h > +++ b/include/trace/irq.h > @@ -51,4 +51,7 @@ TRACE_FORMAT(softirq_exit, > TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec]) > ); > > -#endif > +#endif /* _TRACE_IRQ_H */ > + > +/* This part must be outside protection */ > +#include <trace/define_trace.h> > diff --git a/include/trace/kmem.h b/include/trace/kmem.h > index d7d1218..c22c42f 100644 > --- a/include/trace/kmem.h > +++ b/include/trace/kmem.h > @@ -188,5 +188,7 @@ TRACE_EVENT(kmem_cache_free, > > TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) > ); > +#endif /* _TRACE_KMEM_H */ > > -#endif > +/* This part must be outside protection */ > +#include <trace/define_trace.h> > diff --git a/include/trace/lockdep.h b/include/trace/lockdep.h > index 8ee7900..4d301e7 100644 > --- a/include/trace/lockdep.h > +++ b/include/trace/lockdep.h > @@ -55,3 +55,6 @@ TRACE_EVENT(lock_acquired, > #endif > > #endif /* _TRACE_LOCKDEP_H */ > + > +/* This part must be outside protection */ > +#include <trace/define_trace.h> > diff --git a/include/trace/sched.h b/include/trace/sched.h > index 5b1cf4a..ffa1cab 100644 > --- a/include/trace/sched.h > +++ b/include/trace/sched.h > @@ -334,3 +334,6 @@ TRACE_EVENT(sched_signal_send, > ); > > #endif /* _TRACE_SCHED_H */ > + > +/* This part must be outside protection */ > +#include <trace/define_trace.h> > diff --git a/include/trace/skb.h b/include/trace/skb.h > index e6fd281..1e8fabb 100644 > --- a/include/trace/skb.h > +++ b/include/trace/skb.h > @@ -35,3 +35,6 @@ TRACE_EVENT(kfree_skb, > ); > > #endif /* _TRACE_SKB_H */ > + > +/* This part must be outside protection */ > +#include <trace/define_trace.h> > diff --git a/kernel/exit.c b/kernel/exit.c > index abf9cf3..2fe9d2c 100644 > --- a/kernel/exit.c > +++ b/kernel/exit.c > @@ -56,10 +56,6 @@ > #include <asm/mmu_context.h> > #include "cred-internals.h" > > -DEFINE_TRACE(sched_process_free); > -DEFINE_TRACE(sched_process_exit); > -DEFINE_TRACE(sched_process_wait); > - > static void exit_mm(struct task_struct * tsk); > > static void __unhash_process(struct task_struct *p) > diff --git a/kernel/fork.c b/kernel/fork.c > index b9e2edd..4bebf26 100644 > --- a/kernel/fork.c > +++ b/kernel/fork.c > @@ -83,8 +83,6 @@ DEFINE_PER_CPU(unsigned long, process_counts) = 0; > > __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ > > -DEFINE_TRACE(sched_process_fork); > - > int nr_processes(void) > { > int cpu; > diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c > index d82142b..983d8be 100644 > --- a/kernel/irq/handle.c > +++ b/kernel/irq/handle.c > @@ -17,9 +17,11 @@ > #include <linux/kernel_stat.h> > #include <linux/rculist.h> > #include <linux/hash.h> > -#include <trace/irq.h> > #include <linux/bootmem.h> > > +#define CREATE_TRACE_POINTS > +#include <trace/irq.h> > + > #include "internals.h" > > /* > @@ -348,9 +350,6 @@ static void warn_no_thread(unsigned int irq, struct irqaction *action) > "but no thread function available.", irq, action->name); > } > > -DEFINE_TRACE(irq_handler_entry); > -DEFINE_TRACE(irq_handler_exit); > - > /** > * handle_IRQ_event - irq action chain handler > * @irq: the interrupt number > diff --git a/kernel/kthread.c b/kernel/kthread.c > index 4ebaf85..e1c7692 100644 > --- a/kernel/kthread.c > +++ b/kernel/kthread.c > @@ -21,9 +21,6 @@ static DEFINE_SPINLOCK(kthread_create_lock); > static LIST_HEAD(kthread_create_list); > struct task_struct *kthreadd_task; > > -DEFINE_TRACE(sched_kthread_stop); > -DEFINE_TRACE(sched_kthread_stop_ret); > - > struct kthread_create_info > { > /* Information passed to kthread() from kthreadd. */ > diff --git a/kernel/lockdep.c b/kernel/lockdep.c > index c4582a6..257f21a 100644 > --- a/kernel/lockdep.c > +++ b/kernel/lockdep.c > @@ -42,12 +42,14 @@ > #include <linux/hash.h> > #include <linux/ftrace.h> > #include <linux/stringify.h> > -#include <trace/lockdep.h> > > #include <asm/sections.h> > > #include "lockdep_internals.h" > > +#define CREATE_TRACE_POINTS > +#include <trace/lockdep.h> > + > #ifdef CONFIG_PROVE_LOCKING > int prove_locking = 1; > module_param(prove_locking, int, 0644); > @@ -2929,8 +2931,6 @@ void lock_set_class(struct lockdep_map *lock, const char *name, > } > EXPORT_SYMBOL_GPL(lock_set_class); > > -DEFINE_TRACE(lock_acquire); > - > /* > * We are not always called with irqs disabled - do that here, > * and also avoid lockdep recursion: > @@ -2957,8 +2957,6 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, > } > EXPORT_SYMBOL_GPL(lock_acquire); > > -DEFINE_TRACE(lock_release); > - > void lock_release(struct lockdep_map *lock, int nested, > unsigned long ip) > { > @@ -3061,8 +3059,6 @@ found_it: > put_lock_stats(stats); > } > > -DEFINE_TRACE(lock_acquired); > - > static void > __lock_acquired(struct lockdep_map *lock, unsigned long ip) > { > @@ -3118,8 +3114,6 @@ found_it: > lock->ip = ip; > } > > -DEFINE_TRACE(lock_contended); > - > void lock_contended(struct lockdep_map *lock, unsigned long ip) > { > unsigned long flags; > diff --git a/kernel/sched.c b/kernel/sched.c > index 5724508..e6d4518 100644 > --- a/kernel/sched.c > +++ b/kernel/sched.c > @@ -72,13 +72,15 @@ > #include <linux/debugfs.h> > #include <linux/ctype.h> > #include <linux/ftrace.h> > -#include <trace/sched.h> > > #include <asm/tlb.h> > #include <asm/irq_regs.h> > > #include "sched_cpupri.h" > > +#define CREATE_TRACE_POINTS > +#include <trace/sched.h> > + > /* > * Convert user-nice values [ -20 ... 0 ... 19 ] > * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], > @@ -118,12 +120,6 @@ > */ > #define RUNTIME_INF ((u64)~0ULL) > > -DEFINE_TRACE(sched_wait_task); > -DEFINE_TRACE(sched_wakeup); > -DEFINE_TRACE(sched_wakeup_new); > -DEFINE_TRACE(sched_switch); > -DEFINE_TRACE(sched_migrate_task); > - > #ifdef CONFIG_SMP > > static void double_rq_lock(struct rq *rq1, struct rq *rq2); > diff --git a/kernel/signal.c b/kernel/signal.c > index d803473..1d5703f 100644 > --- a/kernel/signal.c > +++ b/kernel/signal.c > @@ -41,8 +41,6 @@ > > static struct kmem_cache *sigqueue_cachep; > > -DEFINE_TRACE(sched_signal_send); > - > static void __user *sig_handler(struct task_struct *t, int sig) > { > return t->sighand->action[sig - 1].sa.sa_handler; > diff --git a/kernel/softirq.c b/kernel/softirq.c > index 2fecefa..a2d9b45 100644 > --- a/kernel/softirq.c > +++ b/kernel/softirq.c > @@ -186,9 +186,6 @@ EXPORT_SYMBOL(local_bh_enable_ip); > */ > #define MAX_SOFTIRQ_RESTART 10 > > -DEFINE_TRACE(softirq_entry); > -DEFINE_TRACE(softirq_exit); > - > asmlinkage void __do_softirq(void) > { > struct softirq_action *h; > diff --git a/mm/util.c b/mm/util.c > index 2599e83..0e74a22 100644 > --- a/mm/util.c > +++ b/mm/util.c > @@ -4,9 +4,11 @@ > #include <linux/module.h> > #include <linux/err.h> > #include <linux/sched.h> > -#include <linux/tracepoint.h> > #include <asm/uaccess.h> > > +#define CREATE_TRACE_POINTS > +#include <trace/kmem.h> > + > /** > * kstrdup - allocate space for and copy an existing string > * @s: the string to duplicate > @@ -239,13 +241,6 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start, > EXPORT_SYMBOL_GPL(get_user_pages_fast); > > /* Tracepoints definitions. */ > -DEFINE_TRACE(kmalloc); > -DEFINE_TRACE(kmem_cache_alloc); > -DEFINE_TRACE(kmalloc_node); > -DEFINE_TRACE(kmem_cache_alloc_node); > -DEFINE_TRACE(kfree); > -DEFINE_TRACE(kmem_cache_free); > - > EXPORT_TRACEPOINT_SYMBOL(kmalloc); > EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc); > EXPORT_TRACEPOINT_SYMBOL(kmalloc_node); > diff --git a/net/core/net-traces.c b/net/core/net-traces.c > index c8fb456..8017720 100644 > --- a/net/core/net-traces.c > +++ b/net/core/net-traces.c > @@ -19,11 +19,11 @@ > #include <linux/workqueue.h> > #include <linux/netlink.h> > #include <linux/net_dropmon.h> > -#include <trace/skb.h> > > #include <asm/unaligned.h> > #include <asm/bitops.h> > > +#define CREATE_TRACE_POINTS > +#include <trace/skb.h> > > -DEFINE_TRACE(kfree_skb); > EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb); ^ permalink raw reply [flat|nested] 60+ messages in thread
* [PATCH 3/8] tracing: make trace_seq operations available for core kernel 2009-04-14 17:23 [PATCH 0/8] [GIT PULL] TRACE_EVENT for modules Steven Rostedt 2009-04-14 17:23 ` [PATCH 1/8] tracing: consolidate trace and trace_event headers Steven Rostedt 2009-04-14 17:23 ` [PATCH 2/8] tracing: create automated trace defines Steven Rostedt @ 2009-04-14 17:23 ` Steven Rostedt 2009-04-14 19:12 ` Peter Zijlstra 2009-04-14 17:23 ` [PATCH 4/8] tracing/events: move declarations from trace directory to core include Steven Rostedt ` (7 subsequent siblings) 10 siblings, 1 reply; 60+ messages in thread From: Steven Rostedt @ 2009-04-14 17:23 UTC (permalink / raw) To: linux-kernel Cc: Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh [-- Attachment #1: 0003-tracing-make-trace_seq-operations-available-for-cor.patch --] [-- Type: text/plain, Size: 6057 bytes --] From: Steven Rostedt <srostedt@redhat.com> In the process to make TRACE_EVENT macro work for modules, the trace_seq operations must be available for core kernel code. These operations are quite useful and can be used for other implementations. The main idea is that we create a trace_seq handle that acts very much like the seq_file handle. struct trace_seq *s = kmalloc(sizeof(*s, GFP_KERNEL); trace_seq_init(s); trace_seq_printf(s, "some data %d\n", variable); printk("%s", s->buffer); The main use is to allow a top level function call several other functions that may store printf like data into the buffer. Then at the end, the top level function can process all the data with any method it would like to. It could be passed to userspace, output via printk or even use seq_file: trace_seq_to_user(s, ubuf, cnt); seq_puts(m, s->buffer); Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- include/linux/trace_seq.h | 89 +++++++++++++++++++++++++++++++++++++++++++ kernel/trace/trace.h | 15 +------ kernel/trace/trace_output.h | 16 +------- 3 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 include/linux/trace_seq.h diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h new file mode 100644 index 0000000..28051da --- /dev/null +++ b/include/linux/trace_seq.h @@ -0,0 +1,89 @@ +#ifndef _LINUX_TRACE_SEQ_H +#define _LINUX_TRACE_SEQ_H + +/* + * Trace sequences are used to allow a function to call several other functions + * to create a string of data to use (up to a max of PAGE_SIZE. + */ + +struct trace_seq { + unsigned char buffer[PAGE_SIZE]; + unsigned int len; + unsigned int readpos; +}; + +static inline void +trace_seq_init(struct trace_seq *s) +{ + s->len = 0; + s->readpos = 0; +} + +/* + * Currently only defined when tracing is enabled. + */ +#ifdef CONFIG_TRACING +extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); +extern int +trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); +extern void trace_print_seq(struct seq_file *m, struct trace_seq *s); +extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, + size_t cnt); +extern int trace_seq_puts(struct trace_seq *s, const char *str); +extern int trace_seq_putc(struct trace_seq *s, unsigned char c); +extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len); +extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, + size_t len); +extern void *trace_seq_reserve(struct trace_seq *s, size_t len); +extern int trace_seq_path(struct trace_seq *s, struct path *path); + +#else /* CONFIG_TRACING */ +static inline int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))) +{ + return 0; +} +static inline int +trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) +{ + return 0; +} + +static inline void trace_print_seq(struct seq_file *m, struct trace_seq *s) +{ +} +static inline ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, + size_t cnt) +{ + return 0; +} +static inline int trace_seq_puts(struct trace_seq *s, const char *str) +{ + return 0; +} +static inline int trace_seq_putc(struct trace_seq *s, unsigned char c); +{ + return 0; +} +static inline int +trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) +{ + return 0; +} +static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, + size_t len) +{ + return 0; +} +static inline void *trace_seq_reserve(struct trace_seq *s, size_t len) +{ + return NULL; +} +static inline int trace_seq_path(struct trace_seq *s, struct path *path) +{ + return 0; +} +#endif /* CONFIG_TRACING */ + +#endif /* _LINUX_TRACE_SEQ_H */ diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index b05b6ac..1882846 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -12,6 +12,8 @@ #include <linux/kmemtrace.h> #include <trace/power.h> +#include <linux/trace_seq.h> + enum trace_type { __TRACE_FIRST_TYPE = 0, @@ -423,19 +425,6 @@ struct tracer { struct tracer_stat *stats; }; -struct trace_seq { - unsigned char buffer[PAGE_SIZE]; - unsigned int len; - unsigned int readpos; -}; - -static inline void -trace_seq_init(struct trace_seq *s) -{ - s->len = 0; - s->readpos = 0; -} - #define TRACE_PIPE_ALL_CPU -1 diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h index 9163021..5c7cbfb 100644 --- a/kernel/trace/trace_output.h +++ b/kernel/trace/trace_output.h @@ -1,6 +1,7 @@ #ifndef __TRACE_EVENTS_H #define __TRACE_EVENTS_H +#include <linux/trace_seq.h> #include "trace.h" typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, @@ -20,24 +21,9 @@ trace_print_bprintk_msg_only(struct trace_iterator *iter); extern enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter); -extern void trace_print_seq(struct seq_file *m, struct trace_seq *s); - -extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); -extern int -trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); extern int seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags); -extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, - size_t cnt); -extern int trace_seq_puts(struct trace_seq *s, const char *str); -extern int trace_seq_putc(struct trace_seq *s, unsigned char c); -extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len); -extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, - size_t len); -extern void *trace_seq_reserve(struct trace_seq *s, size_t len); -extern int trace_seq_path(struct trace_seq *s, struct path *path); extern int seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s, unsigned long sym_flags); extern int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm, -- 1.6.2.1 -- ^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [PATCH 3/8] tracing: make trace_seq operations available for core kernel 2009-04-14 17:23 ` [PATCH 3/8] tracing: make trace_seq operations available for core kernel Steven Rostedt @ 2009-04-14 19:12 ` Peter Zijlstra 2009-04-15 2:19 ` Steven Rostedt 0 siblings, 1 reply; 60+ messages in thread From: Peter Zijlstra @ 2009-04-14 19:12 UTC (permalink / raw) To: Steven Rostedt Cc: linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh On Tue, 2009-04-14 at 13:23 -0400, Steven Rostedt wrote: > +struct trace_seq { > + unsigned char buffer[PAGE_SIZE]; > + unsigned int len; > + unsigned int readpos; > +}; Would not PAGE_SIZE-2*sizeof(int) be enough? That would make the struct fit into a single page and avoid an order-1 allocation. ^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH 3/8] tracing: make trace_seq operations available for core kernel 2009-04-14 19:12 ` Peter Zijlstra @ 2009-04-15 2:19 ` Steven Rostedt 0 siblings, 0 replies; 60+ messages in thread From: Steven Rostedt @ 2009-04-15 2:19 UTC (permalink / raw) To: Peter Zijlstra Cc: linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh On Tue, 14 Apr 2009, Peter Zijlstra wrote: > On Tue, 2009-04-14 at 13:23 -0400, Steven Rostedt wrote: > > +struct trace_seq { > > + unsigned char buffer[PAGE_SIZE]; > > + unsigned int len; > > + unsigned int readpos; > > +}; > > Would not PAGE_SIZE-2*sizeof(int) be enough? That would make the struct > fit into a single page and avoid an order-1 allocation. That may be an option. I've even thought about doing that before. Not sure why I did not. But we could give it a try. -- Steve ^ permalink raw reply [flat|nested] 60+ messages in thread
* [PATCH 4/8] tracing/events: move declarations from trace directory to core include 2009-04-14 17:23 [PATCH 0/8] [GIT PULL] TRACE_EVENT for modules Steven Rostedt ` (2 preceding siblings ...) 2009-04-14 17:23 ` [PATCH 3/8] tracing: make trace_seq operations available for core kernel Steven Rostedt @ 2009-04-14 17:23 ` Steven Rostedt 2009-04-14 17:23 ` [PATCH 5/8] tracing/events: move the ftrace event tracing code to core Steven Rostedt ` (6 subsequent siblings) 10 siblings, 0 replies; 60+ messages in thread From: Steven Rostedt @ 2009-04-14 17:23 UTC (permalink / raw) To: linux-kernel Cc: Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh [-- Attachment #1: 0004-tracing-events-move-declarations-from-trace-directo.patch --] [-- Type: text/plain, Size: 12936 bytes --] From: Steven Rostedt <srostedt@redhat.com> In preparation to allowing trace events to happen in modules, we need to move some of the local declarations in the kernel/trace directory into include/linux. This patch simply moves the declarations and performs no context changes. Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- include/linux/ftrace_event.h | 146 ++++++++++++++++++++++++++++++++++++++++++ kernel/trace/trace.h | 120 +---------------------------------- kernel/trace/trace_output.h | 14 ---- 3 files changed, 147 insertions(+), 133 deletions(-) create mode 100644 include/linux/ftrace_event.h diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h new file mode 100644 index 0000000..496b76d --- /dev/null +++ b/include/linux/ftrace_event.h @@ -0,0 +1,146 @@ +#ifndef _LINUX_FTRACE_EVENT_H +#define _LINUX_FTRACE_EVENT_H + +#include <linux/trace_seq.h> +#include <linux/ring_buffer.h> + + +struct trace_array; +struct tracer; + +/* + * The trace entry - the most basic unit of tracing. This is what + * is printed in the end as a single line in the trace output, such as: + * + * bash-15816 [01] 235.197585: idle_cpu <- irq_enter + */ +struct trace_entry { + unsigned char type; + unsigned char flags; + unsigned char preempt_count; + int pid; + int tgid; +}; + +/* + * Trace iterator - used by printout routines who present trace + * results to users and which routines might sleep, etc: + */ +struct trace_iterator { + struct trace_array *tr; + struct tracer *trace; + void *private; + int cpu_file; + struct mutex mutex; + struct ring_buffer_iter *buffer_iter[NR_CPUS]; + + /* The below is zeroed out in pipe_read */ + struct trace_seq seq; + struct trace_entry *ent; + int cpu; + u64 ts; + + unsigned long iter_flags; + loff_t pos; + long idx; + + cpumask_var_t started; +}; + + +typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, + int flags); +struct trace_event { + struct hlist_node node; + int type; + trace_print_func trace; + trace_print_func raw; + trace_print_func hex; + trace_print_func binary; +}; + +extern int register_ftrace_event(struct trace_event *event); +extern int unregister_ftrace_event(struct trace_event *event); + +/* Return values for print_line callback */ +enum print_line_t { + TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */ + TRACE_TYPE_HANDLED = 1, + TRACE_TYPE_UNHANDLED = 2, /* Relay to other output functions */ + TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */ +}; + + +struct ring_buffer_event * +trace_current_buffer_lock_reserve(unsigned char type, unsigned long len, + unsigned long flags, int pc); +void trace_current_buffer_unlock_commit(struct ring_buffer_event *event, + unsigned long flags, int pc); +void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event, + unsigned long flags, int pc); +void trace_current_buffer_discard_commit(struct ring_buffer_event *event); + +void tracing_record_cmdline(struct task_struct *tsk); + +struct ftrace_event_call { + char *name; + char *system; + struct dentry *dir; + int enabled; + int (*regfunc)(void); + void (*unregfunc)(void); + int id; + int (*raw_init)(void); + int (*show_format)(struct trace_seq *s); + int (*define_fields)(void); + struct list_head fields; + int n_preds; + struct filter_pred **preds; + +#ifdef CONFIG_EVENT_PROFILE + atomic_t profile_count; + int (*profile_enable)(struct ftrace_event_call *); + void (*profile_disable)(struct ftrace_event_call *); +#endif +}; + +#define MAX_FILTER_PRED 8 +#define MAX_FILTER_STR_VAL 128 + +extern int init_preds(struct ftrace_event_call *call); +extern int filter_match_preds(struct ftrace_event_call *call, void *rec); +extern int filter_current_check_discard(struct ftrace_event_call *call, + void *rec, + struct ring_buffer_event *event); + +extern int trace_define_field(struct ftrace_event_call *call, char *type, + char *name, int offset, int size); + + +/* + * The double __builtin_constant_p is because gcc will give us an error + * if we try to allocate the static variable to fmt if it is not a + * constant. Even with the outer if statement optimizing out. + */ +#define event_trace_printk(ip, fmt, args...) \ +do { \ + __trace_printk_check_format(fmt, ##args); \ + tracing_record_cmdline(current); \ + if (__builtin_constant_p(fmt)) { \ + static const char *trace_printk_fmt \ + __attribute__((section("__trace_printk_fmt"))) = \ + __builtin_constant_p(fmt) ? fmt : NULL; \ + \ + __trace_bprintk(ip, trace_printk_fmt, ##args); \ + } else \ + __trace_printk(ip, fmt, ##args); \ +} while (0) + +#define __common_field(type, item) \ + ret = trace_define_field(event_call, #type, "common_" #item, \ + offsetof(typeof(field.ent), item), \ + sizeof(field.ent.item)); \ + if (ret) \ + return ret; + +#endif /* _LINUX_FTRACE_EVENT_H */ diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 1882846..6bcdf4a 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -13,6 +13,7 @@ #include <trace/power.h> #include <linux/trace_seq.h> +#include <linux/ftrace_event.h> enum trace_type { __TRACE_FIRST_TYPE = 0, @@ -44,20 +45,6 @@ enum trace_type { }; /* - * The trace entry - the most basic unit of tracing. This is what - * is printed in the end as a single line in the trace output, such as: - * - * bash-15816 [01] 235.197585: idle_cpu <- irq_enter - */ -struct trace_entry { - unsigned char type; - unsigned char flags; - unsigned char preempt_count; - int pid; - int tgid; -}; - -/* * Function trace entry - function address and parent function addres: */ struct ftrace_entry { @@ -265,8 +252,6 @@ struct trace_array_cpu { char comm[TASK_COMM_LEN]; }; -struct trace_iterator; - /* * The trace array - an array of per-CPU trace arrays. This is the * highest level data structure that individual tracers deal with. @@ -341,15 +326,6 @@ extern void __ftrace_bad_type(void); __ftrace_bad_type(); \ } while (0) -/* Return values for print_line callback */ -enum print_line_t { - TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */ - TRACE_TYPE_HANDLED = 1, - TRACE_TYPE_UNHANDLED = 2, /* Relay to other output functions */ - TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */ -}; - - /* * An option specific to a tracer. This is a boolean value. * The bit is the bit index that sets its value on the @@ -428,31 +404,6 @@ struct tracer { #define TRACE_PIPE_ALL_CPU -1 -/* - * Trace iterator - used by printout routines who present trace - * results to users and which routines might sleep, etc: - */ -struct trace_iterator { - struct trace_array *tr; - struct tracer *trace; - void *private; - int cpu_file; - struct mutex mutex; - struct ring_buffer_iter *buffer_iter[NR_CPUS]; - - /* The below is zeroed out in pipe_read */ - struct trace_seq seq; - struct trace_entry *ent; - int cpu; - u64 ts; - - unsigned long iter_flags; - loff_t pos; - long idx; - - cpumask_var_t started; -}; - int tracer_init(struct tracer *t, struct trace_array *tr); int tracing_is_enabled(void); void trace_wake_up(void); @@ -479,15 +430,6 @@ void trace_buffer_unlock_commit(struct trace_array *tr, struct ring_buffer_event *event, unsigned long flags, int pc); -struct ring_buffer_event * -trace_current_buffer_lock_reserve(unsigned char type, unsigned long len, - unsigned long flags, int pc); -void trace_current_buffer_unlock_commit(struct ring_buffer_event *event, - unsigned long flags, int pc); -void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event, - unsigned long flags, int pc); -void trace_current_buffer_discard_commit(struct ring_buffer_event *event); - struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data); @@ -510,7 +452,6 @@ void tracing_sched_switch_trace(struct trace_array *tr, struct task_struct *prev, struct task_struct *next, unsigned long flags, int pc); -void tracing_record_cmdline(struct task_struct *tsk); void tracing_sched_wakeup_trace(struct trace_array *tr, struct task_struct *wakee, @@ -790,28 +731,6 @@ struct ftrace_event_field { int size; }; -struct ftrace_event_call { - char *name; - char *system; - struct dentry *dir; - int enabled; - int (*regfunc)(void); - void (*unregfunc)(void); - int id; - int (*raw_init)(void); - int (*show_format)(struct trace_seq *s); - int (*define_fields)(void); - struct list_head fields; - int n_preds; - struct filter_pred **preds; - -#ifdef CONFIG_EVENT_PROFILE - atomic_t profile_count; - int (*profile_enable)(struct ftrace_event_call *); - void (*profile_disable)(struct ftrace_event_call *); -#endif -}; - struct event_subsystem { struct list_head list; const char *name; @@ -825,9 +744,6 @@ struct event_subsystem { (unsigned long)event < (unsigned long)__stop_ftrace_events; \ event++) -#define MAX_FILTER_PRED 8 -#define MAX_FILTER_STR_VAL 128 - struct filter_pred; typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event); @@ -845,9 +761,6 @@ struct filter_pred { int clear; }; -int trace_define_field(struct ftrace_event_call *call, char *type, - char *name, int offset, int size); -extern int init_preds(struct ftrace_event_call *call); extern void filter_free_pred(struct filter_pred *pred); extern void filter_print_preds(struct filter_pred **preds, int n_preds, struct trace_seq *s); @@ -855,13 +768,9 @@ extern int filter_parse(char **pbuf, struct filter_pred *pred); extern int filter_add_pred(struct ftrace_event_call *call, struct filter_pred *pred); extern void filter_disable_preds(struct ftrace_event_call *call); -extern int filter_match_preds(struct ftrace_event_call *call, void *rec); extern void filter_free_subsystem_preds(struct event_subsystem *system); extern int filter_add_subsystem_pred(struct event_subsystem *system, struct filter_pred *pred); -extern int filter_current_check_discard(struct ftrace_event_call *call, - void *rec, - struct ring_buffer_event *event); static inline int filter_check_discard(struct ftrace_event_call *call, void *rec, @@ -876,14 +785,6 @@ filter_check_discard(struct ftrace_event_call *call, void *rec, return 0; } -#define __common_field(type, item) \ - ret = trace_define_field(event_call, #type, "common_" #item, \ - offsetof(typeof(field.ent), item), \ - sizeof(field.ent.item)); \ - if (ret) \ - return ret; - -void event_trace_printk(unsigned long ip, const char *fmt, ...); extern struct ftrace_event_call __start_ftrace_events[]; extern struct ftrace_event_call __stop_ftrace_events[]; @@ -895,25 +796,6 @@ extern struct ftrace_event_call __stop_ftrace_events[]; extern const char *__start___trace_bprintk_fmt[]; extern const char *__stop___trace_bprintk_fmt[]; -/* - * The double __builtin_constant_p is because gcc will give us an error - * if we try to allocate the static variable to fmt if it is not a - * constant. Even with the outer if statement optimizing out. - */ -#define event_trace_printk(ip, fmt, args...) \ -do { \ - __trace_printk_check_format(fmt, ##args); \ - tracing_record_cmdline(current); \ - if (__builtin_constant_p(fmt)) { \ - static const char *trace_printk_fmt \ - __attribute__((section("__trace_printk_fmt"))) = \ - __builtin_constant_p(fmt) ? fmt : NULL; \ - \ - __trace_bprintk(ip, trace_printk_fmt, ##args); \ - } else \ - __trace_printk(ip, fmt, ##args); \ -} while (0) - #undef TRACE_EVENT_FORMAT #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ extern struct ftrace_event_call event_##call; diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h index 5c7cbfb..6e220a8 100644 --- a/kernel/trace/trace_output.h +++ b/kernel/trace/trace_output.h @@ -4,18 +4,6 @@ #include <linux/trace_seq.h> #include "trace.h" -typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, - int flags); - -struct trace_event { - struct hlist_node node; - int type; - trace_print_func trace; - trace_print_func raw; - trace_print_func hex; - trace_print_func binary; -}; - extern enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter); extern enum print_line_t @@ -33,8 +21,6 @@ extern int trace_print_context(struct trace_iterator *iter); extern int trace_print_lat_context(struct trace_iterator *iter); extern struct trace_event *ftrace_find_event(int type); -extern int register_ftrace_event(struct trace_event *event); -extern int unregister_ftrace_event(struct trace_event *event); extern enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags); -- 1.6.2.1 -- ^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PATCH 5/8] tracing/events: move the ftrace event tracing code to core 2009-04-14 17:23 [PATCH 0/8] [GIT PULL] TRACE_EVENT for modules Steven Rostedt ` (3 preceding siblings ...) 2009-04-14 17:23 ` [PATCH 4/8] tracing/events: move declarations from trace directory to core include Steven Rostedt @ 2009-04-14 17:23 ` Steven Rostedt 2009-04-14 19:23 ` Peter Zijlstra 2009-04-14 17:23 ` [PATCH 6/8] tracing/events: convert event call sites to use a link list Steven Rostedt ` (5 subsequent siblings) 10 siblings, 1 reply; 60+ messages in thread From: Steven Rostedt @ 2009-04-14 17:23 UTC (permalink / raw) To: linux-kernel Cc: Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra, Frederic Weisbecker, Theodore Tso, Arjan van de Ven, Christoph Hellwig, Mathieu Desnoyers, Jeremy Fitzhardinge, Lai Jiangshan, Zhaolei, Li Zefan, KOSAKI Motohiro, Masami Hiramatsu, Frank Ch. Eigler, Tom Zanussi, Jiaying Zhang, Michael Rubin, Martin Bligh [-- Attachment #1: 0005-tracing-events-move-the-ftrace-event-tracing-code-t.patch --] [-- Type: text/plain, Size: 30467 bytes --] From: Steven Rostedt <srostedt@redhat.com> This patch moves the ftrace creation into include/trace/ftrace.h and simplifies the work of developers in adding new tracepoints. Just the act of creating the trace points in include/trace and including define_trace.h will create the events in the debugfs/tracing/events directory. This patch removes the need of include/trace/trace_events.h Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- include/trace/define_trace.h | 4 + include/trace/ftrace.h | 492 +++++++++++++++++++++++++++++++++++ include/trace/trace_events.h | 7 - kernel/trace/Makefile | 1 - kernel/trace/events.c | 15 - kernel/trace/trace_events_stage_1.h | 39 --- kernel/trace/trace_events_stage_2.h | 170 ------------ kernel/trace/trace_events_stage_3.h | 279 -------------------- 8 files changed, 496 insertions(+), 511 deletions(-) create mode 100644 include/trace/ftrace.h delete mode 100644 include/trace/trace_events.h delete mode 100644 kernel/trace/events.c delete mode 100644 kernel/trace/trace_events_stage_1.h delete mode 100644 kernel/trace/trace_events_stage_2.h delete mode 100644 kernel/trace/trace_events_stage_3.h diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h index de9dc7d..980eb66 100644 --- a/include/trace/define_trace.h +++ b/include/trace/define_trace.h @@ -56,6 +56,10 @@ #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) +#ifdef CONFIG_EVENT_TRACER +#include <trace/ftrace.h> +#endif + #undef TRACE_HEADER_MULTI_READ /* Only undef what we defined in this file */ diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h new file mode 100644 index 0000000..955b967 --- /dev/null +++ b/include/trace/ftrace.h @@ -0,0 +1,492 @@ +/* + * Stage 1 of the trace events. + * + * Override the macros in <trace/trace_events.h> to include the following: + * + * struct ftrace_raw_<call> { + * struct trace_entry ent; + * <type> <item>; + * <type2> <item2>[<len>]; + * [...] + * }; + * + * The <type> <item> is created by the __field(type, item) macro or + * the __array(type2, item2, len) macro. + * We simply do "type item;", and that will create the fields + * in the structure. + */ + +#include <linux/ftrace_event.h> + +#undef TRACE_FORMAT +#define TRACE_FORMAT(call, proto, args, fmt) + +#undef __array +#define __array(type, item, len) type item[len]; + +#undef __field +#define __field(type, item) type item; + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) args + +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ + struct ftrace_raw_##name { \ + struct trace_entry ent; \ + tstruct \ + }; \ + static struct ftrace_event_call event_##name + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 2 of the trace events. + * + * Override the macros in <trace/trace_events.h> to include the following: + * + * enum print_line_t + * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags) + * { + * struct trace_seq *s = &iter->seq; + * struct ftrace_raw_<call> *field; <-- defined in stage 1 + * struct trace_entry *entry; + * int ret; + * + * entry = iter->ent; + * + * if (entry->type != event_<call>.id) { + * WARN_ON_ONCE(1); + * return TRACE_TYPE_UNHANDLED; + * } + * + * field = (typeof(field))entry; + * + * ret = trace_seq_printf(s, <TP_printk> "\n"); + * if (!ret) + * return TRACE_TYPE_PARTIAL_LINE; + * + * return TRACE_TYPE_HANDLED; + * } + * + * This is the method used to print the raw event to the trace + * output format. Note, this is not needed if the data is read + * in binary. + */ + +#undef __entry +#define __entry field + +#undef TP_printk +#define TP_printk(fmt, args...) fmt "\n", args + +#undef TRACE_EVENT +#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ +enum print_line_t \ +ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ +{ \ + struct trace_seq *s = &iter->seq; \ + struct ftrace_raw_##call *field; \ + struct trace_entry *entry; \ + int ret; \ + \ + entry = iter->ent; \ + \ + if (entry->type != event_##call.id) { \ + WARN_ON_ONCE(1); \ + return TRACE_TYPE_UNHANDLED; \ + } \ + \ + field = (typeof(field))entry; \ + \ + ret = trace_seq_printf(s, #call ": " print); \ + if (!ret) \ + return TRACE_TYPE_PARTIAL_LINE; \ + \ + return TRACE_TYPE_HANDLED; \ +} + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Setup the showing format of trace point. + * + * int + * ftrace_format_##call(struct trace_seq *s) + * { + * struct ftrace_raw_##call field; + * int ret; + * + * ret = trace_seq_printf(s, #type " " #item ";" + * " offset:%u; size:%u;\n", + * offsetof(struct ftrace_raw_##call, item), + * sizeof(field.type)); + * + * } + */ + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) args + +#undef __field +#define __field(type, item) \ + ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ + "offset:%u;\tsize:%u;\n", \ + (unsigned int)offsetof(typeof(field), item), \ + (unsigned int)sizeof(field.item)); \ + if (!ret) \ + return 0; + +#undef __array +#define __array(type, item, len) \ + ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \ + "offset:%u;\tsize:%u;\n", \ + (unsigned int)offsetof(typeof(field), item), \ + (unsigned int)sizeof(field.item)); \ + if (!ret) \ + return 0; + +#undef __entry +#define __entry REC + +#undef TP_printk +#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args) + +#undef TP_fast_assign +#define TP_fast_assign(args...) args + +#undef TRACE_EVENT +#define TRACE_EVENT(call, proto, args, tstruct, func, print) \ +static int \ +ftrace_format_##call(struct trace_seq *s) \ +{ \ + struct ftrace_raw_##call field; \ + int ret; \ + \ + tstruct; \ + \ + trace_seq_printf(s, "\nprint fmt: " print); \ + \ + return ret; \ +} + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +#undef __field +#define __field(type, item) \ + ret = trace_define_field(event_call, #type, #item, \ + offsetof(typeof(field), item), \ + sizeof(field.item)); \ + if (ret) \ + return ret; + +#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)); \ + if (ret) \ + return ret; + +#undef TRACE_EVENT +#define TRACE_EVENT(call, proto, args, tstruct, func, print) \ +int \ +ftrace_define_fields_##call(void) \ +{ \ + struct ftrace_raw_##call field; \ + struct ftrace_event_call *event_call = &event_##call; \ + int ret; \ + \ + __common_field(unsigned char, type); \ + __common_field(unsigned char, flags); \ + __common_field(unsigned char, preempt_count); \ + __common_field(int, pid); \ + __common_field(int, tgid); \ + \ + tstruct; \ + \ + return ret; \ +} + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 3 of the trace events. + * + * Override the macros in <trace/trace_events.h> to include the following: + * + * static void ftrace_event_<call>(proto) + * { + * event_trace_printk(_RET_IP_, "<call>: " <fmt>); + * } + * + * static int ftrace_reg_event_<call>(void) + * { + * int ret; + * + * ret = register_trace_<call>(ftrace_event_<call>); + * if (!ret) + * pr_info("event trace: Could not activate trace point " + * "probe to <call>"); + * return ret; + * } + * + * static void ftrace_unreg_event_<call>(void) + * { + * unregister_trace_<call>(ftrace_event_<call>); + * } + * + * For those macros defined with TRACE_FORMAT: + * + * static struct ftrace_event_call __used + * __attribute__((__aligned__(4))) + * __attribute__((section("_ftrace_events"))) event_<call> = { + * .name = "<call>", + * .regfunc = ftrace_reg_event_<call>, + * .unregfunc = ftrace_unreg_event_<call>, + * } + * + * + * For those macros defined with TRACE_EVENT: + * + * static struct ftrace_event_call event_<call>; + * + * static void ftrace_raw_event_<call>(proto) + * { + * struct ring_buffer_event *event; + * struct ftrace_raw_<call> *entry; <-- defined in stage 1 + * unsigned long irq_flags; + * int pc; + * + * local_save_flags(irq_flags); + * pc = preempt_count(); + * + * event = trace_current_buffer_lock_reserve(event_<call>.id, + * sizeof(struct ftrace_raw_<call>), + * irq_flags, pc); + * if (!event) + * return; + * entry = ring_buffer_event_data(event); + * + * <assign>; <-- Here we assign the entries by the __field and + * __array macros. + * + * trace_current_buffer_unlock_commit(event, irq_flags, pc); + * } + * + * static int ftrace_raw_reg_event_<call>(void) + * { + * int ret; + * + * ret = register_trace_<call>(ftrace_raw_event_<call>); + * if (!ret) + * pr_info("event trace: Could not activate trace point " + * "probe to <call>"); + * return ret; + * } + * + * static void ftrace_unreg_event_<call>(void) + * { + * unregister_trace_<call>(ftrace_raw_event_<call>); + * } + * + * static struct trace_event ftrace_event_type_<call> = { + * .trace = ftrace_raw_output_<call>, <-- stage 2 + * }; + * + * static int ftrace_raw_init_event_<call>(void) + * { + * int id; + * + * id = register_ftrace_event(&ftrace_event_type_<call>); + * if (!id) + * return -ENODEV; + * event_<call>.id = id; + * return 0; + * } + * + * static struct ftrace_event_call __used + * __attribute__((__aligned__(4))) + * __attribute__((section("_ftrace_events"))) event_<call> = { + * .name = "<call>", + * .system = "<system>", + * .raw_init = ftrace_raw_init_event_<call>, + * .regfunc = ftrace_reg_event_<call>, + * .unregfunc = ftrace_unreg_event_<call>, + * .show_format = ftrace_format_<call>, + * } + * + */ + +#undef TP_FMT +#define TP_FMT(fmt, args...) fmt "\n", ##args + +#ifdef CONFIG_EVENT_PROFILE +#define _TRACE_PROFILE(call, proto, args) \ +static void ftrace_profile_##call(proto) \ +{ \ + extern void perf_tpcounter_event(int); \ + perf_tpcounter_event(event_##call.id); \ +} \ + \ +static int ftrace_profile_enable_##call(struct ftrace_event_call *call) \ +{ \ + int ret = 0; \ + \ + if (!atomic_inc_return(&call->profile_count)) \ + ret = register_trace_##call(ftrace_profile_##call); \ + \ + return ret; \ +} \ + \ +static void ftrace_profile_disable_##call(struct ftrace_event_call *call) \ +{ \ + if (atomic_add_negative(-1, &call->profile_count)) \ + unregister_trace_##call(ftrace_profile_##call); \ +} + +#define _TRACE_PROFILE_INIT(call) \ + .profile_count = ATOMIC_INIT(-1), \ + .profile_enable = ftrace_profile_enable_##call, \ + .profile_disable = ftrace_profile_disable_##call, + +#else +#define _TRACE_PROFILE(call, proto, args) +#define _TRACE_PROFILE_INIT(call) +#endif + +#define _TRACE_FORMAT(call, proto, args, fmt) \ +static void ftrace_event_##call(proto) \ +{ \ + event_trace_printk(_RET_IP_, #call ": " fmt); \ +} \ + \ +static int ftrace_reg_event_##call(void) \ +{ \ + int ret; \ + \ + ret = register_trace_##call(ftrace_event_##call); \ + if (ret) \ + pr_info("event trace: Could not activate trace point " \ + "probe to " #call "\n"); \ + return ret; \ +} \ + \ +static void ftrace_unreg_event_##call(void) \ +{ \ + unregister_trace_##call(ftrace_event_##call); \ +} \ + \ +static struct ftrace_event_call event_##call; \ + \ +static int ftrace_init_event_##call(void) \ +{ \ + int id; \ + \ + id = register_ftrace_event(NULL); \ + if (!id) \ + return -ENODEV; \ + event_##call.id = id; \ + return 0; \ +} + +#undef TRACE_FORMAT +#define TRACE_FORMAT(call, proto, args, fmt) \ +_TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) \ +_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \ +static struct ftrace_event_call __used \ +__attribute__((__aligned__(4))) \ +__attribute__((section("_ftrace_events"))) event_##call = { \ + .name = #call, \ + .system = __stringify(TRACE_SYSTEM), \ + .raw_init = ftrace_init_event_##call, \ + .regfunc = ftrace_reg_event_##call, \ + .unregfunc = ftrace_unreg_event_##call, \ + _TRACE_PROFILE_INIT(call) \ +} + +#undef __entry +#define __entry entry + +#undef TRACE_EVENT +#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ +_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \ + \ +static struct ftrace_event_call event_##call; \ + \ +static void ftrace_raw_event_##call(proto) \ +{ \ + struct ftrace_event_call *call = &event_##call; \ + struct ring_buffer_event *event; \ + struct ftrace_raw_##call *entry; \ + unsigned long irq_flags; \ + int pc; \ + \ + local_save_flags(irq_flags); \ + pc = preempt_count(); \ + \ + event = trace_current_buffer_lock_reserve(event_##call.id, \ + sizeof(struct ftrace_raw_##call), \ + irq_flags, pc); \ + if (!event) \ + return; \ + entry = ring_buffer_event_data(event); \ + \ + assign; \ + \ + if (!filter_current_check_discard(call, entry, event)) \ + trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \ +} \ + \ +static int ftrace_raw_reg_event_##call(void) \ +{ \ + int ret; \ + \ + ret = register_trace_##call(ftrace_raw_event_##call); \ + if (ret) \ + pr_info("event trace: Could not activate trace point " \ + "probe to " #call "\n"); \ + return ret; \ +} \ + \ +static void ftrace_raw_unreg_event_##call(void) \ +{ \ + unregister_trace_##call(ftrace_raw_event_##call); \ +} \ + \ +static struct trace_event ftrace_event_type_##call = { \ + .trace = ftrace_raw_output_##call, \ +}; \ + \ +static int ftrace_raw_init_event_##call(void) \ +{ \ + int id; \ + \ + id = register_ftrace_event(&ftrace_event_type_##call); \ + if (!id) \ + return -ENODEV; \ + event_##call.id = id; \ + INIT_LIST_HEAD(&event_##call.fields); \ + init_preds(&event_##call); \ + return 0; \ +} \ + \ +static struct ftrace_event_call __used \ +__attribute__((__aligned__(4))) \ +__attribute__((section("_ftrace_events"))) event_##call = { \ + .name = #call, \ + .system = __stringify(TRACE_SYSTEM), \ + .raw_init = ftrace_raw_init_event_##call, \ + .regfunc = ftrace_raw_reg_event_##call, \ + .unregfunc = ftrace_raw_unreg_event_##call, \ + .show_format = ftrace_format_##call, \ + .define_fields = ftrace_define_fields_##call, \ + _TRACE_PROFILE_INIT(call) \ +} + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +#undef _TRACE_PROFILE +#undef _TRACE_PROFILE_INIT + diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h deleted file mode 100644 index 13d6b85..0000000 --- a/include/trace/trace_events.h +++ /dev/null @@ -1,7 +0,0 @@ -/* trace/<type>.h here */ - -#include <trace/sched.h> -#include <trace/irq.h> -#include <trace/lockdep.h> -#include <trace/skb.h> -#include <trace/kmem.h> diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 3ad367e..fb9d7f9 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -41,7 +41,6 @@ obj-$(CONFIG_KMEMTRACE) += kmemtrace.o obj-$(CONFIG_WORKQUEUE_TRACER) += trace_workqueue.o obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o obj-$(CONFIG_EVENT_TRACING) += trace_events.o -obj-$(CONFIG_EVENT_TRACER) += events.o obj-$(CONFIG_EVENT_TRACING) += trace_export.o obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o diff --git a/kernel/trace/events.c b/kernel/trace/events.c deleted file mode 100644 index 5a35a91..0000000 --- a/kernel/trace/events.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This is the place to register all trace points as events. - */ - -#include <linux/stringify.h> - -#include <trace/trace_events.h> - -#include "trace_output.h" - -#define TRACE_HEADER_MULTI_READ -#include "trace_events_stage_1.h" -#include "trace_events_stage_2.h" -#include "trace_events_stage_3.h" - diff --git a/kernel/trace/trace_events_stage_1.h b/kernel/trace/trace_events_stage_1.h deleted file mode 100644 index 475f46a..0000000 --- a/kernel/trace/trace_events_stage_1.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Stage 1 of the trace events. - * - * Override the macros in <trace/trace_events.h> to include the following: - * - * struct ftrace_raw_<call> { - * struct trace_entry ent; - * <type> <item>; - * <type2> <item2>[<len>]; - * [...] - * }; - * - * The <type> <item> is created by the __field(type, item) macro or - * the __array(type2, item2, len) macro. - * We simply do "type item;", and that will create the fields - * in the structure. - */ - -#undef TRACE_FORMAT -#define TRACE_FORMAT(call, proto, args, fmt) - -#undef __array -#define __array(type, item, len) type item[len]; - -#undef __field -#define __field(type, item) type item; - -#undef TP_STRUCT__entry -#define TP_STRUCT__entry(args...) args - -#undef TRACE_EVENT -#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ - struct ftrace_raw_##name { \ - struct trace_entry ent; \ - tstruct \ - }; \ - static struct ftrace_event_call event_##name - -#include <trace/trace_events.h> diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h deleted file mode 100644 index aa4a67a..0000000 --- a/kernel/trace/trace_events_stage_2.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Stage 2 of the trace events. - * - * Override the macros in <trace/trace_events.h> to include the following: - * - * enum print_line_t - * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags) - * { - * struct trace_seq *s = &iter->seq; - * struct ftrace_raw_<call> *field; <-- defined in stage 1 - * struct trace_entry *entry; - * int ret; - * - * entry = iter->ent; - * - * if (entry->type != event_<call>.id) { - * WARN_ON_ONCE(1); - * return TRACE_TYPE_UNHANDLED; - * } - * - * field = (typeof(field))entry; - * - * ret = trace_seq_printf(s, <TP_printk> "\n"); - * if (!ret) - * return TRACE_TYPE_PARTIAL_LINE; - * - * return TRACE_TYPE_HANDLED; - * } - * - * This is the method used to print the raw event to the trace - * output format. Note, this is not needed if the data is read - * in binary. - */ - -#undef __entry -#define __entry field - -#undef TP_printk -#define TP_printk(fmt, args...) fmt "\n", args - -#undef TRACE_EVENT -#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ -enum print_line_t \ -ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ -{ \ - struct trace_seq *s = &iter->seq; \ - struct ftrace_raw_##call *field; \ - struct trace_entry *entry; \ - int ret; \ - \ - entry = iter->ent; \ - \ - if (entry->type != event_##call.id) { \ - WARN_ON_ONCE(1); \ - return TRACE_TYPE_UNHANDLED; \ - } \ - \ - field = (typeof(field))entry; \ - \ - ret = trace_seq_printf(s, #call ": " print); \ - if (!ret) \ - return TRACE_TYPE_PARTIAL_LINE; \ - \ - return TRACE_TYPE_HANDLED; \ -} - -#include <trace/trace_events.h> - -/* - * Setup the showing format of trace point. - * - * int - * ftrace_format_##call(struct trace_seq *s) - * { - * struct ftrace_raw_##call field; - * int ret; - * - * ret = trace_seq_printf(s, #type " " #item ";" - * " offset:%u; size:%u;\n", - * offsetof(struct ftrace_raw_##call, item), - * sizeof(field.type)); - * - * } - */ - -#undef TP_STRUCT__entry -#define TP_STRUCT__entry(args...) args - -#undef __field -#define __field(type, item) \ - ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ - "offset:%u;\tsize:%u;\n", \ - (unsigned int)offsetof(typeof(field), item), \ - (unsigned int)sizeof(field.item)); \ - if (!ret) \ - return 0; - -#undef __array -#define __array(type, item, len) \ - ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \ - "offset:%u;\tsize:%u;\n", \ - (unsigned int)offsetof(typeof(field), item), \ - (unsigned int)sizeof(field.item)); \ - if (!ret) \ - return 0; - -#undef __entry -#define __entry REC - -#undef TP_printk -#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args) - -#undef TP_fast_assign -#define TP_fast_assign(args...) args - -#undef TRACE_EVENT -#define TRACE_EVENT(call, proto, args, tstruct, func, print) \ -static int \ -ftrace_format_##call(struct trace_seq *s) \ -{ \ - struct ftrace_raw_##call field; \ - int ret; \ - \ - tstruct; \ - \ - trace_seq_printf(s, "\nprint fmt: " print); \ - \ - return ret; \ -} - -#include <trace/trace_events.h> - -#undef __field -#define __field(type, item) \ - ret = trace_define_field(event_call, #type, #item, \ - offsetof(typeof(field), item), \ - sizeof(field.item)); \ - if (ret) \ - return ret; - -#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)); \ - if (ret) \ - return ret; - -#undef TRACE_EVENT -#define TRACE_EVENT(call, proto, args, tstruct, func, print) \ -int \ -ftrace_define_fields_##call(void) \ -{ \ - struct ftrace_raw_##call field; \ - struct ftrace_event_call *event_call = &event_##call; \ - int ret; \ - \ - __common_field(unsigned char, type); \ - __common_field(unsigned char, flags); \ - __common_field(unsigned char, preempt_count); \ - __common_field(int, pid); \ - __common_field(int, tgid); \ - \ - tstruct; \ - \ - return ret; \ -} - -#include <trace/trace_events.h> diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h deleted file mode 100644 index 45c04e1..0000000 --- a/kernel/trace/trace_events_stage_3.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Stage 3 of the trace events. - * - * Override the macros in <trace/trace_events.h> to include the following: - * - * static void ftrace_event_<call>(proto) - * { - * event_trace_printk(_RET_IP_, "<call>: " <fmt>); - * } - * - * static int ftrace_reg_event_<call>(void) - * { - * int ret; - * - * ret = register_trace_<call>(ftrace_event_<call>); - * if (!ret) - * pr_info("event trace: Could not activate trace point " - * "probe to <call>"); - * return ret; - * } - * - * static void ftrace_unreg_event_<call>(void) - * { - * unregister_trace_<call>(ftrace_event_<call>); - * } - * - * For those macros defined with TRACE_FORMAT: - * - * static struct ftrace_event_call __used - * __attribute__((__aligned__(4))) - * __attribute__((section("_ftrace_events"))) event_<call> = { - * .name = "<call>", - * .regfunc = ftrace_reg_event_<call>, - * .unregfunc = ftrace_unreg_event_<call>, - * } - * - * - * For those macros defined with TRACE_EVENT: - * - * static struct ftrace_event_call event_<call>; - * - * static void ftrace_raw_event_<call>(proto) - * { - * struct ring_buffer_event *event; - * struct ftrace_raw_<call> *entry; <-- defined in stage 1 - * unsigned long irq_flags; - * int pc; - * - * local_save_flags(irq_flags); - * pc = preempt_count(); - * - * event = trace_current_buffer_lock_reserve(event_<call>.id, - * sizeof(struct ftrace_raw_<call>), - * irq_flags, pc); - * if (!event) - * return; - * entry = ring_buffer_event_data(event); - * - * <assign>; <-- Here we assign the entries by the __field and - * __array macros. - * - * trace_current_buffer_unlock_commit(event, irq_flags, pc); - * } - * - * static int ftrace_raw_reg_event_<call>(void) - * { - * int ret; - * - * ret = register_trace_<call>(ftrace_raw_event_<call>); - * if (!ret) - * pr_info("event trace: Could not activate trace point " - * "probe to <call>"); - * return ret; - * } - * - * static void ftrace_unreg_event_<call>(void) - * { - * unregister_trace_<call>(ftrace_raw_event_<call>); - * } - * - * static struct trace_event ftrace_event_type_<call> = { - * .trace = ftrace_raw_output_<call>, <-- stage 2 - * }; - * - * static int ftrace_raw_init_event_<call>(void) - * { - * int id; - * - * id = register_ftrace_event(&ftrace_event_type_<call>); - * if (!id) - * return -ENODEV; - * event_<call>.id = id; - * return 0