mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jiri Olsa <jolsa@redhat.com>
To: rostedt@goodmis.org, fweisbec@gmail.com, mingo@redhat.com
Cc: linux-kernel@vger.kernel.org, Jiri Olsa <jolsa@redhat.com>
Subject: [PATCH 05/10] tracing/filter: Unify predicate tree walking, change check_pred_tree function to use it
Date: Thu,  4 Aug 2011 12:08:21 +0200	[thread overview]
Message-ID: <1312452506-5100-6-git-send-email-jolsa@redhat.com> (raw)
In-Reply-To: <1312452506-5100-1-git-send-email-jolsa@redhat.com>

Adding walk_pred_tree function to be used for walking throught
the filter predicates.

For each predicate the callback function is called, allowing
users to add their own functionality or customize their way
through the filter predicates.

Changing check_pred_tree function to use walk_pred_tree.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 kernel/trace/trace_events_filter.c |  137 ++++++++++++++++++++++-------------
 1 files changed, 86 insertions(+), 51 deletions(-)

diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 0948905..5b889d4 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -381,6 +381,63 @@ get_pred_parent(struct filter_pred *pred, struct filter_pred *preds,
 	return pred;
 }
 
+enum walk_return {
+	WALK_PRED_ABORT,
+	WALK_PRED_PARENT,
+	WALK_PRED_DEFAULT,
+};
+
+typedef int (*filter_pred_walkcb_t) (enum move_type move,
+				     struct filter_pred *pred,
+				     int *err, void *data);
+
+static int walk_pred_tree(struct filter_pred *preds,
+			  struct filter_pred *root,
+			  filter_pred_walkcb_t cb, void *data)
+{
+	struct filter_pred *pred = root;
+	enum move_type move = MOVE_DOWN;
+	int done = 0;
+
+	if  (!preds)
+		return -EINVAL;
+
+	do {
+		int err = 0, ret;
+
+		ret = cb(move, pred, &err, data);
+		if (ret == WALK_PRED_ABORT)
+			return err;
+		if (ret == WALK_PRED_PARENT)
+			goto get_parent;
+
+		switch (move) {
+		case MOVE_DOWN:
+			if (pred->left != FILTER_PRED_INVALID) {
+				pred = &preds[pred->left];
+				continue;
+			}
+			goto get_parent;
+		case MOVE_UP_FROM_LEFT:
+			pred = &preds[pred->right];
+			move = MOVE_DOWN;
+			continue;
+		case MOVE_UP_FROM_RIGHT:
+ get_parent:
+			if (pred == root)
+				break;
+			pred = get_pred_parent(pred, preds,
+					       pred->parent,
+					       &move);
+			continue;
+		}
+		done = 1;
+	} while (!done);
+
+	/* We are fine. */
+	return 0;
+}
+
 /*
  * A series of AND or ORs where found together. Instead of
  * climbing up and down the tree branches, an array of the
@@ -1321,6 +1378,23 @@ static int count_preds(struct filter_parse_state *ps)
 	return n_preds;
 }
 
+struct check_pred_data {
+	int count;
+	int max;
+};
+
+static int check_pred_tree_cb(enum move_type move, struct filter_pred *pred,
+			      int *err, void *data)
+{
+	struct check_pred_data *d = data;
+
+	if (WARN_ON(d->count++ > d->max)) {
+		*err = -EINVAL;
+		return WALK_PRED_ABORT;
+	}
+	return WALK_PRED_DEFAULT;
+}
+
 /*
  * The tree is walked at filtering of an event. If the tree is not correctly
  * built, it may cause an infinite loop. Check here that the tree does
@@ -1329,58 +1403,19 @@ static int count_preds(struct filter_parse_state *ps)
 static int check_pred_tree(struct event_filter *filter,
 			   struct filter_pred *root)
 {
-	struct filter_pred *preds;
-	struct filter_pred *pred;
-	enum move_type move = MOVE_DOWN;
-	int count = 0;
-	int done = 0;
-	int max;
-
-	/*
-	 * The max that we can hit a node is three times.
-	 * Once going down, once coming up from left, and
-	 * once coming up from right. This is more than enough
-	 * since leafs are only hit a single time.
-	 */
-	max = 3 * filter->n_preds;
-
-	preds = filter->preds;
-	if  (!preds)
-		return -EINVAL;
-	pred = root;
-
-	do {
-		if (WARN_ON(count++ > max))
-			return -EINVAL;
-
-		switch (move) {
-		case MOVE_DOWN:
-			if (pred->left != FILTER_PRED_INVALID) {
-				pred = &preds[pred->left];
-				continue;
-			}
-			/* A leaf at the root is just a leaf in the tree */
-			if (pred == root)
-				break;
-			pred = get_pred_parent(pred, preds,
-					       pred->parent, &move);
-			continue;
-		case MOVE_UP_FROM_LEFT:
-			pred = &preds[pred->right];
-			move = MOVE_DOWN;
-			continue;
-		case MOVE_UP_FROM_RIGHT:
-			if (pred == root)
-				break;
-			pred = get_pred_parent(pred, preds,
-					       pred->parent, &move);
-			continue;
-		}
-		done = 1;
-	} while (!done);
+	struct check_pred_data data = {
+		/*
+		 * The max that we can hit a node is three times.
+		 * Once going down, once coming up from left, and
+		 * once coming up from right. This is more than enough
+		 * since leafs are only hit a single time.
+		 */
+		.max   = 3 * filter->n_preds,
+		.count = 0,
+	};
 
