diff options
Diffstat (limited to 'kernel/trace/trace_events_hist.c')
-rw-r--r-- | kernel/trace/trace_events_hist.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index bdea5603cbde..23df38aab503 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c | |||
@@ -68,6 +68,13 @@ static u64 hist_field_pstring(struct hist_field *hist_field, void *event) | |||
68 | return (u64)(unsigned long)*addr; | 68 | return (u64)(unsigned long)*addr; |
69 | } | 69 | } |
70 | 70 | ||
71 | static u64 hist_field_log2(struct hist_field *hist_field, void *event) | ||
72 | { | ||
73 | u64 val = *(u64 *)(event + hist_field->field->offset); | ||
74 | |||
75 | return (u64) ilog2(roundup_pow_of_two(val)); | ||
76 | } | ||
77 | |||
71 | #define DEFINE_HIST_FIELD_FN(type) \ | 78 | #define DEFINE_HIST_FIELD_FN(type) \ |
72 | static u64 hist_field_##type(struct hist_field *hist_field, void *event)\ | 79 | static u64 hist_field_##type(struct hist_field *hist_field, void *event)\ |
73 | { \ | 80 | { \ |
@@ -111,6 +118,7 @@ enum hist_field_flags { | |||
111 | HIST_FIELD_FL_EXECNAME = 64, | 118 | HIST_FIELD_FL_EXECNAME = 64, |
112 | HIST_FIELD_FL_SYSCALL = 128, | 119 | HIST_FIELD_FL_SYSCALL = 128, |
113 | HIST_FIELD_FL_STACKTRACE = 256, | 120 | HIST_FIELD_FL_STACKTRACE = 256, |
121 | HIST_FIELD_FL_LOG2 = 512, | ||
114 | }; | 122 | }; |
115 | 123 | ||
116 | struct hist_trigger_attrs { | 124 | struct hist_trigger_attrs { |
@@ -358,6 +366,11 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field, | |||
358 | goto out; | 366 | goto out; |
359 | } | 367 | } |
360 | 368 | ||
369 | if (flags & HIST_FIELD_FL_LOG2) { | ||
370 | hist_field->fn = hist_field_log2; | ||
371 | goto out; | ||
372 | } | ||
373 | |||
361 | if (is_string_field(field)) { | 374 | if (is_string_field(field)) { |
362 | flags |= HIST_FIELD_FL_STRING; | 375 | flags |= HIST_FIELD_FL_STRING; |
363 | 376 | ||
@@ -522,6 +535,8 @@ static int create_key_field(struct hist_trigger_data *hist_data, | |||
522 | flags |= HIST_FIELD_FL_EXECNAME; | 535 | flags |= HIST_FIELD_FL_EXECNAME; |
523 | else if (strcmp(field_str, "syscall") == 0) | 536 | else if (strcmp(field_str, "syscall") == 0) |
524 | flags |= HIST_FIELD_FL_SYSCALL; | 537 | flags |= HIST_FIELD_FL_SYSCALL; |
538 | else if (strcmp(field_str, "log2") == 0) | ||
539 | flags |= HIST_FIELD_FL_LOG2; | ||
525 | else { | 540 | else { |
526 | ret = -EINVAL; | 541 | ret = -EINVAL; |
527 | goto out; | 542 | goto out; |
@@ -980,6 +995,9 @@ hist_trigger_entry_print(struct seq_file *m, | |||
980 | key + key_field->offset, | 995 | key + key_field->offset, |
981 | HIST_STACKTRACE_DEPTH); | 996 | HIST_STACKTRACE_DEPTH); |
982 | multiline = true; | 997 | multiline = true; |
998 | } else if (key_field->flags & HIST_FIELD_FL_LOG2) { | ||
999 | seq_printf(m, "%s: ~ 2^%-2llu", key_field->field->name, | ||
1000 | *(u64 *)(key + key_field->offset)); | ||
983 | } else if (key_field->flags & HIST_FIELD_FL_STRING) { | 1001 | } else if (key_field->flags & HIST_FIELD_FL_STRING) { |
984 | seq_printf(m, "%s: %-50s", key_field->field->name, | 1002 | seq_printf(m, "%s: %-50s", key_field->field->name, |
985 | (char *)(key + key_field->offset)); | 1003 | (char *)(key + key_field->offset)); |
@@ -1112,6 +1130,8 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) | |||
1112 | flags_str = "execname"; | 1130 | flags_str = "execname"; |
1113 | else if (hist_field->flags & HIST_FIELD_FL_SYSCALL) | 1131 | else if (hist_field->flags & HIST_FIELD_FL_SYSCALL) |
1114 | flags_str = "syscall"; | 1132 | flags_str = "syscall"; |
1133 | else if (hist_field->flags & HIST_FIELD_FL_LOG2) | ||
1134 | flags_str = "log2"; | ||
1115 | 1135 | ||
1116 | return flags_str; | 1136 | return flags_str; |
1117 | } | 1137 | } |