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 /kernel/trace | |
| 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>
Diffstat (limited to 'kernel/trace')
| -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 | ||
