Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f306cc82 authored by Tom Zanussi's avatar Tom Zanussi Committed by Steven Rostedt
Browse files

tracing: Update event filters for multibuffer

The trace event filters are still tied to event calls rather than
event files, which means you don't get what you'd expect when using
filters in the multibuffer case:

Before:

  # echo 'bytes_alloc > 8192' > /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
  # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
  bytes_alloc > 8192
  # mkdir /sys/kernel/debug/tracing/instances/test1
  # echo 'bytes_alloc > 2048' > /sys/kernel/debug/tracing/instances/test1/events/kmem/kmalloc/filter
  # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
  bytes_alloc > 2048
  # cat /sys/kernel/debug/tracing/instances/test1/events/kmem/kmalloc/filter
  bytes_alloc > 2048

Setting the filter in tracing/instances/test1/events shouldn't affect
the same event in tracing/events as it does above.

After:

  # echo 'bytes_alloc > 8192' > /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
  # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
  bytes_alloc > 8192
  # mkdir /sys/kernel/debug/tracing/instances/test1
  # echo 'bytes_alloc > 2048' > /sys/kernel/debug/tracing/instances/test1/events/kmem/kmalloc/filter
  # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
  bytes_alloc > 8192
  # cat /sys/kernel/debug/tracing/instances/test1/events/kmem/kmalloc/filter
  bytes_alloc > 2048

We'd like to just move the filter directly from ftrace_event_call to
ftrace_event_file, but there are a couple cases that don't yet have
multibuffer support and therefore have to continue using the current
event_call-based filters.  For those cases, a new USE_CALL_FILTER bit
is added to the event_call flags, whose main purpose is to keep the
old behavior for those cases until they can be updated with
multibuffer support; at that point, the USE_CALL_FILTER flag (and the
new associated call_filter_check_discard() function) can go away.

The multibuffer support also made filter_current_check_discard()
redundant, so this change removes that function as well and replaces
it with filter_check_discard() (or call_filter_check_discard() as
appropriate).

Link: http://lkml.kernel.org/r/f16e9ce4270c62f46b2e966119225e1c3cca7e60.1382620672.git.tom.zanussi@linux.intel.com



Signed-off-by: default avatarTom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent f02b625d
Loading
Loading
Loading
Loading
+20 −5
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ enum {
	TRACE_EVENT_FL_NO_SET_FILTER_BIT,
	TRACE_EVENT_FL_IGNORE_ENABLE_BIT,
	TRACE_EVENT_FL_WAS_ENABLED_BIT,
	TRACE_EVENT_FL_USE_CALL_FILTER_BIT,
};

/*
@@ -213,6 +214,7 @@ enum {
 *  WAS_ENABLED   - Set and stays set when an event was ever enabled
 *                    (used for module unloading, if a module event is enabled,
 *                     it is best to clear the buffers that used it).
 *  USE_CALL_FILTER - For ftrace internal events, don't use file filter
 */
enum {
	TRACE_EVENT_FL_FILTERED		= (1 << TRACE_EVENT_FL_FILTERED_BIT),
@@ -220,6 +222,7 @@ enum {
	TRACE_EVENT_FL_NO_SET_FILTER	= (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT),
	TRACE_EVENT_FL_IGNORE_ENABLE	= (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT),
	TRACE_EVENT_FL_WAS_ENABLED	= (1 << TRACE_EVENT_FL_WAS_ENABLED_BIT),
	TRACE_EVENT_FL_USE_CALL_FILTER	= (1 << TRACE_EVENT_FL_USE_CALL_FILTER_BIT),
};

struct ftrace_event_call {
@@ -238,6 +241,7 @@ struct ftrace_event_call {
	 *   bit 2:		failed to apply filter
	 *   bit 3:		ftrace internal event (do not enable)
	 *   bit 4:		Event was enabled by module
	 *   bit 5:		use call filter rather than file filter
	 */
	int			flags; /* static flags of different events */

@@ -253,6 +257,8 @@ struct ftrace_subsystem_dir;
enum {
	FTRACE_EVENT_FL_ENABLED_BIT,
	FTRACE_EVENT_FL_RECORDED_CMD_BIT,
	FTRACE_EVENT_FL_FILTERED_BIT,
	FTRACE_EVENT_FL_NO_SET_FILTER_BIT,
	FTRACE_EVENT_FL_SOFT_MODE_BIT,
	FTRACE_EVENT_FL_SOFT_DISABLED_BIT,
};
@@ -261,6 +267,8 @@ enum {
 * Ftrace event file flags:
 *  ENABLED	  - The event is enabled
 *  RECORDED_CMD  - The comms should be recorded at sched_switch
 *  FILTERED	  - The event has a filter attached
 *  NO_SET_FILTER - Set when filter has error and is to be ignored
 *  SOFT_MODE     - The event is enabled/disabled by SOFT_DISABLED
 *  SOFT_DISABLED - When set, do not trace the event (even though its
 *                   tracepoint may be enabled)
@@ -268,6 +276,8 @@ enum {
enum {
	FTRACE_EVENT_FL_ENABLED		= (1 << FTRACE_EVENT_FL_ENABLED_BIT),
	FTRACE_EVENT_FL_RECORDED_CMD	= (1 << FTRACE_EVENT_FL_RECORDED_CMD_BIT),
	FTRACE_EVENT_FL_FILTERED	= (1 << FTRACE_EVENT_FL_FILTERED_BIT),
	FTRACE_EVENT_FL_NO_SET_FILTER	= (1 << FTRACE_EVENT_FL_NO_SET_FILTER_BIT),
	FTRACE_EVENT_FL_SOFT_MODE	= (1 << FTRACE_EVENT_FL_SOFT_MODE_BIT),
	FTRACE_EVENT_FL_SOFT_DISABLED	= (1 << FTRACE_EVENT_FL_SOFT_DISABLED_BIT),
};
@@ -275,6 +285,7 @@ enum {
struct ftrace_event_file {
	struct list_head		list;
	struct ftrace_event_call	*event_call;
	struct event_filter		*filter;
	struct dentry			*dir;
	struct trace_array		*tr;
	struct ftrace_subsystem_dir	*system;
@@ -310,11 +321,15 @@ struct ftrace_event_file {

#define MAX_FILTER_STR_VAL	256	/* Should handle KSYM_SYMBOL_LEN */

extern void destroy_preds(struct ftrace_event_call *call);
extern void destroy_preds(struct ftrace_event_file *file);
extern void destroy_call_preds(struct ftrace_event_call *call);
extern int filter_match_preds(struct event_filter *filter, void *rec);
extern int filter_current_check_discard(struct ring_buffer *buffer,
					struct ftrace_event_call *call,
					void *rec,

extern int filter_check_discard(struct ftrace_event_file *file, void *rec,
				struct ring_buffer *buffer,
				struct ring_buffer_event *event);
extern int call_filter_check_discard(struct ftrace_event_call *call, void *rec,
				     struct ring_buffer *buffer,
				     struct ring_buffer_event *event);

enum {
+2 −2
Original line number Diff line number Diff line
@@ -120,7 +120,7 @@ extern struct trace_event_functions exit_syscall_print_funcs;
		.class			= &event_class_syscall_enter,	\
		.event.funcs            = &enter_syscall_print_funcs,	\
		.data			= (void *)&__syscall_meta_##sname,\
		.flags			= TRACE_EVENT_FL_CAP_ANY,	\
		.flags			= TRACE_EVENT_FL_CAP_ANY | TRACE_EVENT_FL_USE_CALL_FILTER,\
	};								\
	static struct ftrace_event_call __used				\
	  __attribute__((section("_ftrace_events")))			\
@@ -134,7 +134,7 @@ extern struct trace_event_functions exit_syscall_print_funcs;
		.class			= &event_class_syscall_exit,	\
		.event.funcs		= &exit_syscall_print_funcs,	\
		.data			= (void *)&__syscall_meta_##sname,\
		.flags			= TRACE_EVENT_FL_CAP_ANY,	\
		.flags			= TRACE_EVENT_FL_CAP_ANY | TRACE_EVENT_FL_USE_CALL_FILTER,\
	};								\
	static struct ftrace_event_call __used				\
	  __attribute__((section("_ftrace_events")))			\
+3 −4
Original line number Diff line number Diff line
@@ -437,9 +437,8 @@ static inline notrace int ftrace_get_offsets_##call( \
 *	{ <assign>; }  <-- Here we assign the entries by the __field and
 *			   __array macros.
 *
 *	if (!filter_current_check_discard(buffer, event_call, entry, event))
 *		trace_nowake_buffer_unlock_commit(buffer,
 *						   event, irq_flags, pc);
 *	if (!filter_check_discard(ftrace_file, entry, buffer, event))
 *		trace_buffer_unlock_commit(buffer, event, irq_flags, pc);
 * }
 *
 * static struct trace_event ftrace_event_type_<call> = {
@@ -553,7 +552,7 @@ ftrace_raw_event_##call(void *__data, proto) \
									\
	{ assign; }							\
									\
	if (!filter_current_check_discard(buffer, event_call, entry, event)) \
	if (!filter_check_discard(ftrace_file, entry, buffer, event))	\
		trace_buffer_unlock_commit(buffer, event, irq_flags, pc); \
}
/*
+30 −10
Original line number Diff line number Diff line
@@ -235,13 +235,33 @@ void trace_array_put(struct trace_array *this_tr)
	mutex_unlock(&trace_types_lock);
}

int filter_current_check_discard(struct ring_buffer *buffer,
				 struct ftrace_event_call *call, void *rec,
int filter_check_discard(struct ftrace_event_file *file, void *rec,
			 struct ring_buffer *buffer,
			 struct ring_buffer_event *event)
{
	return filter_check_discard(call, rec, buffer, event);
	if (unlikely(file->flags & FTRACE_EVENT_FL_FILTERED) &&
	    !filter_match_preds(file->filter, rec)) {
		ring_buffer_discard_commit(buffer, event);
		return 1;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(filter_check_discard);

int call_filter_check_discard(struct ftrace_event_call *call, void *rec,
			      struct ring_buffer *buffer,
			      struct ring_buffer_event *event)
{
	if (unlikely(call->flags & TRACE_EVENT_FL_FILTERED) &&
	    !filter_match_preds(call->filter, rec)) {
		ring_buffer_discard_commit(buffer, event);
		return 1;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(filter_current_check_discard);
EXPORT_SYMBOL_GPL(call_filter_check_discard);

cycle_t buffer_ftrace_now(struct trace_buffer *buf, int cpu)
{
@@ -1633,7 +1653,7 @@ trace_function(struct trace_array *tr,
	entry->ip			= ip;
	entry->parent_ip		= parent_ip;

	if (!filter_check_discard(call, entry, buffer, event))
	if (!call_filter_check_discard(call, entry, buffer, event))
		__buffer_unlock_commit(buffer, event);
}

@@ -1717,7 +1737,7 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer,

	entry->size = trace.nr_entries;

	if (!filter_check_discard(call, entry, buffer, event))
	if (!call_filter_check_discard(call, entry, buffer, event))
		__buffer_unlock_commit(buffer, event);

 out:
@@ -1819,7 +1839,7 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
	trace.entries		= entry->caller;

	save_stack_trace_user(&trace);
	if (!filter_check_discard(call, entry, buffer, event))
	if (!call_filter_check_discard(call, entry, buffer, event))
		__buffer_unlock_commit(buffer, event);

 out_drop_count:
@@ -2011,7 +2031,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
	entry->fmt			= fmt;

	memcpy(entry->buf, tbuffer, sizeof(u32) * len);
	if (!filter_check_discard(call, entry, buffer, event)) {
	if (!call_filter_check_discard(call, entry, buffer, event)) {
		__buffer_unlock_commit(buffer, event);
		ftrace_trace_stack(buffer, flags, 6, pc);
	}
@@ -2066,7 +2086,7 @@ __trace_array_vprintk(struct ring_buffer *buffer,

	memcpy(&entry->buf, tbuffer, len);
	entry->buf[len] = '\0';
	if (!filter_check_discard(call, entry, buffer, event)) {
	if (!call_filter_check_discard(call, entry, buffer, event)) {
		__buffer_unlock_commit(buffer, event);
		ftrace_trace_stack(buffer, flags, 6, pc);
	}
+2 −16
Original line number Diff line number Diff line
@@ -1007,9 +1007,9 @@ struct filter_pred {

extern enum regex_type
filter_parse_regex(char *buff, int len, char **search, int *not);
extern void print_event_filter(struct ftrace_event_call *call,
extern void print_event_filter(struct ftrace_event_file *file,
			       struct trace_seq *s);
extern int apply_event_filter(struct ftrace_event_call *call,
extern int apply_event_filter(struct ftrace_event_file *file,
			      char *filter_string);
extern int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir,
					char *filter_string);
@@ -1020,20 +1020,6 @@ extern int filter_assign_type(const char *type);
struct ftrace_event_field *
trace_find_event_field(struct ftrace_event_call *call, char *name);

static inline int
filter_check_discard(struct ftrace_event_call *call, void *rec,
		     struct ring_buffer *buffer,
		     struct ring_buffer_event *event)
{
	if (unlikely(call->flags & TRACE_EVENT_FL_FILTERED) &&
	    !filter_match_preds(call->filter, rec)) {
		ring_buffer_discard_commit(buffer, event);
		return 1;
	}

	return 0;
}

extern void trace_event_enable_cmd_record(bool enable);
extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr);
extern int event_trace_del_tracer(struct trace_array *tr);
Loading