Commit 1a891cf1 authored by Steven Rostedt's avatar Steven Rostedt

tracing: Add binary '&' filter for events

There are some cases when filtering on a set flag of a field of a tracepoint
is useful. But currently the only filtering commands for numbered fields
is ==, !=, <, <=, >, >=. This does not help when you just want to trace if
a specific flag is set. For example:

 > # sudo trace-cmd record -e brcmfmac:brcmf_dbg -f 'level & 0x40000'
 > disable all
 > enable brcmfmac:brcmf_dbg
 > path = /sys/kernel/debug/tracing/events/brcmfmac/brcmf_dbg/enable
 > (level & 0x40000)
 > ^
 > parse_error: Invalid operator
 >

When trying to trace brcmf_dbg when level has its 1 << 18 bit set, the
filter fails to perform.

By allowing a binary '&' operation, this gives the user the ability to
test a bit.

Note, a binary '|' is not added, as it doesn't make sense as fields must
be compared to constants (for now), and ORing a constant will always return
true.

Link: http://lkml.kernel.org/r/1371057385.9844.261.camel@gandalf.local.homeSuggested-by: default avatarArend van Spriel <arend@broadcom.com>
Tested-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent aaf6ac0f
...@@ -183,7 +183,7 @@ The relational-operators depend on the type of the field being tested: ...@@ -183,7 +183,7 @@ The relational-operators depend on the type of the field being tested:
The operators available for numeric fields are: The operators available for numeric fields are:
==, !=, <, <=, >, >= ==, !=, <, <=, >, >=, &
And for string fields they are: And for string fields they are:
......
...@@ -44,6 +44,7 @@ enum filter_op_ids ...@@ -44,6 +44,7 @@ enum filter_op_ids
OP_LE, OP_LE,
OP_GT, OP_GT,
OP_GE, OP_GE,
OP_BAND,
OP_NONE, OP_NONE,
OP_OPEN_PAREN, OP_OPEN_PAREN,
}; };
...@@ -54,6 +55,7 @@ struct filter_op { ...@@ -54,6 +55,7 @@ struct filter_op {
int precedence; int precedence;
}; };
/* Order must be the same as enum filter_op_ids above */
static struct filter_op filter_ops[] = { static struct filter_op filter_ops[] = {
{ OP_OR, "||", 1 }, { OP_OR, "||", 1 },
{ OP_AND, "&&", 2 }, { OP_AND, "&&", 2 },
...@@ -64,6 +66,7 @@ static struct filter_op filter_ops[] = { ...@@ -64,6 +66,7 @@ static struct filter_op filter_ops[] = {
{ OP_LE, "<=", 5 }, { OP_LE, "<=", 5 },
{ OP_GT, ">", 5 }, { OP_GT, ">", 5 },
{ OP_GE, ">=", 5 }, { OP_GE, ">=", 5 },
{ OP_BAND, "&", 6 },
{ OP_NONE, "OP_NONE", 0 }, { OP_NONE, "OP_NONE", 0 },
{ OP_OPEN_PAREN, "(", 0 }, { OP_OPEN_PAREN, "(", 0 },
}; };
...@@ -156,6 +159,9 @@ static int filter_pred_##type(struct filter_pred *pred, void *event) \ ...@@ -156,6 +159,9 @@ static int filter_pred_##type(struct filter_pred *pred, void *event) \
case OP_GE: \ case OP_GE: \
match = (*addr >= val); \ match = (*addr >= val); \
break; \ break; \
case OP_BAND: \
match = (*addr & val); \
break; \
default: \ default: \
break; \ break; \
} \ } \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment