lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20090330103808.GB6058@nowhere>
Date:	Mon, 30 Mar 2009 12:38:09 +0200
From:	Frederic Weisbecker <fweisbec@...il.com>
To:	Tom Zanussi <tzanussi@...il.com>
Cc:	linux-kernel <linux-kernel@...r.kernel.org>,
	Ingo Molnar <mingo@...e.hu>,
	Steven Rostedt <rostedt@...dmis.org>
Subject: Re: [PATCH] tracing/filters: add run-time field descriptions to
	TRACE_EVENT_FORMAT events

Hi Tom,



On Mon, Mar 30, 2009 at 12:22:04AM -0500, Tom Zanussi wrote:
> This patch adds run-time field descriptions to all the event formats
> exported using TRACE_EVENT_FORMAT.  It also hooks up all the tracers
> that use them (i.e. the tracers in the 'ftrace subsystem') so they can
> also have their output filtered by the event-filtering mechanism.
> 
> When I was testing this, there were a couple of things that fooled me
> into thinking the filters weren't working, when actually they were -
> I'll mention them here so others don't make the same mistakes (and file
> bug reports. ;-)
> 
> One is that some of the tracers trace multiple events e.g. the
> sched_switch tracer uses the context_switch and wakeup events, and if
> you don't set filters on all of the traced events, the unfiltered output
> from the events without filters on them can make it look like the
> filtering as a whole isn't working properly, when actually it is doing
> what it was asked to do - it just wasn't asked to do the right thing.
> 
> The other is that for the really high-volume tracers e.g. the function
> tracer, the volume of filtered events can be so high that it pushes the
> unfiltered events out of the ring buffer before they can be read so e.g.
> cat'ing the trace file repeatedly shows either no output, or once in
> awhile some output but that isn't there the next time you read the
> trace, which isn't what you normally expect when reading the trace file.
> If you read from the trace_pipe file though, you can catch them before
> they disappear.



Oh, do you know why these unfiltered event are disappearing?


