aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace.c1
-rw-r--r--kernel/trace/trace_events_hist.c20
2 files changed, 21 insertions, 0 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 4e342d354c12..988a35263fdd 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -3872,6 +3872,7 @@ static const char readme_msg[] =
3872 "\t .sym-offset display an address as a symbol and offset\n" 3872 "\t .sym-offset display an address as a symbol and offset\n"
3873 "\t .execname display a common_pid as a program name\n" 3873 "\t .execname display a common_pid as a program name\n"
3874 "\t .syscall display a syscall id as a syscall name\n\n" 3874 "\t .syscall display a syscall id as a syscall name\n\n"
3875 "\t .log2 display log2 value rather than raw number\n\n"
3875 "\t The 'pause' parameter can be used to pause an existing hist\n" 3876 "\t The 'pause' parameter can be used to pause an existing hist\n"
3876 "\t trigger or to start a hist trigger but not log any events\n" 3877 "\t trigger or to start a hist trigger but not log any events\n"
3877 "\t until told to do so. 'continue' can be used to start or\n" 3878 "\t until told to do so. 'continue' can be used to start or\n"
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
71static 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) \
72static u64 hist_field_##type(struct hist_field *hist_field, void *event)\ 79static 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
116struct hist_trigger_attrs { 124struct 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}