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/

Reply via email to