diff --git a/Documentation/trace/histogram.rst b/Documentation/trace/histogram.rst index 340bcb5099e7..97b67f05f5ea 100644 --- a/Documentation/trace/histogram.rst +++ b/Documentation/trace/histogram.rst @@ -1943,6 +1943,9 @@ the ".buckets" modifier and specify a size (in this case groups of 10):: Entries: 16 Dropped: 0 +Keys are 64-bit, so the group holding the largest values is truncated where +that range ends and can be smaller than the size asked for. + To save stacktraces, create a synthetic event with a field of type "unsigned long[]" or even just "long[]". For example, to see how long a task is blocked in an uninterruptible state:: diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 972804709b14..c150e1130a5f 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -5561,9 +5561,14 @@ static void hist_trigger_print_key(struct seq_file *m, *(u64 *)(key + key_field->offset)); } else if (key_field->flags & HIST_FIELD_FL_BUCKET) { unsigned long buckets = key_field->buckets; + u64 end; + uval = *(u64 *)(key + key_field->offset); + end = uval + buckets - 1; + if (end < uval) + end = U64_MAX; seq_printf(m, "%s: ~ %llu-%llu", field_name, - uval, uval + buckets -1); + uval, end); } else if (key_field->flags & HIST_FIELD_FL_STRING) { seq_printf(m, "%s: %-50s", field_name, (char *)(key + key_field->offset));