public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9 - v2][RFC] tracing: Lowering the footprint of TRACE_EVENTs
@ 2010-05-04  3:40 Steven Rostedt
  2010-05-04  3:40 ` [PATCH 1/9 - v2][RFC] tracing: Create class struct for events Steven Rostedt
                   ` (8 more replies)
  0 siblings, 9 replies; 36+ messages in thread
From: Steven Rostedt @ 2010-05-04  3:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Frederic Weisbecker, Arnaldo Carvalho de Melo, Mathieu Desnoyers,
	Lai Jiangshan, Li Zefan, Masami Hiramatsu, Christoph Hellwig

[Version 2]

This is an RFC patch set that also affects kprobes and perf.

At the Linux Collaboration Summit, I talked with Mathieu and others about
lowering the footprint of trace events. I spent all of last week
trying to get the size as small as I could.

Currently, each TRACE_EVENT() macro adds 1 - 5K per tracepoint. I got various
results by adding a TRACE_EVENT() with the compiler, depending on
config options that did not seem related. The new tracepoint I added
would add between 1 and 5K, but I did not investigate enough to
see what the true size was.

What was consistent, was the DEFINE_EVENT(). Currently, it adds
a little over 700 bytes per DEFINE_EVENT().

This patch series does not seem to affect TRACE_EVENT() much (had
the same various sizes), but consistently brings DEFINE_EVENT()s
down from 700 bytes to 250 bytes per DEFINE_EVENT(). Since syscalls
use one "class" and are equivalent to DEFINE_EVENT() this can
be a significant savings.

With events and syscalls (82 events and 616 syscalls), before this
patch series, the size of vmlinux was: 16161794, and afterward: 16058182.

That is 103,612 bytes in savings! (over 100K)


Without tracing syscalls (82 events), it brought the size of vmlinux
down from 1591046 to 15999394.

22,071 bytes in savings.

This is just an RFC (for now), to get peoples opinions on the changes.
It does a bit of rewriting of the CPP macros, just to warning you ;-)

Changes in v2:

 o  Ported to latest tip/tracing/core

 o  Removed DECLARE_TRACE_DATA() and made DECLARE_TRACE() have
    the ability to pass a data parameter. This makes DECLARE_TRACE()
    not work with no args. A new DECLARE_TRACE_NOARGS() has been created
    that also allows data to be passed, but does is for tracepoint(void).

 o  Made the callbacks be "proto, void *data" and typecast the data
    within the function.


-- Steve

The code can be found at:

  git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/tracing/rfc-1


Steven Rostedt (9):
      tracing: Create class struct for events
      tracing: Let tracepoints have data passed to tracepoint callbacks
      tracing: Remove per event trace registering
      tracing: Move fields from event to class structure
      tracing: Move raw_init from events to class
      tracing: Allow events to share their print functions
      tracing: Move print functions into event class
      tracing: Remove duplicate id information in event structure
      tracing: Combine event filter_active and enable into single flags field

----
 include/linux/ftrace_event.h           |   73 ++++++++---
 include/linux/syscalls.h               |   57 +++------
 include/linux/tracepoint.h             |   94 +++++++++++---
 include/trace/ftrace.h                 |  218 ++++++++++----------------------
 include/trace/syscall.h                |   10 +-
 kernel/trace/blktrace.c                |   13 ++-
 kernel/trace/kmemtrace.c               |   28 +++--
 kernel/trace/trace.c                   |    9 +-
 kernel/trace/trace.h                   |    5 +-
 kernel/trace/trace_event_perf.c        |   17 ++-
 kernel/trace/trace_events.c            |  131 ++++++++++++-------
 kernel/trace/trace_events_filter.c     |   28 +++--
 kernel/trace/trace_export.c            |   16 ++-
 kernel/trace/trace_functions_graph.c   |   13 ++-
 kernel/trace/trace_kprobe.c            |  104 +++++++++------
 kernel/trace/trace_output.c            |  137 ++++++++++++++-------
 kernel/trace/trace_output.h            |    2 +-
 kernel/trace/trace_syscalls.c          |  113 +++++++++++++++--
 kernel/tracepoint.c                    |   91 ++++++++------
 samples/tracepoints/tp-samples-trace.h |    4 +-
 20 files changed, 697 insertions(+), 466 deletions(-)

