On Mon, 1 Dec 2014 22:57:25 -0500 Steven Rostedt <rost...@goodmis.org> wrote:
> On Mon, 1 Dec 2014 19:52:11 -0800 > Alexei Starovoitov <a...@plumgrid.com> wrote: > > > yeah. teaching tree walk to do (state & 2048) == 0 is not trivial, > > since it doesn't have a concept of value of expression. > > Doing !(state & 2048) is probably a bit easier, since there > > are hacks for 'not' already. > > That's exactly what I was looking at doing. If I can get something > working without spending more than an hour or two, I may even push it > for this release cycle. Actually, this was rather trivial. It took me longer because I was doing this half asleep, but it seems to work. Note, this is a major beta patch. It probably doesn't work with ANDS and ORS, that is !(x == 1 && y == 2) probably doesn't work, but this should: !(x == 1), and so should !(state & 2048). I'll clean this up and get it ready for 3.19. Cheers! -- Steve diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 7a8c1528e141..aee7b743c9df 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -37,6 +37,7 @@ enum filter_op_ids { OP_OR, OP_AND, + OP_NOT, OP_GLOB, OP_NE, OP_EQ, @@ -59,6 +60,7 @@ struct filter_op { static struct filter_op filter_ops[] = { { OP_OR, "||", 1 }, { OP_AND, "&&", 2 }, + { OP_NOT, "!", 3 }, { OP_GLOB, "~", 4 }, { OP_NE, "!=", 4 }, { OP_EQ, "==", 4 }, @@ -166,7 +168,7 @@ static int filter_pred_##type(struct filter_pred *pred, void *event) \ break; \ } \ \ - return match; \ + return match == !pred->not; \ } #define DEFINE_EQUALITY_PRED(size) \ @@ -565,7 +567,7 @@ int filter_match_preds(struct event_filter *filter, void *rec) data.preds = preds = rcu_dereference_sched(filter->preds); ret = walk_pred_tree(preds, root, filter_match_preds_cb, &data); WARN_ON(ret); - return data.match; + return !!data.match; } EXPORT_SYMBOL_GPL(filter_match_preds); @@ -1028,7 +1030,7 @@ static int init_pred(struct filter_parse_state *ps, } if (pred->op == OP_NE) - pred->not = 1; + pred->not ^= 1; pred->fn = fn; return 0; @@ -1590,6 +1592,16 @@ static int replace_preds(struct ftrace_event_call *call, continue; } + if (elt->op == OP_NOT) { + if (!n_preds) { + err = -EINVAL; + goto fail; + } + if (!dry_run) + filter->preds[n_preds - 1].not ^= 1; + continue; + } + if (WARN_ON(n_preds++ == MAX_FILTER_PRED)) { parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0); err = -ENOSPC; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/