> 
> Signed-off-by: Tom Zanussi <tzanussi@...il.com>
> 
> ---
>  kernel/trace/kmemtrace.c            |    8 +++++
>  kernel/trace/trace.c                |   35 +++++++++++++++++++++
>  kernel/trace/trace.h                |   15 +++++++++
>  kernel/trace/trace_branch.c         |    4 ++
>  kernel/trace/trace_event_types.h    |    6 ++-
>  kernel/trace/trace_events.c         |    7 ++++
>  kernel/trace/trace_events_filter.c  |    4 +-
>  kernel/trace/trace_events_stage_2.h |    7 ----
>  kernel/trace/trace_export.c         |   57 +++++++++++++++++++++++++++++++++--
>  kernel/trace/trace_hw_branches.c    |    3 ++
>  kernel/trace/trace_power.c          |    6 ++++
>  11 files changed, 138 insertions(+), 14 deletions(-)
> 
> diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c
> index 5011f4d..5962377 100644
> --- a/kernel/trace/kmemtrace.c
> +++ b/kernel/trace/kmemtrace.c
> @@ -42,6 +42,8 @@ static inline void kmemtrace_alloc(enum kmemtrace_type_id type_id,
>  				   gfp_t gfp_flags,
>  				   int node)
>  {
> +	extern struct ftrace_event_call event_kmem_alloc;


I think you should avoid "extern" inside a function.
You can include trace_event_types.h where they are defined.



> +	struct ftrace_event_call *call = &event_kmem_alloc;
>  	struct trace_array *tr = kmemtrace_array;
>  	struct kmemtrace_alloc_entry *entry;
>  	struct ring_buffer_event *event;
> @@ -62,6 +64,8 @@ static inline void kmemtrace_alloc(enum kmemtrace_type_id type_id,
>  	entry->gfp_flags	= gfp_flags;
>  	entry->node		= node;
>  
> +	filter_check_discard(call, entry, event);
> +
>  	ring_buffer_unlock_commit(tr->buffer, event);
>  
>  	trace_wake_up();
> @@ -71,6 +75,8 @@ static inline void kmemtrace_free(enum kmemtrace_type_id type_id,
>  				  unsigned long call_site,
>  				  const void *ptr)
>  {
> +	extern struct ftrace_event_call event_kmem_free;
> +	struct ftrace_event_call *call = &event_kmem_free;
>  	struct trace_array *tr = kmemtrace_array;
>  	struct kmemtrace_free_entry *entry;
>  	struct ring_buffer_event *event;
> @@ -86,6 +92,8 @@ static inline void kmemtrace_free(enum kmemtrace_type_id type_id,
>  	entry->call_site	= call_site;
>  	entry->ptr		= ptr;
>  
> +	filter_check_discard(call, entry, event);
> +
>  	ring_buffer_unlock_commit(tr->buffer, event);
>  
>  	trace_wake_up();
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 2a81dec..3624b25 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -898,6 +898,8 @@ trace_function(struct trace_array *tr,
>  	       unsigned long ip, unsigned long parent_ip, unsigned long flags,
>  	       int pc)
>  {
> +	extern struct ftrace_event_call event_function;


Ditto.


> +	struct ftrace_event_call *call = &event_function;
>  	struct ring_buffer_event *event;
>  	struct ftrace_entry *entry;
>  
> @@ -912,6 +914,9 @@ trace_function(struct trace_array *tr,
>  	entry	= ring_buffer_event_data(event);
>  	entry->ip			= ip;
>  	entry->parent_ip		= parent_ip;
> +
> +	filter_check_discard(call, entry, event);



trace_function may be called for every functions in the kernel.
So this is a very hot path.

It would be better to have a:

if (unlikely(filter_enabled))
	filter_check_discard(...)

or something like that to not make the weight of filtering
more heavy than a ghost in the off case (=no filter set).



>  	ring_buffer_unlock_commit(tr->buffer, event);
>  }
>  
> @@ -921,6 +926,8 @@ static int __trace_graph_entry(struct trace_array *tr,
>  				unsigned long flags,
>  				int pc)
>  {
> +	extern struct ftrace_event_call event_funcgraph_entry;
> +	struct ftrace_event_call *call = &event_funcgraph_entry;
>  	struct ring_buffer_event *event;
>  	struct ftrace_graph_ent_entry *entry;
>  
> @@ -933,6 +940,7 @@ static int __trace_graph_entry(struct trace_array *tr,
>  		return 0;
>  	entry	= ring_buffer_event_data(event);
>  	entry->graph_ent			= *trace;
> +	filter_check_discard(call, entry, event);



That's the same for this function but worst! Because the function
graph tracer is even more costly than the function tracer.


>  	ring_buffer_unlock_commit(global_trace.buffer, event);
>  
>  	return 1;
> @@ -943,6 +951,8 @@ static void __trace_graph_return(struct trace_array *tr,
>  				unsigned long flags,
>  				int pc)
>  {
> +	extern struct ftrace_event_call event_funcgraph_exit;
> +	struct ftrace_event_call *call = &event_funcgraph_exit;
>  	struct ring_buffer_event *event;
>  	struct ftrace_graph_ret_entry *entry;
>  
> @@ -955,6 +965,7 @@ static void __trace_graph_return(struct trace_array *tr,
>  		return;
>  	entry	= ring_buffer_event_data(event);
>  	entry->ret				= *trace;
> +	filter_check_discard(call, entry, event);



Ditto.



>  	ring_buffer_unlock_commit(global_trace.buffer, event);
>  }
>  #endif
> @@ -973,6 +984,8 @@ static void __ftrace_trace_stack(struct trace_array *tr,
>  				 int skip, int pc)
>  {
>  #ifdef CONFIG_STACKTRACE
> +	extern struct ftrace_event_call event_kernel_stack;
> +	struct ftrace_event_call *call = &event_kernel_stack;
>  	struct ring_buffer_event *event;
>  	struct stack_entry *entry;
>  	struct stack_trace trace;
> @@ -990,6 +1003,7 @@ static void __ftrace_trace_stack(struct trace_array *tr,
>  	trace.entries		= entry->caller;
>  
>  	save_stack_trace(&trace);
> +	filter_check_discard(call, entry, event);


Should be also the same for this one because the function tracer can
rely on stack trace, providing a double cost.

May be we could put a pointer to a global var on the
struct ftrace_event_call so that we can check quickly whether we have
filters to check or not.

Say we have:

bool function_filtering;
bool function_graph_filtering;


When we set the event:

struct ftrace_event_call function_event = {
	.filter_on = &function_filtering;
};


And when you set a filter:

*event->filter_on = true;



>  	ring_buffer_unlock_commit(tr->buffer, event);
>  #endif
>  }
> @@ -1015,6 +1029,8 @@ static void ftrace_trace_userstack(struct trace_array *tr,
>  				   unsigned long flags, int pc)
>  {
>  #ifdef CONFIG_STACKTRACE
> +	extern struct ftrace_event_call event_user_stack;
> +	struct ftrace_event_call *call = &event_user_stack;
>  	struct ring_buffer_event *event;
>  	struct userstack_entry *entry;
>  	struct stack_trace trace;
> @@ -1036,6 +1052,7 @@ static void ftrace_trace_userstack(struct trace_array *tr,
>  	trace.entries		= entry->caller;
>  
>  	save_stack_trace_user(&trace);
> +	filter_check_discard(call, entry, event);



I don't remember well but I think the function tracer can rely on it too.



>  	ring_buffer_unlock_commit(tr->buffer, event);
>  #endif
>  }
> @@ -1052,6 +1069,8 @@ ftrace_trace_special(void *__tr,
>  		     unsigned long arg1, unsigned long arg2, unsigned long arg3,
>  		     int pc)
>  {
> +	extern struct ftrace_event_call event_special;
> +	struct ftrace_event_call *call = &event_special;
>  	struct ring_buffer_event *event;
>  	struct trace_array *tr = __tr;
>  	struct special_entry *entry;
> @@ -1064,6 +1083,7 @@ ftrace_trace_special(void *__tr,
>  	entry->arg1			= arg1;
>  	entry->arg2			= arg2;
>  	entry->arg3			= arg3;
> +	filter_check_discard(call, entry, event);



Hmm, the trace_special type can have multiple semantics.
I don't know if it's worth enable filtering for it.



>  	trace_buffer_unlock_commit(tr, event, 0, pc);
>  }
>  
> @@ -1080,6 +1100,8 @@ tracing_sched_switch_trace(struct trace_array *tr,
>  			   struct task_struct *next,
>  			   unsigned long flags, int pc)
>  {
> +	extern struct ftrace_event_call event_context_switch;
> +	struct ftrace_event_call *call = &event_context_switch;
>  	struct ring_buffer_event *event;
>  	struct ctx_switch_entry *entry;
>  
> @@ -1095,6 +1117,9 @@ tracing_sched_switch_trace(struct trace_array *tr,
>  	entry->next_prio		= next->prio;
>  	entry->next_state		= next->state;
>  	entry->next_cpu	= task_cpu(next);
> +
> +	filter_check_discard(call, entry, event);
> +
>  	trace_buffer_unlock_commit(tr, event, flags, pc);
>  }
>  
> @@ -1104,6 +1129,8 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
>  			   struct task_struct *curr,
>  			   unsigned long flags, int pc)
>  {
> +	extern struct ftrace_event_call event_wakeup;
> +	struct ftrace_event_call *call = &event_wakeup;
>  	struct ring_buffer_event *event;
>  	struct ctx_switch_entry *entry;
>  
> @@ -1120,6 +1147,8 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
>  	entry->next_state		= wakee->state;
>  	entry->next_cpu			= task_cpu(wakee);
>  
> +	filter_check_discard(call, entry, event);
> +
>  	ring_buffer_unlock_commit(tr->buffer, event);
>  	ftrace_trace_stack(tr, flags, 6, pc);
>  	ftrace_trace_userstack(tr, flags, pc);
> @@ -1221,6 +1250,8 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
>  		(raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
>  	static u32 trace_buf[TRACE_BUF_SIZE];
>  
> +	extern struct ftrace_event_call event_bprint;
> +	struct ftrace_event_call *call = &event_bprint;
>  	struct ring_buffer_event *event;
>  	struct trace_array *tr = &global_trace;
>  	struct trace_array_cpu *data;
> @@ -1260,6 +1291,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
>  	entry->fmt			= fmt;
>  
>  	memcpy(entry->buf, trace_buf, sizeof(u32) * len);
> +	filter_check_discard(call, entry, event);
>  	ring_buffer_unlock_commit(tr->buffer, event);
>  
>  out_unlock:
> @@ -1279,6 +1311,8 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
>  	static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED;
>  	static char trace_buf[TRACE_BUF_SIZE];
>  
> +	extern struct ftrace_event_call event_print;
> +	struct ftrace_event_call *call = &event_print;
>  	struct ring_buffer_event *event;
>  	struct trace_array *tr = &global_trace;
>  	struct trace_array_cpu *data;
> @@ -1314,6 +1348,7 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
>  
>  	memcpy(&entry->buf, trace_buf, len);
>  	entry->buf[len] = 0;
> +	filter_check_discard(call, entry, event);
>  	ring_buffer_unlock_commit(tr->buffer, event);
>  
>   out_unlock:
> diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
> index fec6521..cfb07ef 100644
> --- a/kernel/trace/trace.h
> +++ b/kernel/trace/trace.h
> @@ -860,6 +860,21 @@ extern void filter_free_subsystem_preds(struct event_subsystem *system);
>  extern int filter_add_subsystem_pred(struct event_subsystem *system,
>  				     struct filter_pred *pred);
>  
> +static inline void
> +filter_check_discard(struct ftrace_event_call *call, void *rec,
> +		     struct ring_buffer_event *event)
> +{
> +	if (call->preds && !filter_match_preds(call, rec))


Ah you have made it more lightweight than I thought.
I don't remember, is call->preds == NULL when we disable
a filter? I mean, after we have enabled it once?



> +		ring_buffer_event_discard(event);
> +}
> +
> +#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[];
> diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
> index e6e3291..8ee5f1d 100644
> --- a/kernel/trace/trace_branch.c
> +++ b/kernel/trace/trace_branch.c
> @@ -30,6 +30,8 @@ static struct trace_array *branch_tracer;
>  static void
>  probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
>  {
> +	extern struct ftrace_event_call event_branch;
> +	struct ftrace_event_call *call = &event_branch;
>  	struct trace_array *tr = branch_tracer;
>  	struct ring_buffer_event *event;
>  	struct trace_branch *entry;
> @@ -73,6 +75,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
>  	entry->line = f->line;
>  	entry->correct = val == expect;
>  
> +	filter_check_discard(call, entry, event);
> +
>  	ring_buffer_unlock_commit(tr->buffer, event);
>  
>   out:
> diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h
> index fd78bee..95b147a 100644
> --- a/kernel/trace/trace_event_types.h
> +++ b/kernel/trace/trace_event_types.h
> @@ -122,8 +122,10 @@ TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore,
>  TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore,
>  	TRACE_STRUCT(
>  		TRACE_FIELD(unsigned int, line, line)
> -		TRACE_FIELD_SPECIAL(char func[TRACE_FUNC_SIZE+1], func, func)
> -		TRACE_FIELD_SPECIAL(char file[TRACE_FUNC_SIZE+1], file, file)
> +		TRACE_FIELD_SPECIAL(char func[TRACE_FUNC_SIZE+1], func,
> +				    TRACE_FUNC_SIZE+1, func)
> +		TRACE_FIELD_SPECIAL(char file[TRACE_FUNC_SIZE+1], file,
> +				    TRACE_FUNC_SIZE+1, file)
>  		TRACE_FIELD(char, correct, correct)
>  	),
>  	TP_RAW_FMT("%u:%s:%s (%u)")
> diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
> index 64ec4d2..be9299a 100644
> --- a/kernel/trace/trace_events.c
> +++ b/kernel/trace/trace_events.c
> @@ -680,6 +680,7 @@ static struct dentry *
>  event_subsystem_dir(const char *name, struct dentry *d_events)
>  {
>  	struct event_subsystem *system;
> +	struct dentry *entry;
>  
>  	/* First see if we did not already create this dir */
>  	list_for_each_entry(system, &event_subsystems, list) {
> @@ -708,6 +709,12 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
>  
>  	system->preds = NULL;
>  
> +	entry = debugfs_create_file("filter", 0644, system->entry, system,
> +				    &ftrace_subsystem_filter_fops);
> +	if (!entry)
> +		pr_warning("Could not create debugfs "
> +			   "'%s/filter' entry\n", name);
> +
>  	return system->entry;
>  }
>  
> diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
> index 026be41..470ad94 100644
> --- a/kernel/trace/trace_events_filter.c
> +++ b/kernel/trace/trace_events_filter.c
> @@ -185,7 +185,7 @@ void filter_free_subsystem_preds(struct event_subsystem *system)
>  	}
>  
>  	events_for_each(call) {
> -		if (!call->name || !call->regfunc)
> +		if (!call->define_fields)
>  			continue;
>  
>  		if (!strcmp(call->system, system->name))
> @@ -324,7 +324,7 @@ int filter_add_subsystem_pred(struct event_subsystem *system,
>  	events_for_each(call) {
>  		int err;
>  
> -		if (!call->name || !call->regfunc)
> +		if (!call->define_fields)
>  			continue;
>  
>  		if (strcmp(call->system, system->name))
> diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h
> index 30743f7..1c94b87 100644
> --- a/kernel/trace/trace_events_stage_2.h
> +++ b/kernel/trace/trace_events_stage_2.h
> @@ -146,13 +146,6 @@ ftrace_format_##call(struct trace_seq *s)				\
>  	if (ret)							\
>  		return ret;
>  
> -#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;
> -
>  #undef TRACE_EVENT
>  #define TRACE_EVENT(call, proto, args, tstruct, func, print)		\
>  int									\
> diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
> index 4d9952d..47989be 100644
> --- a/kernel/trace/trace_export.c
> +++ b/kernel/trace/trace_export.c
> @@ -30,7 +30,7 @@
>  
>  
>  #undef TRACE_FIELD_SPECIAL
> -#define TRACE_FIELD_SPECIAL(type_item, item, cmd)			\
> +#define TRACE_FIELD_SPECIAL(type_item, item, len, cmd)			\
>  	ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t"	\
>  			       "offset:%u;\tsize:%u;\n",		\
>  			       (unsigned int)offsetof(typeof(field), item), \
> @@ -85,18 +85,69 @@ ftrace_format_##call(struct trace_seq *s)				\
>  #define TRACE_ENTRY	entry
>  
>  #undef TRACE_FIELD_SPECIAL
> -#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \
> +#define TRACE_FIELD_SPECIAL(type_item, item, len, cmd)	\
>  	cmd;
>  
>  #undef TRACE_EVENT_FORMAT
>  #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)	\
> +int ftrace_define_fields_##call(void);					\
> +static int ftrace_raw_init_event_##call(void);				\
>  									\
> -static struct ftrace_event_call __used					\
> +struct ftrace_event_call __used						\
>  __attribute__((__aligned__(4)))						\
>  __attribute__((section("_ftrace_events"))) event_##call = {		\
>  	.name			= #call,				\
>  	.id			= proto,				\
>  	.system			= __stringify(TRACE_SYSTEM),		\
> +	.raw_init		= ftrace_raw_init_event_##call,		\
>  	.show_format		= ftrace_format_##call,			\
> +	.define_fields		= ftrace_define_fields_##call,		\
> +};									\
> +static int ftrace_raw_init_event_##call(void)				\
> +{									\
> +	INIT_LIST_HEAD(&event_##call.fields);				\
> +	return 0;							\
> +}									\
> 
> +#include "trace_event_types.h"
> +
> +#undef TRACE_FIELD
> +#define TRACE_FIELD(type, item, assign)					\
> +	ret = trace_define_field(event_call, #type, #item,		\
> +				 offsetof(typeof(field), item),		\
> +				 sizeof(field.item));			\
> +	if (ret)							\
> +		return ret;
> +
> +#undef TRACE_FIELD_SPECIAL
> +#define TRACE_FIELD_SPECIAL(type, item, len, cmd)			\
> +	ret = trace_define_field(event_call, #type "[" #len "]", #item,	\
> +				 offsetof(typeof(field), item),		\
> +				 sizeof(field.item));			\
> +	if (ret)							\
> +		return ret;
> +
> +#undef TRACE_FIELD_ZERO_CHAR
> +#define TRACE_FIELD_ZERO_CHAR(item)
> +
> +#undef TRACE_EVENT_FORMAT
> +#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)	\
> +int									\
> +ftrace_define_fields_##call(void)					\
> +{									\
> +	struct ftrace_event_call *event_call = &event_##call;		\
> +	struct args field;						\
> +	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_event_types.h"
> diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
> index 7bfdf4c..bca7791 100644
> --- a/kernel/trace/trace_hw_branches.c
> +++ b/kernel/trace/trace_hw_branches.c
> @@ -168,6 +168,8 @@ static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
>  
>  void trace_hw_branch(u64 from, u64 to)
>  {
> +	extern struct ftrace_event_call event_hw_branch;
> +	struct ftrace_event_call *call = &event_hw_branch;
>  	struct trace_array *tr = hw_branch_trace;
>  	struct ring_buffer_event *event;
>  	struct hw_branch_entry *entry;
> @@ -194,6 +196,7 @@ void trace_hw_branch(u64 from, u64 to)
>  	entry->ent.type = TRACE_HW_BRANCHES;
>  	entry->from = from;
>  	entry->to   = to;
> +	filter_check_discard(call, entry, event);
>  	trace_buffer_unlock_commit(tr, event, 0, 0);
>  
>   out:
> diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c
> index bae791e..20ef32d 100644
> --- a/kernel/trace/trace_power.c
> +++ b/kernel/trace/trace_power.c
> @@ -36,6 +36,8 @@ static void probe_power_start(struct power_trace *it, unsigned int type,
>  
>  static void probe_power_end(struct power_trace *it)
>  {
> +	extern struct ftrace_event_call event_power;
> +	struct ftrace_event_call *call = &event_power;
>  	struct ring_buffer_event *event;
>  	struct trace_power *entry;
>  	struct trace_array_cpu *data;
> @@ -54,6 +56,7 @@ static void probe_power_end(struct power_trace *it)
>  		goto out;
>  	entry	= ring_buffer_event_data(event);
>  	entry->state_data = *it;
> +	filter_check_discard(call, entry, event);
>  	trace_buffer_unlock_commit(tr, event, 0, 0);
>   out:
>  	preempt_enable();
> @@ -62,6 +65,8 @@ static void probe_power_end(struct power_trace *it)
>  static void probe_power_mark(struct power_trace *it, unsigned int type,
>  				unsigned int level)
>  {
> +	extern struct ftrace_event_call event_power;
> +	struct ftrace_event_call *call = &event_power;
>  	struct ring_buffer_event *event;
>  	struct trace_power *entry;
>  	struct trace_array_cpu *data;
> @@ -84,6 +89,7 @@ static void probe_power_mark(struct power_trace *it, unsigned int type,
>  		goto out;
>  	entry	= ring_buffer_event_data(event);
>  	entry->state_data = *it;
> +	filter_check_discard(call, entry, event);
>  	trace_buffer_unlock_commit(tr, event, 0, 0);
>   out:
>  	preempt_enable();
> -- 
> 1.5.6.3
> 



All ine one it looks nice!

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