@@ -777,9 +777,17 @@ static void make_histogram(struct perf_ftrace *ftrace, int buckets[],
777777 if (ftrace -> use_nsec )
778778 num *= 1000 ;
779779
780- i = log2 (num );
781- if (i < 0 )
780+ if (!ftrace -> bucket_range ) {
781+ i = log2 (num );
782+ if (i < 0 )
783+ i = 0 ;
784+ } else {
785+ // Less than 1 unit (ms or ns), or, in the future,
786+ // than the min latency desired.
782787 i = 0 ;
788+ if (num > 0 ) // 1st entry: [ 1 unit .. bucket_range units ]
789+ i = num / ftrace -> bucket_range + 1 ;
790+ }
783791 if (i >= NUM_BUCKET )
784792 i = NUM_BUCKET - 1 ;
785793
@@ -815,28 +823,58 @@ static void display_histogram(struct perf_ftrace *ftrace, int buckets[])
815823 " DURATION " , "COUNT" , bar_total , "GRAPH" );
816824
817825 bar_len = buckets [0 ] * bar_total / total ;
818- printf (" %4d - %-4d %s | %10d | %.*s%*s |\n" ,
826+
827+ printf (" %4d - %4d %s | %10d | %.*s%*s |\n" ,
819828 0 , 1 , use_nsec ? "ns" : "us" , buckets [0 ], bar_len , bar , bar_total - bar_len , "" );
820829
821830 for (i = 1 ; i < NUM_BUCKET - 1 ; i ++ ) {
822- int start = (1 << (i - 1 ));
823- int stop = 1 << i ;
831+ int start , stop ;
824832 const char * unit = use_nsec ? "ns" : "us" ;
825833
826- if (start >= 1024 ) {
827- start >>= 10 ;
828- stop >>= 10 ;
829- unit = use_nsec ? "us" : "ms" ;
834+ if (!ftrace -> bucket_range ) {
835+ start = (1 << (i - 1 ));
836+ stop = 1 << i ;
837+
838+ if (start >= 1024 ) {
839+ start >>= 10 ;
840+ stop >>= 10 ;
841+ unit = use_nsec ? "us" : "ms" ;
842+ }
843+ } else {
844+ start = (i - 1 ) * ftrace -> bucket_range + 1 ;
845+ stop = i * ftrace -> bucket_range + 1 ;
846+
847+ if (start >= 1000 ) {
848+ double dstart = start / 1000.0 ,
849+ dstop = stop / 1000.0 ;
850+ printf (" %4.2f - %-4.2f" , dstart , dstop );
851+ unit = use_nsec ? "us" : "ms" ;
852+ goto print_bucket_info ;
853+ }
830854 }
855+
856+ printf (" %4d - %4d" , start , stop );
857+ print_bucket_info :
831858 bar_len = buckets [i ] * bar_total / total ;
832- printf (" %4d - %-4d %s | %10d | %.*s%*s |\n" ,
833- start , stop , unit , buckets [i ], bar_len , bar ,
859+ printf (" %s | %10d | %.*s%*s |\n" , unit , buckets [i ], bar_len , bar ,
834860 bar_total - bar_len , "" );
835861 }
836862
837863 bar_len = buckets [NUM_BUCKET - 1 ] * bar_total / total ;
838- printf (" %4d - %-4s %s | %10d | %.*s%*s |\n" ,
839- 1 , "..." , use_nsec ? "ms" : " s" , buckets [NUM_BUCKET - 1 ],
864+ if (!ftrace -> bucket_range ) {
865+ printf (" %4d - %-4s %s" , 1 , "..." , use_nsec ? "ms" : "s " );
866+ } else {
867+ int upper_outlier = (NUM_BUCKET - 2 ) * ftrace -> bucket_range ;
868+
869+ if (upper_outlier >= 1000 ) {
870+ double dstart = upper_outlier / 1000.0 ;
871+
872+ printf (" %4.2f - %-4s %s" , dstart , "..." , use_nsec ? "us" : "ms" );
873+ } else {
874+ printf (" %4d - %4s %s" , upper_outlier , "..." , use_nsec ? "ns" : "us" );
875+ }
876+ }
877+ printf (" | %10d | %.*s%*s |\n" , buckets [NUM_BUCKET - 1 ],
840878 bar_len , bar , bar_total - bar_len , "" );
841879
842880}
@@ -1558,6 +1596,8 @@ int cmd_ftrace(int argc, const char **argv)
15581596#endif
15591597 OPT_BOOLEAN ('n' , "use-nsec" , & ftrace .use_nsec ,
15601598 "Use nano-second histogram" ),
1599+ OPT_UINTEGER (0 , "bucket-range" , & ftrace .bucket_range ,
1600+ "Bucket range in ms or ns (-n/--use-nsec), default is log2() mode" ),
15611601 OPT_PARENT (common_options ),
15621602 };
15631603 const struct option profile_options [] = {
0 commit comments