Commit fdf5b679 authored by Steven Rostedt (Red Hat)'s avatar Steven Rostedt (Red Hat) Committed by Steven Rostedt

tracing: Optimise comparison filters and fix binary and for 64 bit

Currently the filter logic for comparisons (like greater-than and less-than)
are used, they share the same function and a switch statement is used to
jump to the comparison type to perform. This is done in the extreme hot path
of the tracing code, and it does not take much more space to create a
unique comparison function to perform each type of comparison and remove the
switch statement.

Also, a bug was found where the binary and operation for 64 bits could fail
if the resulting bits were greater than 32 bits, because the result was
passed into a 32 bit variable. This was fixed when adding the separate
binary and function.
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 60f1d5e3
...@@ -145,34 +145,50 @@ struct pred_stack { ...@@ -145,34 +145,50 @@ struct pred_stack {
/* If not of not match is equal to not of not, then it is a match */ /* If not of not match is equal to not of not, then it is a match */
#define DEFINE_COMPARISON_PRED(type) \ #define DEFINE_COMPARISON_PRED(type) \
static int filter_pred_##type(struct filter_pred *pred, void *event) \ static int filter_pred_LT_##type(struct filter_pred *pred, void *event) \
{ \ { \
type *addr = (type *)(event + pred->offset); \ type *addr = (type *)(event + pred->offset); \
type val = (type)pred->val; \ type val = (type)pred->val; \
int match = 0; \ int match = (*addr < val); \
\
switch (pred->op) { \
case OP_LT: \
match = (*addr < val); \
break; \
case OP_LE: \
match = (*addr <= val); \
break; \
case OP_GT: \
match = (*addr > val); \
break; \
case OP_GE: \
match = (*addr >= val); \
break; \
case OP_BAND: \
match = (*addr & val); \
break; \
default: \
break; \
} \
\
return !!match == !pred->not; \ return !!match == !pred->not; \
} } \
static int filter_pred_LE_##type(struct filter_pred *pred, void *event) \
{ \
type *addr = (type *)(event + pred->offset); \
type val = (type)pred->val; \
int match = (*addr <= val); \
return !!match == !pred->not; \
} \
static int filter_pred_GT_##type(struct filter_pred *pred, void *event) \
{ \
type *addr = (type *)(event + pred->offset); \
type val = (type)pred->val; \
int match = (*addr > val); \
return !!match == !pred->not; \
} \
static int filter_pred_GE_##type(struct filter_pred *pred, void *event) \
{ \
type *addr = (type *)(event + pred->offset); \
type val = (type)pred->val; \
int match = (*addr >= val); \
return !!match == !pred->not; \
} \
static int filter_pred_BAND_##type(struct filter_pred *pred, void *event) \
{ \
type *addr = (type *)(event + pred->offset); \
type val = (type)pred->val; \
int match = !!(*addr & val); \
return match == !pred->not; \
} \
static const filter_pred_fn_t pred_funcs_##type[] = { \
filter_pred_LT_##type, \
filter_pred_LE_##type, \
filter_pred_GT_##type, \
filter_pred_GE_##type, \
filter_pred_BAND_##type, \
};
#define PRED_FUNC_START OP_LT
#define DEFINE_EQUALITY_PRED(size) \ #define DEFINE_EQUALITY_PRED(size) \
static int filter_pred_##size(struct filter_pred *pred, void *event) \ static int filter_pred_##size(struct filter_pred *pred, void *event) \
...@@ -982,33 +998,33 @@ static filter_pred_fn_t select_comparison_fn(int op, int field_size, ...@@ -982,33 +998,33 @@ static filter_pred_fn_t select_comparison_fn(int op, int field_size,
if (op == OP_EQ || op == OP_NE) if (op == OP_EQ || op == OP_NE)
fn = filter_pred_64; fn = filter_pred_64;
else if (field_is_signed) else if (field_is_signed)
fn = filter_pred_s64; fn = pred_funcs_s64[op - PRED_FUNC_START];
else else
fn = filter_pred_u64; fn = pred_funcs_u64[op - PRED_FUNC_START];
break; break;
case 4: case 4:
if (op == OP_EQ || op == OP_NE) if (op == OP_EQ || op == OP_NE)
fn = filter_pred_32; fn = filter_pred_32;
else if (field_is_signed) else if (field_is_signed)
fn = filter_pred_s32; fn = pred_funcs_s32[op - PRED_FUNC_START];
else else
fn = filter_pred_u32; fn = pred_funcs_u32[op - PRED_FUNC_START];
break; break;
case 2: case 2:
if (op == OP_EQ || op == OP_NE) if (op == OP_EQ || op == OP_NE)
fn = filter_pred_16; fn = filter_pred_16;
else if (field_is_signed) else if (field_is_signed)
fn = filter_pred_s16; fn = pred_funcs_s16[op - PRED_FUNC_START];
else else
fn = filter_pred_u16; fn = pred_funcs_u16[op - PRED_FUNC_START];
break; break;
case 1: case 1:
if (op == OP_EQ || op == OP_NE) if (op == OP_EQ || op == OP_NE)
fn = filter_pred_8; fn = filter_pred_8;
else if (field_is_signed) else if (field_is_signed)
fn = filter_pred_s8; fn = pred_funcs_s8[op - PRED_FUNC_START];
else else
fn = filter_pred_u8; fn = pred_funcs_u8[op - PRED_FUNC_START];
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