linux-stable/kernel/trace
Steven Rostedt 61e9dea20e tracing/filter: Use a tree instead of stack for filter_match_preds()
Currently the filter_match_preds() requires a stack to push
and pop the preds to determine if the filter matches the record or not.
This has two drawbacks:

1) It requires a stack to store state information. As this is done
   in fast paths we can't allocate the storage for this stack, and
   we can't use a global as it must be re-entrant. The stack is stored
   on the kernel stack and this greatly limits how many preds we
   may allow.

2) All conditions are calculated even when a short circuit exists.
   a || b  will always calculate a and b even though a was determined
   to be true.

Using a tree we can walk a constant structure that will save
the state as we go. The algorithm is simply:

  pred = root;
  do {
	switch (move) {
	case MOVE_DOWN:
		if (OR or AND) {
			pred = left;
			continue;
		}
		if (pred == root)
			break;
		match = pred->fn();
		pred = pred->parent;
		move = left child ? MOVE_UP_FROM_LEFT : MOVE_UP_FROM_RIGHT;
		continue;

	case MOVE_UP_FROM_LEFT:
		/* Only OR or AND can be a parent */
		if (match && OR || !match && AND) {
			/* short circuit */
			if (pred == root)
				break;
			pred = pred->parent;
			move = left child ?
				MOVE_UP_FROM_LEFT :
				MOVE_UP_FROM_RIGHT;
			continue;
		}
		pred = pred->right;
		move = MOVE_DOWN;
		continue;

	case MOVE_UP_FROM_RIGHT:
		if (pred == root)
			break;
		pred = pred->parent;
		move = left child ? MOVE_UP_FROM_LEFT : MOVE_UP_FROM_RIGHT;
		continue;
	}
	done = 1;
  } while (!done);

This way there's no strict limit to how many preds we allow
and it also will short circuit the logical operations when possible.

Cc: Tom Zanussi <tzanussi@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2011-02-07 20:56:19 -05:00
..
blktrace.c block: ensure that completion error gets properly traced 2011-01-10 09:06:44 +01:00
ftrace.c
Kconfig perf: Clean up power events by introducing new, more generic ones 2011-01-04 08:16:54 +01:00
Makefile tracing: Fix TRACE_EVENT power tracepoint creation 2011-01-07 23:26:29 -05:00
power-traces.c perf: Clean up power events by introducing new, more generic ones 2011-01-04 08:16:54 +01:00
ring_buffer.c ring_buffer: Off-by-one and duplicate events in ring_buffer_read_page 2010-12-23 12:09:30 -05:00
ring_buffer_benchmark.c
trace.c tracing: Fix preempt count leak 2011-01-07 23:20:02 -05:00
trace.h tracing/filter: Use a tree instead of stack for filter_match_preds() 2011-02-07 20:56:19 -05:00
trace_branch.c
trace_clock.c
trace_entries.h
trace_event_perf.c
trace_events.c tracing: Replace trace_event struct array with pointer array 2011-02-02 21:37:13 -05:00
trace_events_filter.c tracing/filter: Use a tree instead of stack for filter_match_preds() 2011-02-07 20:56:19 -05:00
trace_export.c tracing: Replace trace_event struct array with pointer array 2011-02-02 21:37:13 -05:00
trace_functions.c
trace_functions_graph.c
trace_irqsoff.c lockdep: Move early boot local IRQ enable/disable status to init/main.c 2011-01-20 13:32:33 +01:00
trace_kdb.c
trace_kprobe.c
trace_mmiotrace.c
trace_nop.c
trace_output.c
trace_output.h
trace_printk.c
trace_sched_switch.c
trace_sched_wakeup.c
trace_selftest.c sched: Constify function scope static struct sched_param usage 2011-01-07 15:55:45 +01:00
trace_selftest_dynamic.c
trace_stack.c
trace_stat.c
trace_stat.h
trace_syscalls.c tracing: Replace syscall_meta_data struct array with pointer array 2011-02-03 09:29:06 -05:00
trace_workqueue.c