diff options
author | Jiri Olsa <jolsa@redhat.com> | 2011-08-11 10:25:53 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2011-08-19 14:35:58 -0400 |
commit | f30120fce1efaa426f340a354d5ace36dab59f0e (patch) | |
tree | 03a819877897ec8f40f0f889a8cd3659ba056926 | |
parent | 96bc293a97e7f1651977976be7dd42031f6d8ea3 (diff) |
tracing/filter: Change filter_match_preds function to use walk_pred_tree
Changing filter_match_preds function to use unified predicates tree
processing.
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1313072754-4620-10-git-send-email-jolsa@redhat.com
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | kernel/trace/trace_events_filter.c | 124 |
1 files changed, 58 insertions, 66 deletions
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index f44e68b89f15..319c3cac7d95 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -467,99 +467,91 @@ static int process_ops(struct filter_pred *preds, | |||
467 | 467 | ||
468 | for (i = 0; i < op->val; i++) { | 468 | for (i = 0; i < op->val; i++) { |
469 | pred = &preds[op->ops[i]]; | 469 | pred = &preds[op->ops[i]]; |
470 | match = pred->fn(pred, rec); | 470 | if (!WARN_ON_ONCE(!pred->fn)) |
471 | match = pred->fn(pred, rec); | ||
471 | if (!!match == type) | 472 | if (!!match == type) |
472 | return match; | 473 | return match; |
473 | } | 474 | } |
474 | return match; | 475 | return match; |
475 | } | 476 | } |
476 | 477 | ||
478 | struct filter_match_preds_data { | ||
479 | struct filter_pred *preds; | ||
480 | int match; | ||
481 | void *rec; | ||
482 | }; | ||
483 | |||
484 | static int filter_match_preds_cb(enum move_type move, struct filter_pred *pred, | ||
485 | int *err, void *data) | ||
486 | { | ||
487 | struct filter_match_preds_data *d = data; | ||
488 | |||
489 | *err = 0; | ||
490 | switch (move) { | ||
491 | case MOVE_DOWN: | ||
492 | /* only AND and OR have children */ | ||
493 | if (pred->left != FILTER_PRED_INVALID) { | ||
494 | /* If ops is set, then it was folded. */ | ||
495 | if (!pred->ops) | ||
496 | return WALK_PRED_DEFAULT; | ||
497 | /* We can treat folded ops as a leaf node */ | ||
498 | d->match = process_ops(d->preds, pred, d->rec); | ||
499 | } else { | ||
500 | if (!WARN_ON_ONCE(!pred->fn)) | ||
501 | d->match = pred->fn(pred, d->rec); | ||
502 | } | ||
503 | |||
504 | return WALK_PRED_PARENT; | ||
505 | case MOVE_UP_FROM_LEFT: | ||
506 | /* | ||
507 | * Check for short circuits. | ||
508 | * | ||
509 | * Optimization: !!match == (pred->op == OP_OR) | ||
510 | * is the same as: | ||
511 | * if ((match && pred->op == OP_OR) || | ||
512 | * (!match && pred->op == OP_AND)) | ||
513 | */ | ||
514 | if (!!d->match == (pred->op == OP_OR)) | ||
515 | return WALK_PRED_PARENT; | ||
516 | break; | ||
517 | case MOVE_UP_FROM_RIGHT: | ||
518 | break; | ||
519 | } | ||
520 | |||
521 | return WALK_PRED_DEFAULT; | ||
522 | } | ||
523 | |||
477 | /* return 1 if event matches, 0 otherwise (discard) */ | 524 | /* return 1 if event matches, 0 otherwise (discard) */ |
478 | int filter_match_preds(struct event_filter *filter, void *rec) | 525 | int filter_match_preds(struct event_filter *filter, void *rec) |
479 | { | 526 | { |
480 | int match = -1; | ||
481 | enum move_type move = MOVE_DOWN; | ||
482 | struct filter_pred *preds; | 527 | struct filter_pred *preds; |
483 | struct filter_pred *pred; | ||
484 | struct filter_pred *root; | 528 | struct filter_pred *root; |
485 | int n_preds; | 529 | struct filter_match_preds_data data = { |
486 | int done = 0; | 530 | /* match is currently meaningless */ |
531 | .match = -1, | ||
532 | .rec = rec, | ||
533 | }; | ||
534 | int n_preds, ret; | ||
487 | 535 | ||
488 | /* no filter is considered a match */ | 536 | /* no filter is considered a match */ |
489 | if (!filter) | 537 | if (!filter) |
490 | return 1; | 538 | return 1; |
491 | 539 | ||
492 | n_preds = filter->n_preds; | 540 | n_preds = filter->n_preds; |
493 | |||
494 | if (!n_preds) | 541 | if (!n_preds) |
495 | return 1; | 542 | return 1; |
496 | 543 | ||
497 | /* | 544 | /* |
498 | * n_preds, root and filter->preds are protect with preemption disabled. | 545 | * n_preds, root and filter->preds are protect with preemption disabled. |
499 | */ | 546 | */ |
500 | preds = rcu_dereference_sched(filter->preds); | ||
501 | root = rcu_dereference_sched(filter->root); | 547 | root = rcu_dereference_sched(filter->root); |
502 | if (!root) | 548 | if (!root) |
503 | return 1; | 549 | return 1; |
504 | 550 | ||
505 | pred = root; | 551 | data.preds = preds = rcu_dereference_sched(filter->preds); |
506 | 552 | ret = walk_pred_tree(preds, root, filter_match_preds_cb, &data); | |
507 | /* match is currently meaningless */ | 553 | WARN_ON(ret); |
508 | match = -1; | 554 | return data.match; |
509 | |||
510 | do { | ||
511 | switch (move) { | ||
512 | case MOVE_DOWN: | ||
513 | /* only AND and OR have children */ | ||
514 | if (pred->left != FILTER_PRED_INVALID) { | ||
515 | /* If ops is set, then it was folded. */ | ||
516 | if (!pred->ops) { | ||
517 | /* keep going to down the left side */ | ||
518 | pred = &preds[pred->left]; | ||
519 | continue; | ||
520 | } | ||
521 | /* We can treat folded ops as a leaf node */ | ||
522 | match = process_ops(preds, pred, rec); | ||
523 | } else | ||
524 | match = pred->fn(pred, rec); | ||
525 | /* If this pred is the only pred */ | ||
526 | if (pred == root) | ||
527 | break; | ||
528 | pred = get_pred_parent(pred, preds, | ||
529 | pred->parent, &move); | ||
530 | continue; | ||
531 | case MOVE_UP_FROM_LEFT: | ||
532 | /* | ||
533 | * Check for short circuits. | ||
534 | * | ||
535 | * Optimization: !!match == (pred->op == OP_OR) | ||
536 | * is the same as: | ||
537 | * if ((match && pred->op == OP_OR) || | ||
538 | * (!match && pred->op == OP_AND)) | ||
539 | */ | ||
540 | if (!!match == (pred->op == OP_OR)) { | ||
541 | if (pred == root) | ||
542 | break; | ||
543 | pred = get_pred_parent(pred, preds, | ||
544 | pred->parent, &move); | ||
545 | continue; | ||
546 | } | ||
547 | /* now go down the right side of the tree. */ | ||
548 | pred = &preds[pred->right]; | ||
549 | move = MOVE_DOWN; | ||
550 | continue; | ||
551 | case MOVE_UP_FROM_RIGHT: | ||
552 | /* We finished this equation. */ | ||
553 | if (pred == root) | ||
554 | break; | ||
555 | pred = get_pred_parent(pred, preds, | ||
556 | pred->parent, &move); | ||
557 | continue; | ||
558 | } | ||
559 | done = 1; | ||
560 | } while (!done); | ||
561 | |||
562 | return match; | ||
563 | } | 555 | } |
564 | EXPORT_SYMBOL_GPL(filter_match_preds); | 556 | EXPORT_SYMBOL_GPL(filter_match_preds); |
565 | 557 | ||