Skip to content

Commit 5819ead

Browse files
tzanussirostedt
authored andcommitted
tracing: Reimplement log2
log2 as currently implemented applies only to u64 trace_event_field derived fields, and assumes that anything it's applied to is a u64 field. To prepare for synthetic fields like latencies, log2 should be applicable to those as well, so take the opportunity now to fix the current problems as well as expand to more general uses. log2 should be thought of as a chaining function rather than a field type. To enable this as well as possible future function implementations, add a hist_field operand array into the hist_field definition for this purpose, and make use of it to implement the log2 'function'. Link: http://lkml.kernel.org/r/b47f93fc0b87b36eccf716b0c018f3a71e1f1111.1506105045.git.tom.zanussi@linux.intel.com Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
1 parent 8501325 commit 5819ead

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

kernel/trace/trace_events_hist.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,16 @@ struct hist_field;
2828

2929
typedef u64 (*hist_field_fn_t) (struct hist_field *field, void *event);
3030

31+
#define HIST_FIELD_OPERANDS_MAX 2
32+
3133
struct hist_field {
3234
struct ftrace_event_field *field;
3335
unsigned long flags;
3436
hist_field_fn_t fn;
3537
unsigned int size;
3638
unsigned int offset;
39+
unsigned int is_signed;
40+
struct hist_field *operands[HIST_FIELD_OPERANDS_MAX];
3741
};
3842

3943
static u64 hist_field_none(struct hist_field *field, void *event)
@@ -71,7 +75,9 @@ static u64 hist_field_pstring(struct hist_field *hist_field, void *event)
7175

7276
static u64 hist_field_log2(struct hist_field *hist_field, void *event)
7377
{
74-
u64 val = *(u64 *)(event + hist_field->field->offset);
78+
struct hist_field *operand = hist_field->operands[0];
79+
80+
u64 val = operand->fn(operand, event);
7581

7682
return (u64) ilog2(roundup_pow_of_two(val));
7783
}
@@ -156,6 +162,8 @@ static const char *hist_field_name(struct hist_field *field,
156162

157163
if (field->field)
158164
field_name = field->field->name;
165+
else if (field->flags & HIST_FIELD_FL_LOG2)
166+
field_name = hist_field_name(field->operands[0], ++level);
159167

160168
if (field_name == NULL)
161169
field_name = "";
@@ -357,8 +365,20 @@ static const struct tracing_map_ops hist_trigger_elt_comm_ops = {
357365
.elt_init = hist_trigger_elt_comm_init,
358366
};
359367

360-
static void destroy_hist_field(struct hist_field *hist_field)
368+
static void destroy_hist_field(struct hist_field *hist_field,
369+
unsigned int level)
361370
{
371+
unsigned int i;
372+
373+
if (level > 2)
374+
return;
375+
376+
if (!hist_field)
377+
return;
378+
379+
for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++)
380+
destroy_hist_field(hist_field->operands[i], level + 1);
381+
362382
kfree(hist_field);
363383
}
364384

@@ -385,7 +405,10 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field,
385405
}
386406

387407
if (flags & HIST_FIELD_FL_LOG2) {
408+
unsigned long fl = flags & ~HIST_FIELD_FL_LOG2;
388409
hist_field->fn = hist_field_log2;
410+
hist_field->operands[0] = create_hist_field(field, fl);
411+
hist_field->size = hist_field->operands[0]->size;
389412
goto out;
390413
}
391414

@@ -405,7 +428,7 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field,
405428
hist_field->fn = select_value_fn(field->size,
406429
field->is_signed);
407430
if (!hist_field->fn) {
408-
destroy_hist_field(hist_field);
431+
destroy_hist_field(hist_field, 0);
409432
return NULL;
410433
}
411434
}
@@ -422,7 +445,7 @@ static void destroy_hist_fields(struct hist_trigger_data *hist_data)
422445

423446
for (i = 0; i < TRACING_MAP_FIELDS_MAX; i++) {
424447
if (hist_data->fields[i]) {
425-
destroy_hist_field(hist_data->fields[i]);
448+
destroy_hist_field(hist_data->fields[i], 0);
426449
hist_data->fields[i] = NULL;
427450
}
428451
}

0 commit comments

Comments
 (0)