-	/* We are fine. */
-	return 0;
+	return walk_pred_tree(filter->preds, root,
+			      check_pred_tree_cb, &data);
 }
 
 static int count_leafs(struct filter_pred *preds, struct filter_pred *root)
-- 
1.7.1


  parent reply	other threads:[~2011-08-04 10:09 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-04 10:08 [PATCH 0/10] ftrace/filter: Trace events filtering related fixies Jiri Olsa
2011-08-04 10:08 ` [PATCH 01/10] tracing/filter: Use static allocation for filter predicates Jiri Olsa
2011-08-04 10:08 ` [PATCH 02/10] tracing/filter: Separate predicate init and filter addition Jiri Olsa
2011-08-10 20:51   ` Steven Rostedt
2011-08-04 10:08 ` [PATCH 03/10] tracing/filter: Remove field_name from filter_pred struct Jiri Olsa
2011-08-04 10:08 ` [PATCH 04/10] tracing/filter: Simplify tracepoint event lookup Jiri Olsa
2011-08-04 10:08 ` Jiri Olsa [this message]
2011-08-04 10:08 ` [PATCH 06/10] tracing/filter: Change count_leafs function to use walk_pred_tree Jiri Olsa
2011-08-10 21:05   ` Steven Rostedt
2011-08-04 10:08 ` [PATCH 07/10] tracing/filter: Change fold_pred_tree " Jiri Olsa
2011-08-04 10:08 ` [PATCH 08/10] tracing/filter: Change fold_pred " Jiri Olsa
2011-08-04 10:08 ` [PATCH 09/10] tracing/filter: Change filter_match_preds " Jiri Olsa
2011-08-10 21:14   ` Steven Rostedt
2011-08-10 21:16     ` Steven Rostedt
2011-08-04 10:08 ` [PATCH 10/10] tracing/filter: Add startup tests for events filter Jiri Olsa
2011-08-04 11:22   ` [PATCHv2 " Jiri Olsa
2011-08-10 21:24     ` Steven Rostedt
2011-08-10 21:25 ` [PATCH 0/10] ftrace/filter: Trace events filtering related fixies Steven Rostedt
2011-08-11 14:21   ` Jiri Olsa
2011-08-11 14:25   ` [PATCHv2 " Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 01/10] tracing/filter: Use static allocation for filter predicates Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 02/10] tracing/filter: Separate predicate init and filter addition Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 03/10] tracing/filter: Remove field_name from filter_pred struct Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 04/10] tracing/filter: Simplify tracepoint event lookup Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 05/10] tracing/filter: Unify predicate tree walking, change check_pred_tree function to use it Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 06/10] tracing/filter: Change count_leafs function to use walk_pred_tree Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 07/10] tracing/filter: Change fold_pred_tree " Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 08/10] tracing/filter: Change fold_pred " Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 09/10] tracing/filter: Change filter_match_preds " Jiri Olsa
2011-08-11 14:25     ` [PATCHv2 10/10] tracing/filter: Add startup tests for events filter Jiri Olsa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1312452506-5100-6-git-send-email-jolsa@redhat.com \
    --to=jolsa@redhat.com \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®