perf tools: allow top users to switch between weighted and individual counter display
PATCH 1/1 perf tools: allow top users to switch between weighted and individual counter display
(depends on last resurrect annotation patch)
perf_counter tools: allow top users to switch between weighted and individual counter display.
Add [w]eighted hotkey. Pressing [w] toggles between displaying weighted total of all counters, and the counter selected via [E]vent select key.
------------------------------------------------------------------------------
PerfTop: 90395 irqs/sec kernel:16.1% [cache-misses/cache-references/instructions], (all, 4 CPUs)
------------------------------------------------------------------------------
weight samples pcnt RIP kernel function ______ _______ _____ ________________ _______________
1275408.6 10881 - 5.3% - ffffffff81146f70 : copy_page_c
553683.4 43569 - 21.3% - ffffffff81146f20 : clear_page_c
74075.0 6768 - 3.3% - ffffffff81147190 : copy_user_generic_string 40602.9 7538 - 3.7% - ffffffff81284ba2 : _spin_lock 26882.1 965 - 0.5% - ffffffff8109d280 : file_ra_state_init
[w]
------------------------------------------------------------------------------
PerfTop: 91221 irqs/sec kernel:14.5% [10000Hz cache-misses], (all, 4 CPUs)
------------------------------------------------------------------------------
weight samples pcnt RIP kernel function ______ _______ _____ ________________ _______________
47320.00 - 22.3% - ffffffff81146f20 : clear_page_c
14261.00 - 6.7% - ffffffff810992f5 : __rmqueue
11046.00 - 5.2% - ffffffff81146f70 : copy_page_c
7842.00 - 3.7% - ffffffff81284ba2 : _spin_lock
7234.00 - 3.4% - ffffffff810aa1d6 : unmap_vmasLKML-Reference: <new-submission>
--- tools/perf/builtin-top.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-)
tools/perf/builtin-top.c +17 -7
@@ -90,6 +90,7 @@ static char *sym_filter = NULL;struct sym_entry *sym_filter_entry =NULL ;static int sym_pcnt_filter =5 ;static int sym_counter =0 ; +static int display_weighted =-1 ;/* * Symbols
@@ -354,6 +355,9 @@ static double sym_weight(const struct sydouble weight = sym->snap_count;int counter; +if (!display_weighted) +return weight; +for (counter =1 ; counter < nr_counters-1 ; counter++) weight *= sym->count[counter];
@@ -401,7 +405,7 @@ static void rb_insert_active_sym(structstatic void print_sym_table (void ) {int printed =0 , j; -int counter; +int counter, snap = !display_weighted ? sym_counter :0 ;float samples_per_sec = samples/delay_secs;float ksamples_per_sec = (samples-userspace_samples)/delay_secs;float sum_ksamples =0.0 ;
@@ -417,7 +421,7 @@ static void print_sym_table(void)pthread_mutex_unlock (&active_symbols_lock);list_for_each_entry_safe_from (syme, n, &active_symbols, node) { - syme->snap_count = syme->count[0 ]; + syme->snap_count = syme->count[snap];if (syme->snap_count !=0 ) { syme->weight =sym_weight (syme);rb_insert_active_sym (&tmp, syme);
@@ -437,7 +441,7 @@ static void print_sym_table(void) samples_per_sec, 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec))); -if (nr_counters ==1 ) { +if (nr_counters ==1 || !display_weighted) {printf ("%Ld" , (u64 )attrs[0 ].sample_period);if (freq)printf ("Hz " );
@@ -445,7 +449,9 @@ static void print_sym_table(void)printf (" " ); } -for (counter =0 ; counter < nr_counters; counter++) { +if (!display_weighted) +printf ("%s" ,event_name (sym_counter)); +else for (counter =0 ; counter < nr_counters; counter++) {if (counter)printf ("/" );
@@ -495,7 +501,7 @@ static void print_sym_table(void) pcnt =100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / sum_ksamples)); -if (nr_counters ==1 ) +if (nr_counters ==1 || !display_weighted)printf ("%20.2f - " , syme->weight);else printf ("%9.1f %10ld - " , syme->weight, syme->snap_count);
@@ -601,13 +607,14 @@ static void print_known_keys(void)fprintf (stdout,"\nknown keys:\n" );fprintf (stdout,"\t[d] display refresh delay. \t(%d)\n" , delay_secs);fprintf (stdout,"\t[e] display entries (lines). \t(%d)\n" , print_entries); -fprintf (stdout,"\t[E] annotate event counter. \t(%s)\n" ,event_name (sym_counter)); +fprintf (stdout,"\t[E] active event counter. \t(%s)\n" ,event_name (sym_counter));fprintf (stdout,"\t[f] profile display filter (count). \t(%d)\n" , count_filter);fprintf (stdout,"\t[F] annotate display filter (percent). \t(%d%%)\n" , sym_pcnt_filter);fprintf (stdout,"\t[qQ] quit.\n" );fprintf (stdout,"\t[s] annotate symbol. \t(%s)\n" , name?:"NULL" );fprintf (stdout,"\t[S] stop annotation.\n" ); -fprintf (stdout,"\t[z] toggle count zeroing. \t(%d)\n" , zero ?1 :0 ); +fprintf (stdout,"\t[w] toggle display weighted/count[E]r. \t(%d)\n" , display_weighted ?1 :0 ); +fprintf (stdout,"\t[z] toggle sample zeroing. \t(%d)\n" , zero ?1 :0 ); }static void handle_keypress (int c)
@@ -663,6 +670,9 @@ repeat:pthread_mutex_unlock (&syme->source_lock); }break ; +case 'w' : + display_weighted = ~display_weighted; +break ;case 'z' : zero = ~zero;break ;
Quoted 6 lines · Mike Galbraith
(depends on last resurrect annotation patch)
perf_countertools: allow top users to switch between weighted and individual counter display.Add [w]eighted hotkey. Pressing [w] toggles between displaying weighted total of all counters, and the counter selected via [E]vent select key.
/me stuck it next to that other one, let see what happens ;-)
Thanks Mike.
Quoted 9 lines · Peter Zijlstra
Quoted 6 lines · Mike Galbraith
(depends on last resurrect annotation patch)
perf_countertools: allow top users to switch between weighted and individual counter display.Add [w]eighted hotkey. Pressing [w] toggles between displaying weighted total of all counters, and the counter selected via [E]vent select key.
/me stuck it next to that other one, let see what happens ;-)
(plugs in Bitwolf-9000 charger)
Quoted 4 lines · Mike Galbraith
Quoted 3 lines · Peter Zijlstra
Quoted 2 lines · Mike Galbraith
(depends on last resurrect annotation patch)
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
perf_countertools: allow top users to switch between weighted and individual counter display.Add [w]eighted hotkey. Pressing [w] toggles between displaying weighted total of all counters, and the counter selected via [E]vent select key.
/me stuck it next to that other one, let see what happens ;-)
(plugs in Bitwolf-9000 charger)
seems to work well here.
A few minor comments:
- I had to guess that '?' gets me a help screen. Might make sense to display a line at the bottom (?) to give some hints.
- Once i was on the help screen, i expected either <Enter> or '?' to make it vanish. Only setting an option got rid of it - i suspect this should be improved. (Also, a line in the help screen that tells us how to go back without changing anything would be helpful as well.)
- I randomly tried the 's' option to do annotation. But it didnt do anything. Probably because i didnt start perf top via --vmlinux, right? This behavior is not intuitive in any case - it should probably display an error message at minimum - but if possible it should try to guess the position of the vmlinux file.
Ingo
Quoted 19 lines · Ingo Molnar
Quoted 4 lines · Mike Galbraith
Quoted 3 lines · Peter Zijlstra
Quoted 2 lines · Mike Galbraith
(depends on last resurrect annotation patch)
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
perf_countertools: allow top users to switch between weighted and individual counter display.Add [w]eighted hotkey. Pressing [w] toggles between displaying weighted total of all counters, and the counter selected via [E]vent select key.
/me stuck it next to that other one, let see what happens ;-)
(plugs in Bitwolf-9000 charger)
seems to work well here.
A few minor comments:
Quoted 8 lines
- I had to guess that '?' gets me a help screen. Might make sense to display a line at the bottom (?) to give some hints.
- Once i was on the help screen, i expected either <Enter> or '?' to make it vanish. Only setting an option got rid of it - i suspect this should be improved. (Also, a line in the help screen that tells us how to go back without changing anything would be helpful as well.)
How about the below?
Quoted 5 lines
- I randomly tried the 's' option to do annotation. But it didnt do anything. Probably because i didnt start perf top via --vmlinux, right? This behavior is not intuitive in any case - it should probably display an error message at minimum - but if possible it should try to guess the position of the vmlinux file.
Guessing would require rebuilding symbols, and serialization for the data acquisition thread, maybe something to do when/if top is made fully interactive. In the below, I just show what keys are available with the provided command line options.
Not sure I like waiting for input at start though, maybe just display and sleep a couple seconds would be friendlier.
perf_counter tools: improve perf top interactive key handling.
Display mapped keys and wait for input on startup to ensure that the user knows which keys are available. Change keypress handling such that current vairable values are displayed, and pressing an unmapped key continues with variables unchanged.
LKML-Reference: <new-submission>
tools/perf/builtin-top.c | 109 +++++++++++++++++++++++++++++++--------------- 1 files changed, 74 insertions(+), 35 deletions(-)
tools/perf/builtin-top.c +74 -35
@@ -595,25 +595,84 @@ out_free:free (buf); } -static void print_known_keys (void ) +static void print_mapped_keys (void ) { -fprintf (stdout,"\nknown keys:\n" ); -fprintf (stdout,"\t[d] select display delay.\n" ); -fprintf (stdout,"\t[e] select display entries (lines).\n" ); -fprintf (stdout,"\t[E] active event counter. \t(%s)\n" ,event_name (sym_counter)); -fprintf (stdout,"\t[f] select normal display count filter.\n" ); -fprintf (stdout,"\t[F] select annotation display count filter (percentage).\n" ); -fprintf (stdout,"\t[qQ] quit.\n" ); -fprintf (stdout,"\t[s] select annotation symbol and start annotation.\n" ); -fprintf (stdout,"\t[S] stop annotation, revert to normal display.\n" ); -fprintf (stdout,"\t[w] toggle display weighted/count[E]r. \t(%d)\n" , display_weighted ?1 :0 ); +char *name =NULL ; + +if (sym_filter_entry) { +struct symbol *sym = (struct symbol *)(sym_filter_entry+1 ); + name = sym->name; + } + +fprintf (stdout,"\nMapped keys:\n" ); +fprintf (stdout,"\t[d] display refresh delay. \t(%d)\n" , delay_secs); +fprintf (stdout,"\t[e] display entries (lines). \t(%d)\n" , print_entries); + +if (nr_counters >1 ) +fprintf (stdout,"\t[E] active event counter. \t(%s)\n" ,event_name (sym_counter)); + +fprintf (stdout,"\t[f] profile display filter (count). \t(%d)\n" , count_filter); + +if (vmlinux) { +fprintf (stdout,"\t[F] annotate display filter (percent). \t(%d%%)\n" , sym_pcnt_filter); +fprintf (stdout,"\t[s] annotate symbol. \t(%s)\n" , name?:"NULL" ); +fprintf (stdout,"\t[S] stop annotation.\n" ); + } + +if (nr_counters >1 ) +fprintf (stdout,"\t[w] toggle display weighted/count[E]r. \t(%d)\n" , display_weighted ?1 :0 ); +fprintf (stdout,"\t[z] toggle sample zeroing. \t(%d)\n" , zero ?1 :0 ); +fprintf (stdout,"\t[qQ] quit.\n" ); +} + +static int key_mapped (int c) +{ +switch (c) { +case 'd' : +case 'e' : +case 'f' : +case 'z' : +case 'q' : +case 'Q' : +return 1 ; +case 'E' : +case 'w' : +return nr_counters >1 ?1 :0 ; +case 'F' : +case 's' : +case 'S' : +return vmlinux ?1 :0 ; + } + +return 0 ; }static void handle_keypress (int c) { -int once =0 ; -repeat: +if (!key_mapped (c)) { +struct pollfd stdin_poll = { .fd =0 , .events =POLLIN }; +struct termios tc, save; + +print_mapped_keys (); +fprintf (stdout,"\nEnter selection, or unmapped key to continue: " ); +fflush (stdout); + +tcgetattr (0 , &save); + tc = save; + tc.c_lflag &= ~(ICANON |ECHO ); + tc.c_cc[VMIN ] =0 ; + tc.c_cc[VTIME ] =0 ; +tcsetattr (0 ,TCSANOW , &tc); + +poll (&stdin_poll,1 ,-1 ); + c =getc (stdin); + +tcsetattr (0 ,TCSAFLUSH , &save); +if (!key_mapped (c)) +return ; + } +switch (c) {case 'd' :prompt_integer (&delay_secs,"Enter display delay" );
@@ -669,28 +728,6 @@ repeat:case 'z' : zero = ~zero;break ; -default : { -struct pollfd stdin_poll = { .fd =0 , .events =POLLIN }; -struct termios tc, save; - -if (!once) { -print_known_keys (); - once++; - } - -tcgetattr (0 , &save); - tc = save; - tc.c_lflag &= ~(ICANON |ECHO ); - tc.c_cc[VMIN ] =0 ; - tc.c_cc[VTIME ] =0 ; -tcsetattr (0 ,TCSANOW , &tc); - -poll (&stdin_poll,1 ,-1 ); - c =getc (stdin); - -tcsetattr (0 ,TCSAFLUSH , &save); - goto repeat; - } } }
@@ -705,6 +742,8 @@ static void *display_thread(void *arg __used) tc.c_lflag &= ~(ICANON |ECHO ); tc.c_cc[VMIN ] =0 ; tc.c_cc[VTIME ] =0 ; + +handle_keypress (0 ); repeat: delay_msecs = delay_secs *1000 ;tcsetattr (0 ,TCSANOW , &tc);
Quoted 2 lines · Mike Galbraith
Not sure I like waiting for input at start though, maybe just display and sleep a couple seconds would be friendlier.
I find both really annoying, so just go straight into displaying. That kind of usage information belongs in the man page. I've updated same to reflect the current implementation, and will submit separately.
perf_counter tools: improve perf top interactive key handling.
Pressing any key which is not currently mapped to functionality, based on startup command line options, displays currently mapped keys, and prompts for input. Pressing any unmapped key at the prompt returns the user to display mode with variables unchanged. eg, pressing ? <SPACE> <ESC> etc displays currently available keys, the value of the variable associated with that key, and prompts. Pressing same again aborts input.
LKML-Reference: <new-submission>
--- tools/perf/builtin-top.c | 108 +++++++++++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 35 deletions(-)
tools/perf/builtin-top.c +73 -35
@@ -595,25 +595,84 @@ out_free:free (buf); } -static void print_known_keys (void ) +static void print_mapped_keys (void ) { -fprintf (stdout,"\nknown keys:\n" ); -fprintf (stdout,"\t[d] select display delay.\n" ); -fprintf (stdout,"\t[e] select display entries (lines).\n" ); -fprintf (stdout,"\t[E] active event counter. \t(%s)\n" ,event_name (sym_counter)); -fprintf (stdout,"\t[f] select normal display count filter.\n" ); -fprintf (stdout,"\t[F] select annotation display count filter (percentage).\n" ); -fprintf (stdout,"\t[qQ] quit.\n" ); -fprintf (stdout,"\t[s] select annotation symbol and start annotation.\n" ); -fprintf (stdout,"\t[S] stop annotation, revert to normal display.\n" ); -fprintf (stdout,"\t[w] toggle display weighted/count[E]r. \t(%d)\n" , display_weighted ?1 :0 ); +char *name =NULL ; + +if (sym_filter_entry) { +struct symbol *sym = (struct symbol *)(sym_filter_entry+1 ); + name = sym->name; + } + +fprintf (stdout,"\nMapped keys:\n" ); +fprintf (stdout,"\t[d] display refresh delay. \t(%d)\n" , delay_secs); +fprintf (stdout,"\t[e] display entries (lines). \t(%d)\n" , print_entries); + +if (nr_counters >1 ) +fprintf (stdout,"\t[E] active event counter. \t(%s)\n" ,event_name (sym_counter)); + +fprintf (stdout,"\t[f] profile display filter (count). \t(%d)\n" , count_filter); + +if (vmlinux) { +fprintf (stdout,"\t[F] annotate display filter (percent). \t(%d%%)\n" , sym_pcnt_filter); +fprintf (stdout,"\t[s] annotate symbol. \t(%s)\n" , name?:"NULL" ); +fprintf (stdout,"\t[S] stop annotation.\n" ); + } + +if (nr_counters >1 ) +fprintf (stdout,"\t[w] toggle display weighted/count[E]r. \t(%d)\n" , display_weighted ?1 :0 ); +fprintf (stdout,"\t[z] toggle sample zeroing. \t(%d)\n" , zero ?1 :0 ); +fprintf (stdout,"\t[qQ] quit.\n" ); +} + +static int key_mapped (int c) +{ +switch (c) { +case 'd' : +case 'e' : +case 'f' : +case 'z' : +case 'q' : +case 'Q' : +return 1 ; +case 'E' : +case 'w' : +return nr_counters >1 ?1 :0 ; +case 'F' : +case 's' : +case 'S' : +return vmlinux ?1 :0 ; + } + +return 0 ; }static void handle_keypress (int c) { -int once =0 ; -repeat: +if (!key_mapped (c)) { +struct pollfd stdin_poll = { .fd =0 , .events =POLLIN }; +struct termios tc, save; + +print_mapped_keys (); +fprintf (stdout,"\nEnter selection, or unmapped key to continue: " ); +fflush (stdout); + +tcgetattr (0 , &save); + tc = save; + tc.c_lflag &= ~(ICANON |ECHO ); + tc.c_cc[VMIN ] =0 ; + tc.c_cc[VTIME ] =0 ; +tcsetattr (0 ,TCSANOW , &tc); + +poll (&stdin_poll,1 ,-1 ); + c =getc (stdin); + +tcsetattr (0 ,TCSAFLUSH , &save); +if (!key_mapped (c)) +return ; + } +switch (c) {case 'd' :prompt_integer (&delay_secs,"Enter display delay" );
@@ -669,28 +728,6 @@ repeat:case 'z' : zero = ~zero;break ; -default : { -struct pollfd stdin_poll = { .fd =0 , .events =POLLIN }; -struct termios tc, save; - -if (!once) { -print_known_keys (); - once++; - } - -tcgetattr (0 , &save); - tc = save; - tc.c_lflag &= ~(ICANON |ECHO ); - tc.c_cc[VMIN ] =0 ; - tc.c_cc[VTIME ] =0 ; -tcsetattr (0 ,TCSANOW , &tc); - -poll (&stdin_poll,1 ,-1 ); - c =getc (stdin); - -tcsetattr (0 ,TCSAFLUSH , &save); - goto repeat; - } } }
@@ -705,6 +742,7 @@ static void *display_thread(void *arg __ tc.c_lflag &= ~(ICANON |ECHO ); tc.c_cc[VMIN ] =0 ; tc.c_cc[VTIME ] =0 ; + repeat: delay_msecs = delay_secs *1000 ;tcsetattr (0 ,TCSANOW , &tc);
PATCH 1/1 perf tools: update perf top man page
perf_counter tools: update perf top manual page to reflect current implementation.
LKML-Reference: <new-submission>
--- tools/perf/Documentation/perf-top.txt | 112 ++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 13 deletions(-)
tools/perf/Documentation/perf-top.txt +99 -13
@@ -3,36 +3,122 @@ perf-top(1) NAME ---- -perf-top - Run a command and profile it +perf-top - System profiling tool. SYNOPSIS -------- [verse] -'perf top' [-e <EVENT> | --event=EVENT] [-l] [-a] <command> +'perf top' [-e <EVENT> | --event=EVENT] [<options>] DESCRIPTION ----------- -This command runs a command and gathers a performance counter profile -from it. +This command generates and displays a performance counter profile in realtime. OPTIONS ------- -<command>...:: - Any command you can specify in a shell. +-a:: +--all-cpus:: + System-wide collection. (default) + +-c <count>:: +--count=<count>:: + Event period to sample. + +-C <cpu>:: +--CPU=<cpu>:: + CPU to profile. + +-d <seconds>:: +--delay=<seconds>:: + Number of seconds to delay between refreshes. --e:: ---event=:: +-e <event>:: +--event=<event>:: Select the PMU event. Selection can be a symbolic event name (use 'perf list' to list all events) or a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a - hexadecimal event descriptor. + hexadecimal event descriptor. --a:: - system-wide collection +-E <entries>:: +--entries=<entries>:: + Display this many functions. + +-f <count>:: +--count-filter=<count>:: + Only display functions with more events than this. + +-F <freq>:: +--freq=<freq>:: + Profile at this frequency. + +-i:: +--inherit:: + Child tasks inherit counters, only makes sens with -p option. + +-k <path>:: +--vmlinux=<path>:: + Path to vmlinux. Required for annotation functionality. + +-m <pages>:: +--mmap-pages=<pages>:: + Number of mmapped data pages. + +-p <pid>:: +--pid=<pid>:: + Profile events on existing pid. + +-r <priority>:: +--realtime=<priority>:: + Collect data with this RT SCHED_FIFO priority. + +-s <symbol>:: +--sym-annotate=<symbol>:: + Annotate this symbol. Requires -k option. + +-v:: +--verbose:: + Be more verbose (show counter open errors, etc). + +-z:: +--zero:: + Zero history across display updates. + +INTERACTIVE PROMPTING KEYS +-------------------------- + +[d]:: + Display refresh delay. + +[e]:: + Number of entries to display. + +[E]:: + Event to display when multiple counters are active. + +[f]:: + Profile display filter (>= hit count). + +[F]:: + Annotation display filter (>= % of total). + +[s]:: + Annotate symbol. + +[S]:: + Stop annotation, return to full profile display. + +[w]:: + Toggle between weighted sum and individual count[E]r profile. + +[z]:: + Toggle event count zeroing across display updates. + +[qQ]:: + Quit. + +Pressing any unmapped key displays a menu, and prompts for input. --l:: - scale counter values SEE ALSO --------
[tip:perfcounters/core] perf top: Update man page
Commit-ID: 2a7c07f3ba0bb1234ef787134c81a9a4a2319aa9 Gitweb: http://git.kernel.org/tip/2a7c07f3ba0bb1234ef787134c81a9a4a2319aa9 Author: Mike Galbraith <[email protected]> AuthorDate: Tue, 4 Aug 2009 10:24:41 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 4 Aug 2009 10:35:19 +0200
perf top: Update man page
perf_counter tools: update perf top manual page to reflect current implementation.
LKML-Reference: <[email protected]>
LKML-Reference: <new-submission>
--- tools/perf/Documentation/perf-top.txt | 112 +++++++++++++++++++++++++++++---- 1 files changed, 99 insertions(+), 13 deletions(-)
tools/perf/Documentation/perf-top.txt +99 -13
@@ -3,36 +3,122 @@ perf-top(1) NAME ---- -perf-top - Run a command and profile it +perf-top - System profiling tool. SYNOPSIS -------- [verse] -'perf top' [-e <EVENT> | --event=EVENT] [-l] [-a] <command> +'perf top' [-e <EVENT> | --event=EVENT] [<options>] DESCRIPTION ----------- -This command runs a command and gathers a performance counter profile -from it. +This command generates and displays a performance counter profile in realtime. OPTIONS ------- -<command>...:: - Any command you can specify in a shell. +-a:: +--all-cpus:: + System-wide collection. (default) + +-c <count>:: +--count=<count>:: + Event period to sample. + +-C <cpu>:: +--CPU=<cpu>:: + CPU to profile. + +-d <seconds>:: +--delay=<seconds>:: + Number of seconds to delay between refreshes. --e:: ---event=:: +-e <event>:: +--event=<event>:: Select the PMU event. Selection can be a symbolic event name (use 'perf list' to list all events) or a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a - hexadecimal event descriptor. + hexadecimal event descriptor. --a:: - system-wide collection +-E <entries>:: +--entries=<entries>:: + Display this many functions. + +-f <count>:: +--count-filter=<count>:: + Only display functions with more events than this. + +-F <freq>:: +--freq=<freq>:: + Profile at this frequency. + +-i:: +--inherit:: + Child tasks inherit counters, only makes sens with -p option. + +-k <path>:: +--vmlinux=<path>:: + Path to vmlinux. Required for annotation functionality. + +-m <pages>:: +--mmap-pages=<pages>:: + Number of mmapped data pages. + +-p <pid>:: +--pid=<pid>:: + Profile events on existing pid. + +-r <priority>:: +--realtime=<priority>:: + Collect data with this RT SCHED_FIFO priority. + +-s <symbol>:: +--sym-annotate=<symbol>:: + Annotate this symbol. Requires -k option. + +-v:: +--verbose:: + Be more verbose (show counter open errors, etc). + +-z:: +--zero:: + Zero history across display updates. + +INTERACTIVE PROMPTING KEYS +-------------------------- + +[d]:: + Display refresh delay. + +[e]:: + Number of entries to display. + +[E]:: + Event to display when multiple counters are active. + +[f]:: + Profile display filter (>= hit count). + +[F]:: + Annotation display filter (>= % of total). + +[s]:: + Annotate symbol. + +[S]:: + Stop annotation, return to full profile display. + +[w]:: + Toggle between weighted sum and individual count[E]r profile. + +[z]:: + Toggle event count zeroing across display updates. + +[qQ]:: + Quit. + +Pressing any unmapped key displays a menu, and prompts for input. --l:: - scale counter values SEE ALSO --------
Quoted 9 lines · Mike Galbraith
Quoted 2 lines · Mike Galbraith
Not sure I like waiting for input at start though, maybe just display and sleep a couple seconds would be friendlier.
I find both really annoying, so just go straight into displaying. That kind of usage information belongs in the man page. I've updated same to reflect the current implementation, and will submit separately.
yeah - will apply both patches, thanks Mike.
I'm wondering, have you seen the 'tig' tool before? It puts the console into raw mode too and has a rather pleasant text interface. Since it's a relatively young project it might have a compact code base that could be imported (assuming the license is compatible and assuming what i say is true - have not checked yet).
Ingo
Quoted 7 lines · Ingo Molnar
Quoted 5 lines · Mike Galbraith
Quoted 2 lines · Mike Galbraith
Not sure I like waiting for input at start though, maybe just display and sleep a couple seconds would be friendlier.
Quoted 6 lines
Quoted 4 lines
I find both really annoying, so just go straight into displaying. That kind of usage information belongs in the man page. I've updated same to reflect the current implementation, and will submit separately.
yeah - will apply both patches, thanks Mike.
Thanks.
Quoted 5 lines
I'm wondering, have you seen the 'tig' tool before? It puts the console into raw mode too and has a rather pleasant text interface. Since it's a relatively young project it might have a compact code base that could be imported (assuming the license is compatible and assuming what i say is true - have not checked yet).
No, I haven't. I'll take a look (time time time) though, because I'd like to make top fully interactive, and my code is... um er, somewhat crude :)
-Mike
Quoted 23 lines · Mike Galbraith
Quoted 7 lines · Ingo Molnar
Quoted 5 lines · Mike Galbraith
Quoted 2 lines · Mike Galbraith
Not sure I like waiting for input at start though, maybe just display and sleep a couple seconds would be friendlier.
Quoted 6 lines
Quoted 4 lines
I find both really annoying, so just go straight into displaying. That kind of usage information belongs in the man page. I've updated same to reflect the current implementation, and will submit separately.
yeah - will apply both patches, thanks Mike.
Thanks.
Quoted 5 lines
I'm wondering, have you seen the 'tig' tool before? It puts the console into raw mode too and has a rather pleasant text interface. Since it's a relatively young project it might have a compact code base that could be imported (assuming the license is compatible and assuming what i say is true - have not checked yet).
Quoted 3 lines
No, I haven't. I'll take a look (time time time) though, because I'd like to make top fully interactive, and my code is... um er, somewhat crude :)
it's at:
git clone http://jonas.nitro.dk/tig/tig.git
7 KLOC and clean looking. Code seems quite readable and in standard Git style - i.e. kernel and tools/perf/ compatible. License is GPLv2 or later - i.e. that too is kernel compatible.
The tig.c is a bit large at 7000+ lines, but it looks easily split. It uses libcurses for console handling.
Looks like a pretty good starting point IMO.
Ingo
[tip:perfcounters/core] perf top: Improve interactive key handling
In reply to Mike GalbraithCommit-ID: 0aafe6d2af76ea03501683d7d972edd0018878be Gitweb: http://git.kernel.org/tip/0aafe6d2af76ea03501683d7d972edd0018878be Author: Mike Galbraith <[email protected]> AuthorDate: Tue, 4 Aug 2009 10:21:23 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 4 Aug 2009 10:35:18 +0200
perf top: Improve interactive key handling
Pressing any key which is not currently mapped to functionality, based on startup command line options, displays currently mapped keys, and prompts for input.
Pressing any unmapped key at the prompt returns the user to display mode with variables unchanged. eg, pressing ? <SPACE> <ESC> etc displays currently available keys, the value of the variable associated with that key, and prompts.
Pressing same again aborts input.
LKML-Reference: <[email protected]>
--- tools/perf/builtin-top.c | 108 +++++++++++++++++++++++++++++++--------------- 1 files changed, 73 insertions(+), 35 deletions(-)
tools/perf/builtin-top.c +73 -35
@@ -595,25 +595,84 @@ out_free:free (buf); } -static void print_known_keys (void ) +static void print_mapped_keys (void ) { -fprintf (stdout,"\nknown keys:\n" ); -fprintf (stdout,"\t[d] select display delay.\n" ); -fprintf (stdout,"\t[e] select display entries (lines).\n" ); -fprintf (stdout,"\t[E] active event counter. \t(%s)\n" ,event_name (sym_counter)); -fprintf (stdout,"\t[f] select normal display count filter.\n" ); -fprintf (stdout,"\t[F] select annotation display count filter (percentage).\n" ); -fprintf (stdout,"\t[qQ] quit.\n" ); -fprintf (stdout,"\t[s] select annotation symbol and start annotation.\n" ); -fprintf (stdout,"\t[S] stop annotation, revert to normal display.\n" ); -fprintf (stdout,"\t[w] toggle display weighted/count[E]r. \t(%d)\n" , display_weighted ?1 :0 ); +char *name =NULL ; + +if (sym_filter_entry) { +struct symbol *sym = (struct symbol *)(sym_filter_entry+1 ); + name = sym->name; + } + +fprintf (stdout,"\nMapped keys:\n" ); +fprintf (stdout,"\t[d] display refresh delay. \t(%d)\n" , delay_secs); +fprintf (stdout,"\t[e] display entries (lines). \t(%d)\n" , print_entries); + +if (nr_counters >1 ) +fprintf (stdout,"\t[E] active event counter. \t(%s)\n" ,event_name (sym_counter)); + +fprintf (stdout,"\t[f] profile display filter (count). \t(%d)\n" , count_filter); + +if (vmlinux) { +fprintf (stdout,"\t[F] annotate display filter (percent). \t(%d%%)\n" , sym_pcnt_filter); +fprintf (stdout,"\t[s] annotate symbol. \t(%s)\n" , name?:"NULL" ); +fprintf (stdout,"\t[S] stop annotation.\n" ); + } + +if (nr_counters >1 ) +fprintf (stdout,"\t[w] toggle display weighted/count[E]r. \t(%d)\n" , display_weighted ?1 :0 ); +fprintf (stdout,"\t[z] toggle sample zeroing. \t(%d)\n" , zero ?1 :0 ); +fprintf (stdout,"\t[qQ] quit.\n" ); +} + +static int key_mapped (int c) +{ +switch (c) { +case 'd' : +case 'e' : +case 'f' : +case 'z' : +case 'q' : +case 'Q' : +return 1 ; +case 'E' : +case 'w' : +return nr_counters >1 ?1 :0 ; +case 'F' : +case 's' : +case 'S' : +return vmlinux ?1 :0 ; + } + +return 0 ; }static void handle_keypress (int c) { -int once =0 ; -repeat: +if (!key_mapped (c)) { +struct pollfd stdin_poll = { .fd =0 , .events =POLLIN }; +struct termios tc, save; + +print_mapped_keys (); +fprintf (stdout,"\nEnter selection, or unmapped key to continue: " ); +fflush (stdout); + +tcgetattr (0 , &save); + tc = save; + tc.c_lflag &= ~(ICANON |ECHO ); + tc.c_cc[VMIN ] =0 ; + tc.c_cc[VTIME ] =0 ; +tcsetattr (0 ,TCSANOW , &tc); + +poll (&stdin_poll,1 ,-1 ); + c =getc (stdin); + +tcsetattr (0 ,TCSAFLUSH , &save); +if (!key_mapped (c)) +return ; + } +switch (c) {case 'd' :prompt_integer (&delay_secs,"Enter display delay" );
@@ -669,28 +728,6 @@ repeat:case 'z' : zero = ~zero;break ; -default : { -struct pollfd stdin_poll = { .fd =0 , .events =POLLIN }; -struct termios tc, save; - -if (!once) { -print_known_keys (); - once++; - } - -tcgetattr (0 , &save); - tc = save; - tc.c_lflag &= ~(ICANON |ECHO ); - tc.c_cc[VMIN ] =0 ; - tc.c_cc[VTIME ] =0 ; -tcsetattr (0 ,TCSANOW , &tc); - -poll (&stdin_poll,1 ,-1 ); - c =getc (stdin); - -tcsetattr (0 ,TCSAFLUSH , &save); - goto repeat; - } } }
@@ -705,6 +742,7 @@ static void *display_thread(void *arg __used) tc.c_lflag &= ~(ICANON |ECHO ); tc.c_cc[VMIN ] =0 ; tc.c_cc[VTIME ] =0 ; + repeat: delay_msecs = delay_secs *1000 ;tcsetattr (0 ,TCSANOW , &tc);
[tip:perfcounters/core] perf_counter tools: Allow top users to switch between weighted and individual counter display
In reply to Mike GalbraithCommit-ID: 5cb1a23a1019ce4a4b2596ba53ebb86536680d02 Gitweb: http://git.kernel.org/tip/5cb1a23a1019ce4a4b2596ba53ebb86536680d02 Author: Mike Galbraith <[email protected]> AuthorDate: Fri, 24 Jul 2009 10:09:50 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 2 Aug 2009 14:01:43 +0200
perf_counter tools: Allow top users to switch between weighted and individual counter display
Add [w]eighted hotkey. Pressing [w] toggles between displaying weighted total of all counters, and the counter selected via [E]vent select key.
------------------------------------------------------------------------------
PerfTop: 90395 irqs/sec kernel:16.1% [cache-misses/cache-references/instructions], (all, 4 CPUs)
------------------------------------------------------------------------------
weight samples pcnt RIP kernel function ______ _______ _____ ________________ _______________
1275408.6 10881 - 5.3% - ffffffff81146f70 : copy_page_c
553683.4 43569 - 21.3% - ffffffff81146f20 : clear_page_c
74075.0 6768 - 3.3% - ffffffff81147190 : copy_user_generic_string 40602.9 7538 - 3.7% - ffffffff81284ba2 : _spin_lock 26882.1 965 - 0.5% - ffffffff8109d280 : file_ra_state_init
[w]
------------------------------------------------------------------------------
PerfTop: 91221 irqs/sec kernel:14.5% [10000Hz cache-misses], (all, 4 CPUs)
------------------------------------------------------------------------------
weight samples pcnt RIP kernel function ______ _______ _____ ________________ _______________
47320.00 - 22.3% - ffffffff81146f20 : clear_page_c
14261.00 - 6.7% - ffffffff810992f5 : __rmqueue
11046.00 - 5.2% - ffffffff81146f70 : copy_page_c
7842.00 - 3.7% - ffffffff81284ba2 : _spin_lock
7234.00 - 3.4% - ffffffff810aa1d6 : unmap_vmasLKML-Reference: <[email protected]>
--- tools/perf/builtin-top.c | 24 +++++++++++++++++------- 1 files changed, 17 insertions(+), 7 deletions(-)
tools/perf/builtin-top.c +17 -7
@@ -90,6 +90,7 @@ static char *sym_filter = NULL;struct sym_entry *sym_filter_entry =NULL ;static int sym_pcnt_filter =5 ;static int sym_counter =0 ; +static int display_weighted =-1 ;/* * Symbols
@@ -354,6 +355,9 @@ static double sym_weight(const struct sym_entry *sym)double weight = sym->snap_count;int counter; +if (!display_weighted) +return weight; +for (counter =1 ; counter < nr_counters-1 ; counter++) weight *= sym->count[counter];
@@ -401,7 +405,7 @@ static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se)static void print_sym_table (void ) {int printed =0 , j; -int counter; +int counter, snap = !display_weighted ? sym_counter :0 ;float samples_per_sec = samples/delay_secs;float ksamples_per_sec = (samples-userspace_samples)/delay_secs;float sum_ksamples =0.0 ;
@@ -417,7 +421,7 @@ static void print_sym_table(void)pthread_mutex_unlock (&active_symbols_lock);list_for_each_entry_safe_from (syme, n, &active_symbols, node) { - syme->snap_count = syme->count[0 ]; + syme->snap_count = syme->count[snap];if (syme->snap_count !=0 ) { syme->weight =sym_weight (syme);rb_insert_active_sym (&tmp, syme);
@@ -437,7 +441,7 @@ static void print_sym_table(void) samples_per_sec, 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec))); -if (nr_counters ==1 ) { +if (nr_counters ==1 || !display_weighted) {printf ("%Ld" , (u64 )attrs[0 ].sample_period);if (freq)printf ("Hz " );
@@ -445,7 +449,9 @@ static void print_sym_table(void)printf (" " ); } -for (counter =0 ; counter < nr_counters; counter++) { +if (!display_weighted) +printf ("%s" ,event_name (sym_counter)); +else for (counter =0 ; counter < nr_counters; counter++) {if (counter)printf ("/" );
@@ -495,7 +501,7 @@ static void print_sym_table(void) pcnt =100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / sum_ksamples)); -if (nr_counters ==1 ) +if (nr_counters ==1 || !display_weighted)printf ("%20.2f - " , syme->weight);else printf ("%9.1f %10ld - " , syme->weight, syme->snap_count);
@@ -594,13 +600,14 @@ static void print_known_keys(void)fprintf (stdout,"\nknown keys:\n" );fprintf (stdout,"\t[d] select display delay.\n" );fprintf (stdout,"\t[e] select display entries (lines).\n" ); -fprintf (stdout,"\t[E] select annotation event counter.\n" ); +fprintf (stdout,"\t[E] active event counter. \t(%s)\n" ,event_name (sym_counter));fprintf (stdout,"\t[f] select normal display count filter.\n" );fprintf (stdout,"\t[F] select annotation display count filter (percentage).\n" );fprintf (stdout,"\t[qQ] quit.\n" );fprintf (stdout,"\t[s] select annotation symbol and start annotation.\n" );fprintf (stdout,"\t[S] stop annotation, revert to normal display.\n" ); -fprintf (stdout,"\t[z] toggle event count zeroing.\n" ); +fprintf (stdout,"\t[w] toggle display weighted/count[E]r. \t(%d)\n" , display_weighted ?1 :0 ); +fprintf (stdout,"\t[z] toggle sample zeroing. \t(%d)\n" , zero ?1 :0 ); }static void handle_keypress (int c)
@@ -656,6 +663,9 @@ repeat:pthread_mutex_unlock (&syme->source_lock); }break ; +case 'w' : + display_weighted = ~display_weighted; +break ;case 'z' : zero = ~zero;break ;