^ permalink raw reply	[flat|nested] 36+ messages in thread
* Re: [PATCH 2/9 - v2][RFC] tracing: Let tracepoints have data passed to tracepoint callbacks
@ 2010-05-07 12:40 Steven Rostedt
  2010-05-07 14:39 ` [PATCH 2/9 - v2][RFC] tracing: Let tracepoints have data?passed " Mathieu Desnoyers
  0 siblings, 1 reply; 36+ messages in thread
From: Steven Rostedt @ 2010-05-07 12:40 UTC (permalink / raw)
  To: Frederic Weisbecker
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Thomas Gleixner,
	Peter Zijlstra, Arnaldo Carvalho de Melo, Mathieu Desnoyers,
	Lai Jiangshan, Li Zefan, Masami Hiramatsu, Christoph Hellwig,
	Mathieu Desnoyers

[-- Attachment #1: Type: text/plain, Size: 9336 bytes --]



"Frederic Weisbecker" <fweisbec@gmail.com> wrote:

>On Mon, May 03, 2010 at 11:40:47PM -0400, Steven Rostedt wrote:
>> From: Steven Rostedt <srostedt@redhat.com>
>> 
>> This patch allows data to be passed to the tracepoint callbacks
>> if the tracepoint was created to do so.
>> 
>> The DECLARE_TRACE() now adds two new functions:
>> 
>> 	register_trace_mytracepoint_data()
>> 	unregister_trace_mytracepoint_data()
>> 
>> These two are the same as the original
>> 
>> 	register_trace_mytracepoint()
>> 	unregister_trace_mytracepoint()
>> 
>> But now allow you to pass a private data pointer that will
>> be passed to the callback handle. For example:
>> 
>> DECLARE_TRACE(mytracepoint, int value, value);
>> 
>> will create a function called trace_mytracepoint()
>> 
>> 	void trace_mytracepoint(int value);
>> 
>> If the user wants to pass data to register a function to this tracepoint
>> and have data also passed to this callback, they can use:
>> 
>> 	int mycallback(int value, void *data);
>> 
>> 	register_trace_mytracepoint_data(mycallback, mydata);
>> 
>> Then the mycallback() will receive the "mydata" as the parameter after
>> the args.
>> 
>> A more detailed example:
>> 
>>   DECLARE_TRACE(mytracepoint, TP_PROTO(int status), TP_ARGS(status));
>> 
>>   /* In the C file */
>> 
>>   DEFINE_TRACE(mytracepoint, TP_PROTO(int status), TP_ARGS(status));
>> 
>>   [...]
>> 
>>        trace_mytacepoint(status);
>> 
>>   /* In a file registering this tracepoint */
>> 
>>   int my_callback(int status, void *data)
>>   {
>> 	struct my_struct my_data = data;
>> 	[...]
>>   }
>> 
>>   [...]
>> 	my_data = kmalloc(sizeof(*my_data), GFP_KERNEL);
>> 	init_my_data(my_data);
>> 	register_trace_mytracepoint_data(my_callback, my_data);
>> 
>> The same callback can also be registered to the same tracepoint as long
>> as the data registered is the different. Note, the data must also be used
>> to unregister the callback:
>> 
>> 	unregister_trace_mytracepoint_data(my_callback, my_data);
>> 
>> Because of the data parameter, tracepoints declared this way can not have
>> no args. That is:
>> 
>>   DECLARE_TRACE(mytracepoint, TP_PROTO(void), TP_ARGS());
>> 
>> will cause an error.
>> 
>> If no arguments are needed, a new macro can be used instead:
>> 
>>   DECLARE_TRACE_NOARGS(mytracepoint);
>> 
>> Since there are no arguments, the proto and args fields are left out.
>> 
>> This is part of a series to make the tracepoint footprint smaller:
>> 
>>    text	   data	    bss	    dec	    hex	filename
>> 5788186	1337252	9351592	16477030	 fb6b66	vmlinux.orig
>> 5792282	1333796	9351592	16477670	 fb6de6	vmlinux.class
>> 5793448	1333780	9351592	16478820	 fb7264	vmlinux.tracepoint
>> 
>> Again, this patch also increases the size of the kernel, but
>> lays the ground work for decreasing it.
>> 
>>  v2: Made the DECLARE_TRACE() have the ability to pass arguments
>>      and added a new DECLARE_TRACE_NOARGS() for tracepoints that
>>      do not need any arguments.
>> 
>> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
>> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
>> ---
>>  include/linux/tracepoint.h             |   94 +++++++++++++++++++++++++-------
>>  kernel/tracepoint.c                    |   91 +++++++++++++++++--------------
>>  samples/tracepoints/tp-samples-trace.h |    4 +-
>>  3 files changed, 126 insertions(+), 63 deletions(-)
>> 
>> diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
>> index 78b4bd3..ee8059a 100644
>> --- a/include/linux/tracepoint.h
>> +++ b/include/linux/tracepoint.h
>> @@ -20,12 +20,17 @@
>>  struct module;
>>  struct tracepoint;
>>  
>> +struct tracepoint_func {
>> +	void *func;
>> +	void *data;
>> +};
>> +
>>  struct tracepoint {
>>  	const char *name;		/* Tracepoint name */
>>  	int state;			/* State. */
>>  	void (*regfunc)(void);
>>  	void (*unregfunc)(void);
>> -	void **funcs;
>> +	struct tracepoint_func *funcs;
>>  } __attribute__((aligned(32)));		/*
>>  					 * Aligned on 32 bytes because it is
>>  					 * globally visible and gcc happily
>> @@ -46,14 +51,18 @@ struct tracepoint {
>>   */
>>  #define __DO_TRACE(tp, proto, args)					\
>>  	do {								\
>> -		void **it_func;						\
>> +		struct tracepoint_func *it_func_ptr;			\
>> +		void *it_func;						\
>> +		void *__data;						\
>>  									\
>>  		rcu_read_lock_sched_notrace();				\
>> -		it_func = rcu_dereference_sched((tp)->funcs);		\
>> -		if (it_func) {						\
>> +		it_func_ptr = rcu_dereference_sched((tp)->funcs);	\
>> +		if (it_func_ptr) {					\
>>  			do {						\
>> -				((void(*)(proto))(*it_func))(args);	\
>> -			} while (*(++it_func));				\
>> +				it_func = (it_func_ptr)->func;		\
>> +				__data = (it_func_ptr)->data;		\
>> +				((void(*)(proto))(it_func))(args);	\
>
>
>So, we had a talk about this and we concluded that it is probably fine
>on every archs to push one more argument than needed in a function.
>

Yeah, I'm hoping it's fine.

>But I think it would be nice to add a comment about this. Firstly
>because this line breaks all the self-explanation of the code, I mean
>I tried hard to find how the non-data callback case was handled :)
>Secondly to also to avoid people asking what happens here.
>

OK I'll add a bit of comments to the macros. So much for my job security ;-)

>
>
>
>> +			} while ((++it_func_ptr)->func);		\
>>  		}							\
>>  		rcu_read_unlock_sched_notrace();			\
>>  	} while (0)
>> @@ -63,23 +72,47 @@ struct tracepoint {
>>   * not add unwanted padding between the beginning of the section and the
>>   * structure. Force alignment to the same alignment as the section start.
>>   */
>> -#define DECLARE_TRACE(name, proto, args)				\
>> +#define __DECLARE_TRACE(name, proto, args, data_proto, data_args)	\
>>  	extern struct tracepoint __tracepoint_##name;			\
>>  	static inline void trace_##name(proto)				\
>>  	{								\
>>  		if (unlikely(__tracepoint_##name.state))		\
>>  			__DO_TRACE(&__tracepoint_##name,		\
>> -				TP_PROTO(proto), TP_ARGS(args));	\
>> +				TP_PROTO(data_proto),			\
>> +				TP_ARGS(data_args));			\
>>  	}								\
>>  	static inline int register_trace_##name(void (*probe)(proto))	\
>>  	{								\
>> -		return tracepoint_probe_register(#name, (void *)probe);	\
>> +		return tracepoint_probe_register(#name, (void *)probe,	\
>> +						 NULL);			\
>> +	}								\
>> +	static inline int unregister_trace_##name(void (*probe)(proto)) \
>> +	{								\
>> +		return tracepoint_probe_unregister(#name, (void *)probe,\
>> +						   NULL);		\
>>  	}								\
>> -	static inline int unregister_trace_##name(void (*probe)(proto))	\
>> +	static inline int						\
>> +	register_trace_##name##_data(void (*probe)(data_proto),		\
>> +				     void *data)			\
>>  	{								\
>> -		return tracepoint_probe_unregister(#name, (void *)probe);\
>> +		return tracepoint_probe_register(#name, (void *)probe,	\
>> +						 data);			\
>> +	}								\
>> +	static inline int						\
>> +	unregister_trace_##name##_data(void (*probe)(data_proto),	\
>> +				       void *data)			\
>> +	{								\
>> +		return tracepoint_probe_unregister(#name, (void *)probe,\
>> +						   data);		\
>>  	}
>>  
>> +#define DECLARE_TRACE_NOARGS(name)					\
>> +		__DECLARE_TRACE(name, void, , void *__data, __data)
>
>
>
>That too, may be, deserves a small comment :)

OK

>
>
>
>> +
>> +#define DECLARE_TRACE(name, proto, args)				\
>> +		__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),	\
>> +				PARAMS(proto, void *__data),		\
>> +				PARAMS(args, __data))
>>  
>>  #define DEFINE_TRACE_FN(name, reg, unreg)				\
>>  	static const char __tpstrtab_##name[]				\
>> @@ -100,19 +133,37 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
>>  	struct tracepoint *end);
>>  
>>  #else /* !CONFIG_TRACEPOINTS */
>> -#define DECLARE_TRACE(name, proto, args)				\
>> -	static inline void _do_trace_##name(struct tracepoint *tp, proto) \
>> -	{ }								\
>> +#define __DECLARE_TRACE(name, proto, args, data_proto, data_args)	\
>>  	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))	\
>> +	static inline int unregister_trace_##name(void (*probe)(proto)) \
>> +	{								\
>> +		return -ENOSYS;						\
>> +	}								\
>> +	static inline int						\
>> +	register_trace_##name##_data(void (*probe)(data_proto),		\
>> +				     void *data)			\
>> +	{								\
>> +		return -ENOSYS;						\
>> +	}								\
>> +	static inline int						\
>> +	unregister_trace_##name##_data(void (*probe)(data_proto),	\
>> +				       void *data)			\
>>  	{								\
>>  		return -ENOSYS;						\
>>  	}
>> +#define DECLARE_TRACE_NOARGS(name)					\
>> +		__DECLARE_TRACE(name, void, , void *__data, __data)
>> +
>> +#define DECLARE_TRACE(name, proto, args)				\
>> +		__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),	\
>> +				PARAMS(proto, void *__data),		\
>> +				PARAMS(args, __data))
>
>
>
>
>It seems that the on and off cases are exactly the same for DECLARE_TRACE*(),
>you could provide a single version and let the __DECLARE_TRACE() do
>the on/off trick.
>

I don't know what you mean here?

-- Steve 

>Thanks.
>

-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2010-05-07 20:59 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-04  3:40 [PATCH 0/9 - v2][RFC] tracing: Lowering the footprint of TRACE_EVENTs Steven Rostedt
2010-05-04  3:40 ` [PATCH 1/9 - v2][RFC] tracing: Create class struct for events Steven Rostedt
2010-05-07  4:21   ` Frederic Weisbecker
2010-05-04  3:40 ` [PATCH 2/9 - v2][RFC] tracing: Let tracepoints have data passed to tracepoint callbacks Steven Rostedt
2010-05-07  3:52   ` Frederic Weisbecker
2010-05-07 14:09     ` Steven Rostedt
2010-05-07 18:06       ` Frederic Weisbecker
2010-05-07 19:10         ` Steven Rostedt
2010-05-04  3:40 ` [PATCH 3/9 - v2][RFC] tracing: Remove per event trace registering Steven Rostedt
2010-05-07  4:20   ` Frederic Weisbecker
2010-05-07 12:42     ` Steven Rostedt
2010-05-07 14:54     ` Mathieu Desnoyers
2010-05-07 15:12       ` Steven Rostedt
2010-05-07 15:31         ` Mathieu Desnoyers
2010-05-07 15:43           ` Steven Rostedt
2010-05-07 18:01       ` Frederic Weisbecker
2010-05-07 19:08         ` Steven Rostedt
2010-05-07 20:03           ` Frederic Weisbecker
2010-05-07 20:58           ` Mathieu Desnoyers
2010-05-07  8:20   ` Li Zefan
2010-05-07 12:59     ` Steven Rostedt
2010-05-04  3:40 ` [PATCH 4/9 - v2][RFC] tracing: Move fields from event to class structure Steven Rostedt
2010-05-07  4:49   ` Frederic Weisbecker
2010-05-07 12:57     ` Steven Rostedt
2010-05-04  3:40 ` [PATCH 5/9 - v2][RFC] tracing: Move raw_init from events to class Steven Rostedt
2010-05-04  3:40 ` [PATCH 6/9 - v2][RFC] tracing: Allow events to share their print functions Steven Rostedt
2010-05-04  3:40 ` [PATCH 7/9 - v2][RFC] tracing: Move print functions into event class Steven Rostedt
2010-05-04  3:40 ` [PATCH 8/9 - v2][RFC] tracing: Remove duplicate id information in event structure Steven Rostedt
2010-05-04  3:40 ` [PATCH 9/9 - v2][RFC] tracing: Combine event filter_active and enable into single flags field Steven Rostedt
  -- strict thread matches above, loose matches on Subject: below --
2010-05-07 12:40 [PATCH 2/9 - v2][RFC] tracing: Let tracepoints have data passed to tracepoint callbacks Steven Rostedt
2010-05-07 14:39 ` [PATCH 2/9 - v2][RFC] tracing: Let tracepoints have data?passed " Mathieu Desnoyers
2010-05-07 14:55   ` Steven Rostedt
2010-05-07 15:08     ` Mathieu Desnoyers
2010-05-07 15:15       ` Steven Rostedt
2010-05-07 15:30         ` Mathieu Desnoyers
2010-05-07 15:45           ` Steven Rostedt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox