perf/core improvements and fixes
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit af924aa35129edf338ebc8da6a4eae08cf7cb297:
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2014-08-18 10:14:43 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo
for you to fetch changes up to 141da74d2eff8de134c5a5ffaf2800a8a1b27517:
perf hists browser: Consolidate callchain print functions in TUI (2014-08-22 13:12:15 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
User visible:
o Don't try to find DSOs in SYSV maps (Don Zickus)
o Fallback to MAP__FUNCTION if daddr maps are NULL, i.e. addresses get looked upon more maps (Don Zickus)
o Kernel fix to properly handle exited tasks, by returning POLLHUP values on perf event file descriptors. Tooling changes will come next, but were tested with this kernel fix. (Jiri Olsa)
o Add +field argument support for --field option, so that one can add fields to the default list of fields to show, i.e. now one can just do:
perf report --fields +pid
And the pid will appear in addition to the default fields. (Jiri Olsa)
Developer stuff:
o More Intel PT prep stuff, including:
- Add a 'perf test' for tracking with sched_switch
- Add 'flush' callback to scripting API
o hists browser (used in top and report) refactorings, getting rid of unused variables and reducing source code size by handling similar cases in a fewer functions (Namhyung Kim).
o Explicitly include util/debug.h for powerpc, was being indirectly included, broke the build when some change made it stop being included. (Sukadev Bhattiprolu)
----------------------------------------------------------------
Adrian Hunter (4):
perf tests: Add a test for tracking with sched_switch perf scripting: Add 'flush' callback to scripting API perf machine: Rename machine__get_kernel_start_addr() method perf tools: Add machine__kernel_ip()
Don Zickus (2):
perf symbols: Don't try to find DSOs in SYSV maps perf machine: Fallback to MAP__FUNCTION if daddr maps are NULL
Jiri Olsa (4):
perf: Fix perf_poll to return proper POLLHUP value
perf: Add PERF_EVENT_STATE_EXIT state for events with exited task perf top: Use set_term_quiet() instead of open coded equivalent perf tools: Add +field argument support for --field option
Namhyung Kim (5):
perf hists browser: Get rid of unused 'remaining' variable perf hists browser: Fix children overhead dump
perf hists browser: Factor out hist_browser__show_callchain_entry() perf hists browser: Cleanup callchain print functions perf hists browser: Consolidate callchain print functions in TUI
Sukadev Bhattiprolu (1):
perf tools powerpc: Explicitly include util/debug.h
include/linux/perf_event.h | 1 + kernel/events/core.c | 12 +- tools/perf/Makefile.perf | 1 + tools/perf/arch/powerpc/util/skip-callchain-idx.c | 1 + tools/perf/builtin-script.c | 13 + tools/perf/builtin-top.c | 9 +- tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/switch-tracking.c | 572 +++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/ui/browsers/hists.c | 343 +++++------- tools/perf/ui/hist.c | 6 +- tools/perf/util/event.c | 6 +- tools/perf/util/machine.c | 41 +- tools/perf/util/machine.h | 17 + tools/perf/util/map.c | 1 + .../perf/util/scripting-engines/trace-event-perl.c | 6 + .../util/scripting-engines/trace-event-python.c | 6 + tools/perf/util/sort.c | 24 +- tools/perf/util/sort.h | 1 + tools/perf/util/trace-event-scripting.c | 7 + tools/perf/util/trace-event.h | 1 + 21 files changed, 827 insertions(+), 246 deletions(-) create mode 100644 tools/perf/tests/switch-tracking.c
Arnaldo Carvalho de Melo
maintainerPATCH 1/16 perf symbols: Don't try to find DSOs in SYSV maps
From: Don Zickus <[email protected]>
We are seeing a lot of the following with regards to SYSV memory
Failed to open /SYSV0000279c, continuing without symbols
We don't believe this memory will have DSO info, so treat it like the heap and stack for now and skip it to prevent the warning.
--- tools/perf/util/map.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/util/map.c +1 -0
@@ -31,6 +31,7 @@ static inline int is_anon_memory(const char *filename)static inline int is_no_dso_memory (const char *filename) {return !strncmp (filename,"[stack" ,6 ) || + !strncmp (filename,"/SYSV" ,5 ) || !strcmp (filename,"[heap]" ); }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 2/16 perf tools powerpc: Explicitly include util/debug.h
In reply to Arnaldo Carvalho de MeloFrom: Sukadev Bhattiprolu <[email protected]>
Looks like util/debug.h was indirectly included before and is no longer included now. pr_debug is left undefined and the build of perf tool fails on Powerpc.
Explicitly include util/debug.h.
--- tools/perf/arch/powerpc/util/skip-callchain-idx.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/arch/powerpc/util/skip-callchain-idx.c +1 -0
@@ -15,6 +15,7 @@#include "util/thread.h" #include "util/callchain.h" +#include "util/debug.h" /* * When saving the callchain on Power, the kernel conservatively saves
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 3/16 perf hists browser: Get rid of unused 'remaining' variable
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
It seems that the 'remaining' variable is not used by any real code.
--- tools/perf/ui/browsers/hists.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
tools/perf/ui/browsers/hists.c +2 -8
@@ -488,14 +488,13 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse {struct rb_node *node;int first_row = row, width, offset = level *LEVEL_OFFSET_STEP ; -u64 new_total, remaining; +u64 new_total;if (callchain_param.mode ==CHAIN_GRAPH_REL ) new_total = chain_node->children_hit;else new_total = total; - remaining = new_total; node =rb_first (&chain_node->rb_root);while (node) { struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
@@ -506,8 +505,6 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browseint first = true;int extra_offset =0 ; - remaining -= cumul; -list_for_each_entry (chain, &child->val, list) {char bf[1024 ], *alloc_str;const char *str;
@@ -1084,7 +1081,7 @@ static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *bro {struct rb_node *node;int offset = level *LEVEL_OFFSET_STEP ; -u64 new_total, remaining; +u64 new_total;int printed =0 ;if (callchain_param.mode ==CHAIN_GRAPH_REL )
@@ -1092,7 +1089,6 @@ static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *broelse new_total = total; - remaining = new_total; node =rb_first (&chain_node->rb_root);while (node) { struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
@@ -1103,8 +1099,6 @@ static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *broint first = true;int extra_offset =0 ; - remaining -= cumul; -list_for_each_entry (chain, &child->val, list) {char bf[1024 ], *alloc_str;const char *str;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 4/16 perf hists browser: Fix children overhead dump
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
When perf report runs on TUI, 'P' key dumps current screen to a file but it incorrectly displayed children overhead (as same of self overhead). This was because it fetched the value from self stats.
--- tools/perf/ui/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/ui/hist.c +1 -1
@@ -304,7 +304,7 @@ static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \struct perf_hpp *hpp,struct hist_entry *he) \ { \ - return hpp__fmt_acc(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ + return hpp__fmt_acc(fmt, hpp, he, he_get_acc_##_field, " %*.2f%%", \ hpp_entry_scnprintf, true); \ }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 5/16 perf hists browser: Factor out hist_browser__show_callchain_entry()
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Factor out duplicate callchain printing code into the hist_browser__ show_callchain_entry().
--- tools/perf/ui/browsers/hists.c | 64 ++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 31 deletions(-)
tools/perf/ui/browsers/hists.c +33 -31
@@ -477,6 +477,29 @@ static char *callchain_list__sym_name(struct callchain_list *cl,return bf; } +static void hist_browser__show_callchain_entry (struct hist_browser *browser, +struct callchain_list *chain, +unsigned short row,int offset, +char folded_sign,const char *str, +bool *is_current_entry) +{ +int color, width; + + color =HE_COLORSET_NORMAL ; + width = browser->b.width - (offset +2 ); +if (ui_browser__is_current_entry (&browser->b, row)) { + browser->selection = &chain->ms; + color =HE_COLORSET_SELECTED ; + *is_current_entry = true; + } + +ui_browser__set_color (&browser->b, color); +hist_browser__gotorc (browser, row,0 ); +slsmg_write_nstring (" " , offset); +slsmg_printf ("%c " , folded_sign); +slsmg_write_nstring (str, width); +} +#define LEVEL_OFFSET_STEP 3 static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browser,
@@ -487,7 +510,7 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse bool *is_current_entry) {struct rb_node *node; -int first_row = row, width, offset = level *LEVEL_OFFSET_STEP ; +int first_row = row, offset = level *LEVEL_OFFSET_STEP ;u64 new_total;if (callchain_param.mode ==CHAIN_GRAPH_REL )
@@ -508,7 +531,6 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browselist_for_each_entry (chain, &child->val, list) {char bf[1024 ], *alloc_str;const char *str; -int color;bool was_first = first;if (first)
@@ -534,19 +556,10 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse str = alloc_str; } - color =HE_COLORSET_NORMAL ; - width = browser->b.width - (offset + extra_offset +2 ); -if (ui_browser__is_current_entry (&browser->b, row)) { - browser->selection = &chain->ms; - color =HE_COLORSET_SELECTED ; - *is_current_entry = true; - } - -ui_browser__set_color (&browser->b, color); -hist_browser__gotorc (browser, row,0 ); -slsmg_write_nstring (" " , offset + extra_offset); -slsmg_printf ("%c " , folded_sign); -slsmg_write_nstring (str, width); +hist_browser__show_callchain_entry (browser, chain, row, + offset + extra_offset, + folded_sign, str, + is_current_entry);free (alloc_str);if (++row == browser->b.rows)
@@ -577,14 +590,12 @@ static int hist_browser__show_callchain_node(struct hist_browser *browser, bool *is_current_entry) {struct callchain_list *chain; -int first_row = row, - offset = level *LEVEL_OFFSET_STEP , - width = browser->b.width - offset; +int first_row = row; +int offset = level *LEVEL_OFFSET_STEP ;char folded_sign =' ' ;list_for_each_entry (chain, &node->val, list) {char bf[1024 ], *s; -int color; folded_sign =callchain_list__folded (chain);
@@ -593,20 +604,11 @@ static int hist_browser__show_callchain_node(struct hist_browser *browser,continue ; } - color =HE_COLORSET_NORMAL ; -if (ui_browser__is_current_entry (&browser->b, row)) { - browser->selection = &chain->ms; - color =HE_COLORSET_SELECTED ; - *is_current_entry = true; - } - s =callchain_list__sym_name (chain, bf,sizeof (bf), browser->show_dso); -hist_browser__gotorc (browser, row,0 ); -ui_browser__set_color (&browser->b, color); -slsmg_write_nstring (" " , offset); -slsmg_printf ("%c " , folded_sign); -slsmg_write_nstring (s, width -2 ); +hist_browser__show_callchain_entry (browser, chain, row, + offset, folded_sign, s, + is_current_entry);if (++row == browser->b.rows) goto out;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 6/16 perf tests: Add a test for tracking with sched_switch
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Add a test that checks that sched_switch events and tracking events can be recorded for a workload using the evsel->system_wide and evsel->tracking flags (respectively) with other events sometimes enabled or disabled.
--- tools/perf/Makefile.perf | 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/switch-tracking.c | 572 +++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 578 insertions(+) create mode 100644 tools/perf/tests/switch-tracking.c
tools/perf/Makefile.perf +1 -0
@@ -425,6 +425,7 @@ endif endif LIB_OBJS += $(OUTPUT)tests/mmap-thread-lookup.o LIB_OBJS += $(OUTPUT)tests/thread-mg-share.o +LIB_OBJS += $(OUTPUT)tests/switch-tracking.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
tools/perf/tests/builtin-test.c +4 -0
@@ -154,6 +154,10 @@ static struct test { .func = test__hists_cumulate, }, { + .desc = "Test tracking with sched_switch", + .func = test__switch_tracking, + }, + { .func = NULL, }, };
tools/perf/tests/switch-tracking.c new file +572 -0
572 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -48,6 +48,7 @@ int test__mmap_thread_lookup(void);int test__thread_mg_share (void );int test__hists_output (void );int test__hists_cumulate (void ); +int test__switch_tracking (void );#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 7/16 perf scripting: Add 'flush' callback to scripting API
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
In order to defer some output via the scripting API, there needs to be a callback after session processing but before the session is deleted.
--- tools/perf/builtin-script.c | 13 +++++++++++++ tools/perf/util/scripting-engines/trace-event-perl.c | 6 ++++++ tools/perf/util/scripting-engines/trace-event-python.c | 6 ++++++ tools/perf/util/trace-event-scripting.c | 7 +++++++ tools/perf/util/trace-event.h | 1 + 5 files changed, 33 insertions(+)
tools/perf/builtin-script.c +13 -0
@@ -485,6 +485,11 @@ static int default_start_script(const char *script __maybe_unused,return 0 ; } +static int default_flush_script (void ) +{ +return 0 ; +} +static int default_stop_script (void ) {return 0 ;
@@ -498,6 +503,7 @@ static int default_generate_script(struct pevent *pevent __maybe_unused,static struct scripting_ops default_scripting_ops = { .start_script = default_start_script, + .flush_script = default_flush_script, .stop_script = default_stop_script, .process_event = process_event, .generate_script = default_generate_script,
@@ -513,6 +519,11 @@ static void setup_scripting(void) scripting_ops = &default_scripting_ops; } +static int flush_scripting (void ) +{ +return scripting_ops->flush_script (); +} +static int cleanup_scripting (void ) {pr_debug ("\nperf script stopped\n" );
@@ -1813,6 +1824,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) err =__cmd_script (&script); +flush_scripting (); + out_delete:perf_session__delete (session);
tools/perf/util/scripting-engines/trace-event-perl.c +6 -0
@@ -432,6 +432,11 @@ error:return err; } +static int perl_flush_script (void ) +{ +return 0 ; +} +/* * Stop trace script */
@@ -633,6 +638,7 @@ static int perl_generate_script(struct pevent *pevent, const char *outfile)struct scripting_ops perl_scripting_ops = { .name ="Perl" , .start_script = perl_start_script, + .flush_script = perl_flush_script, .stop_script = perl_stop_script, .process_event = perl_process_event, .generate_script = perl_generate_script,
tools/perf/util/scripting-engines/trace-event-python.c +6 -0
@@ -639,6 +639,11 @@ error:return err; } +static int python_flush_script (void ) +{ +return 0 ; +} +/* * Stop trace script */
@@ -823,6 +828,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)struct scripting_ops python_scripting_ops = { .name ="Python" , .start_script = python_start_script, + .flush_script = python_flush_script, .stop_script = python_stop_script, .process_event = python_process_event, .generate_script = python_generate_script,
tools/perf/util/trace-event-scripting.c +7 -0
@@ -30,6 +30,11 @@struct scripting_context *scripting_context; +static int flush_script_unsupported (void ) +{ +return 0 ; +} +static int stop_script_unsupported (void ) {return 0 ;
@@ -74,6 +79,7 @@ static int python_generate_script_unsupported(struct pevent *peventstruct scripting_ops python_scripting_unsupported_ops = { .name ="Python" , .start_script = python_start_script_unsupported, + .flush_script = flush_script_unsupported, .stop_script = stop_script_unsupported, .process_event = process_event_unsupported, .generate_script = python_generate_script_unsupported,
@@ -137,6 +143,7 @@ static int perl_generate_script_unsupported(struct pevent *peventstruct scripting_ops perl_scripting_unsupported_ops = { .name ="Perl" , .start_script = perl_start_script_unsupported, + .flush_script = flush_script_unsupported, .stop_script = stop_script_unsupported, .process_event = process_event_unsupported, .generate_script = perl_generate_script_unsupported,
tools/perf/util/trace-event.h +1 -0
@@ -64,6 +64,7 @@ struct perf_session;struct scripting_ops {const char *name;int (*start_script) (const char *script,int argc,const char **argv); +int (*flush_script) (void );int (*stop_script) (void ); void (*process_event) (union perf_event *event, struct perf_sample *sample,
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 8/16 perf machine: Rename machine__get_kernel_start_addr() method
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Rename machine__get_kernel_start_addr() to machine__get_running_kernel_start() so that a new function, with a similar name to the original name, can be added that gets the kernel start address from the kernel map.
--- tools/perf/util/machine.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/util/machine.c +4 -4
@@ -593,8 +593,8 @@ const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL};* Returns the name of the start symbol in *symbol_name. Pass in NULL as * symbol_name if it's not that important. */ -static u64 machine__get_kernel_start_addr (struct machine *machine, -const char **symbol_name) +static u64 machine__get_running_kernel_start (struct machine *machine, +const char **symbol_name) {char filename[PATH_MAX ];int i;
@@ -621,7 +621,7 @@ static u64 machine__get_kernel_start_addr(struct machine *machine,int __machine__create_kernel_maps (struct machine *machine,struct dso *kernel) {enum map_type type; -u64 start =machine__get_kernel_start_addr (machine,NULL ); +u64 start =machine__get_running_kernel_start (machine,NULL );for (type =0 ; type <MAP__NR_TYPES ; ++type) {struct kmap *kmap;
@@ -940,7 +940,7 @@ int machine__create_kernel_maps(struct machine *machine) {struct dso *kernel =machine__get_kernel (machine);const char *name; -u64 addr =machine__get_kernel_start_addr (machine, &name); +u64 addr =machine__get_running_kernel_start (machine, &name);if (!addr)return -1 ;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 9/16 perf tools: Add machine__kernel_ip()
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Add a function to determine if an address is in the kernel. This is based on the kernel function kernel_ip().
--- tools/perf/util/event.c | 6 +++--- tools/perf/util/machine.c | 23 +++++++++++++++++++++++ tools/perf/util/machine.h | 17 +++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-)
tools/perf/util/event.c +3 -3
@@ -784,9 +784,9 @@ try_again:* "[vdso]" dso, but for now lets use the old trick of looking * in the whole kernel symbol list. */ -if ((long long )al->addr <0 && - cpumode ==PERF_RECORD_MISC_USER && - machine && mg != &machine->kmaps) { +if (cpumode ==PERF_RECORD_MISC_USER && machine && + mg != &machine->kmaps && +machine__kernel_ip (machine, al->addr)) { mg = &machine->kmaps; load_map = true; goto try_again;
tools/perf/util/machine.c +23 -0
@@ -32,6 +32,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) machine->symbol_filter =NULL ; machine->id_hdr_size =0 ; machine->comm_exec = false; + machine->kernel_start =0 ; machine->root_dir =strdup (root_dir);if (machine->root_dir ==NULL )
@@ -1559,3 +1560,25 @@ int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid,return 0 ; } + +int machine__get_kernel_start (struct machine *machine) +{ +struct map *map =machine__kernel_map (machine,MAP__FUNCTION ); +int err =0 ; + +/* +* The only addresses above 2^63 are kernel addresses of a 64-bit +* kernel. Note that addresses are unsigned so that on a 32-bit system +* all addresses including kernel addresses are less than 2^32. In +* that case (32-bit system), if the kernel mapping is unknown, all +* addresses will be assumed to be in user space - see +* machine__kernel_ip(). +*/ + machine->kernel_start =1ULL <<63 ; +if (map) { + err =map__load (map, machine->symbol_filter); +if (map->start) + machine->kernel_start = map->start; + } +return err; +}
tools/perf/util/machine.h +17 -0
@@ -36,6 +36,7 @@ struct machine {struct list_head kernel_dsos;struct map_groups kmaps;struct map *vmlinux_maps[MAP__NR_TYPES ]; +u64 kernel_start;symbol_filter_t symbol_filter;pid_t *current_tid; };
@@ -46,6 +47,22 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type)return machine->vmlinux_maps[type]; } +int machine__get_kernel_start (struct machine *machine); + +static inline u64 machine__kernel_start (struct machine *machine) +{ +if (!machine->kernel_start) +machine__get_kernel_start (machine); +return machine->kernel_start; +} + +static inline bool machine__kernel_ip (struct machine *machine,u64 ip) +{ +u64 kernel_start =machine__kernel_start (machine); + +return ip >= kernel_start; +} +struct thread *machine__find_thread (struct machine *machine,pid_t pid,pid_t tid); struct comm *machine__thread_exec_comm(struct machine *machine,
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 10/16 perf hists browser: Cleanup callchain print functions
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
The hist_browser__show_callchain() and friends don't need to be that complex. They're splitted in 3 pieces - one for traversing top-level tree, other one for special casing first chains in the top-level entries, and last one for recursive traversing inner trees. It led to code duplication and unnecessary complexity IMHO.
Simplify the function and consolidate the logic into a single function
- it can recursively call itself. A little difference in printing callchains in top-level tree can be handled with a small change.
It should have no functional change.
--- tools/perf/ui/browsers/hists.c | 112 +++++++++++------------------------------ 1 file changed, 29 insertions(+), 83 deletions(-)
tools/perf/ui/browsers/hists.c +29 -83
@@ -502,23 +502,16 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,#define LEVEL_OFFSET_STEP 3 -static int hist_browser__show_callchain_node_rb_tree (struct hist_browser *browser, -struct callchain_node *chain_node, -u64 total,int level, -unsigned short row, -off_t *row_offset, -bool *is_current_entry) +static int hist_browser__show_callchain (struct hist_browser *browser, +struct rb_root *root,int level, +unsigned short row,off_t *row_offset, +u64 total,bool *is_current_entry) {struct rb_node *node;int first_row = row, offset = level *LEVEL_OFFSET_STEP ;u64 new_total; -if (callchain_param.mode ==CHAIN_GRAPH_REL ) - new_total = chain_node->children_hit; -else - new_total = total; - - node =rb_first (&chain_node->rb_root); + node =rb_first (root);while (node) { struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);struct rb_node *next =rb_next (node);
@@ -535,7 +528,7 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browseif (first) first = false; -else +else if (level >1 ) extra_offset =LEVEL_OFFSET_STEP ; folded_sign =callchain_list__folded (chain);
@@ -547,8 +540,9 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse alloc_str =NULL ; str =callchain_list__sym_name (chain, bf,sizeof (bf), browser->show_dso); -if (was_first) { -double percent = cumul *100.0 / new_total; + +if (was_first && level >1 ) { +double percent = cumul *100.0 / total;if (asprintf (&alloc_str,"%2.2f%% %s" , percent, str) <0 ) str ="Not enough memory!" ;
@@ -571,78 +565,23 @@ do_next:if (folded_sign =='-' ) {const int new_level = level + (extra_offset ?2 :1 ); - row +=hist_browser__show_callchain_node_rb_tree (browser, child, new_total, - new_level, row, row_offset, - is_current_entry); - } -if (row == browser->b.rows) - goto out; - node = next; - } -out: -return row - first_row; -} - -static int hist_browser__show_callchain_node (struct hist_browser *browser, -struct callchain_node *node, -int level,unsigned short row, -off_t *row_offset, -bool *is_current_entry) -{ -struct callchain_list *chain; -int first_row = row; -int offset = level *LEVEL_OFFSET_STEP ; -char folded_sign =' ' ; - -list_for_each_entry (chain, &node->val, list) { -char bf[1024 ], *s; - folded_sign =callchain_list__folded (chain); +if (callchain_param.mode ==CHAIN_GRAPH_REL ) + new_total = child->children_hit; +else + new_total = total; -if (*row_offset !=0 ) { - --*row_offset; -continue ; + row +=hist_browser__show_callchain (browser, &child->rb_root, + new_level, + row, row_offset, + new_total, + is_current_entry); } - - s =callchain_list__sym_name (chain, bf,sizeof (bf), - browser->show_dso); -hist_browser__show_callchain_entry (browser, chain, row, - offset, folded_sign, s, - is_current_entry); - -if (++row == browser->b.rows) - goto out; - } - -if (folded_sign =='-' ) - row +=hist_browser__show_callchain_node_rb_tree (browser, node, - browser->hists->stats.total_period, - level +1 , row, - row_offset, - is_current_entry); -out: -return row - first_row; -} - -static int hist_browser__show_callchain (struct hist_browser *browser, -struct rb_root *chain, -int level,unsigned short row, -off_t *row_offset, -bool *is_current_entry) -{ -struct rb_node *nd; -int first_row = row; - -for (nd =rb_first (chain); nd; nd =rb_next (nd)) { - struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); - - row +=hist_browser__show_callchain_node (browser, node, level, - row, row_offset, - is_current_entry);if (row == browser->b.rows)break ; + node = next; } - +out:return row - first_row; }
@@ -817,9 +756,16 @@ static int hist_browser__show_entry(struct hist_browser *browser, --row_offset;if (folded_sign =='-' && row != browser->b.rows) { - printed +=hist_browser__show_callchain (browser, &entry->sorted_chain, +u64 total =hists__total_period (entry->hists); + +if (symbol_conf.cumulate_callchain) + total = entry->stat_acc->period; + + printed +=hist_browser__show_callchain (browser, + &entry->sorted_chain,1 , row, &row_offset, - ¤t_entry); + total, ¤t_entry); +if (current_entry) browser->he_selection = entry; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 11/16 perf machine: Fallback to MAP__FUNCTION if daddr maps are NULL
In reply to Arnaldo Carvalho de MeloFrom: Don Zickus <[email protected]>
As we run "perf c2c" on more applications, we noticed we're missing significant samples from a common customer's application. Looking at the /proc/<pid>/maps file for the app, we see "rwxs" and "rwxp" permissions on many of the shared memory & heap regions, and on all the thread stacks.
Because those regions have the "x" bit set, perf marks them with a MAP_FUNCTION type. Hence ip_resolve_data() never finds load or store events coming from them.
We fixed this by re-calling thread__find_addr_location with MAP__FUNCTION in the case where map is NULL as a last ditch effort to map the sample before giving up and dropping it.
--- tools/perf/util/machine.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
tools/perf/util/machine.c +10 -0
@@ -1314,6 +1314,16 @@ static void ip__resolve_data(struct machine *machine, struct thread *thread,thread__find_addr_location (thread, machine, m,MAP__VARIABLE , addr, &al); +if (al.map ==NULL ) { +/* +* some shared data regions have execute bit set which puts +* their mapping in the MAP__FUNCTION type array. +* Check there as a fallback option before dropping the sample. +*/ +thread__find_addr_location (thread, machine, m,MAP__FUNCTION , addr, + &al); + } + ams->addr = addr; ams->al_addr = al.addr; ams->sym = al.sym;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 12/16 perf: Fix perf_poll to return proper POLLHUP value
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Currently perf_poll returns POLL_HUP in case of error, which is wrong, because poll syscall expects POLLHUP. The POLL_HUP is meant to be used for SIGIO state.
--- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
@@ -3627,7 +3627,7 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) {struct perf_event *event = file->private_data;struct ring_buffer *rb; -unsigned int events =POLL_HUP ; +unsigned int events =POLLHUP ;poll_wait (file, &event->waitq, wait);/*
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 13/16 perf: Add PERF_EVENT_STATE_EXIT state for events with exited task
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Adding new perf event state to indicate that the monitored task has exited. In this case the event stays alive until the owner task exits or close the event fd while providing the last data through the read syscall and ring buffer.
Instead it needs to propagate the error info (monitored task has died) via poll and read syscalls by returning POLLHUP and 0 respectively.
--- include/linux/perf_event.h | 1 + kernel/events/core.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-)
include/linux/perf_event.h +1 -0
@@ -269,6 +269,7 @@ struct pmu {* enum perf_event_active_state - the states of a event */ enum perf_event_active_state { +PERF_EVENT_STATE_EXIT =-3 ,PERF_EVENT_STATE_ERROR =-2 ,PERF_EVENT_STATE_OFF =-1 ,PERF_EVENT_STATE_INACTIVE =0 ,
kernel/events/core.c +9 -1
@@ -3600,7 +3600,8 @@ perf_read_hw(struct perf_event *event, char __user *buf, size_t count)* error state (i.e. because it was pinned but it couldn't be * scheduled on to the CPU at some point). */ -if (event->state ==PERF_EVENT_STATE_ERROR ) +if ((event->state ==PERF_EVENT_STATE_ERROR ) || + (event->state ==PERF_EVENT_STATE_EXIT ))return 0 ;if (count < event->read_size)
@@ -3630,6 +3631,10 @@ static unsigned int perf_poll(struct file *file, poll_table *wait)unsigned int events =POLLHUP ;poll_wait (file, &event->waitq, wait); + +if (event->state ==PERF_EVENT_STATE_EXIT ) +return events; +/* * Pin the event->rb by taking event->mmap_mutex; otherwise * perf_event_set_output() can swizzle our rb and make us miss wakeups.
@@ -7588,6 +7593,9 @@ __perf_event_exit_task(struct perf_event *child_event,if (child_event->parent) {sync_child_event (child_event, child);free_event (child_event); + }else { + child_event->state =PERF_EVENT_STATE_EXIT ; +perf_event_wakeup (child_event); } }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 14/16 perf top: Use set_term_quiet() instead of open coded equivalent
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
--- tools/perf/builtin-top.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
tools/perf/builtin-top.c +2 -7
@@ -433,18 +433,13 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)if (!perf_top__key_mapped (top, c)) {struct pollfd stdin_poll = { .fd =0 , .events =POLLIN }; -struct termios tc, save; +struct termios save;perf_top__print_mapped_keys (top);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); +set_term_quiet_input (&save);poll (&stdin_poll,1 ,-1 ); c =getc (stdin);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 15/16 perf tools: Add +field argument support for --field option
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Adding support to add field(s) to default field order via using the '+' prefix, like for report:
$ perf report
Samples: 10 of event 'cycles', Event count (approx.): 4463799
Overhead Command Shared Object Symbol
32.40% ls [kernel.kallsyms] [k] filemap_fault
28.19% ls [kernel.kallsyms] [k] get_page_from_freelist
23.38% ls [kernel.kallsyms] [k] enqueue_entity
15.04% ls [kernel.kallsyms] [k] mmap_region $ perf report -F +period,sample
Samples: 10 of event 'cycles', Event count (approx.): 4463799
Overhead Period Samples Command Shared Object Symbol
32.40% 1446493 1 ls [kernel.kallsyms] [k] filemap_fault
28.19% 1258486 1 ls [kernel.kallsyms] [k] get_page_from_freelist
23.38% 1043754 1 ls [kernel.kallsyms] [k] enqueue_entity
15.04% 671160 1 ls [kernel.kallsyms] [k] mmap_regionWorks in general for commands using --field option.
--- tools/perf/ui/hist.c | 4 ++-- tools/perf/util/sort.c | 24 +++++++++++++++++++----- tools/perf/util/sort.h | 1 + 3 files changed, 22 insertions(+), 7 deletions(-)
tools/perf/ui/hist.c +2 -2
@@ -452,7 +452,7 @@ void perf_hpp__init(void)/* * If user specified field order, no need to setup default fields. */ -if (field_order) +if (is_strict_order (field_order))return ;if (symbol_conf.cumulate_callchain) {
@@ -519,7 +519,7 @@ void perf_hpp__column_disable(unsigned col)void perf_hpp__cancel_cumulate (void ) { -if (field_order) +if (is_strict_order (field_order))return ;perf_hpp__column_disable (PERF_HPP__OVERHEAD_ACC );
tools/perf/util/sort.c +19 -5
@@ -1453,7 +1453,7 @@ static int __setup_sorting(void)int ret =0 ;if (sort_keys ==NULL ) { -if (field_order) { +if (is_strict_order (field_order)) {/* * If user specified field order but no sort order, * we'll honor it and not add default sort orders.
@@ -1639,23 +1639,36 @@ static void reset_dimensions(void) memory_sort_dimensions[i].taken =0 ; } +bool is_strict_order (const char *order) +{ +return order && (*order !='+' ); +} +static int __setup_output_field (void ) { -char *tmp, *tok, *str; -int ret =0 ; +char *tmp, *tok, *str, *strp; +int ret = -EINVAL ;if (field_order ==NULL )return 0 ;reset_dimensions (); - str =strdup (field_order); + strp = str =strdup (field_order);if (str ==NULL ) {error ("Not enough memory to setup output fields" );return -ENOMEM ; } -for (tok =strtok_r (str,", " , &tmp); +if (!is_strict_order (field_order)) + strp++; + +if (!strlen (strp)) { +error ("Invalid --fields key: `+'" ); + goto out; + } + +for (tok =strtok_r (strp,", " , &tmp); tok; tok =strtok_r (NULL ,", " , &tmp)) { ret =output_field_add (tok);if (ret == -EINVAL ) {
@@ -1667,6 +1680,7 @@ static int __setup_output_field(void) } } +out:free (str);return ret; }
tools/perf/util/sort.h +1 -0
@@ -218,4 +218,5 @@ void perf_hpp__set_elide(int idx, bool elide);int report_parse_ignore_callees_opt (const struct option *opt,const char *arg,int unset); +bool is_strict_order (const char *order);#endif /* __PERF_SORT_H */
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 16/16 perf hists browser: Consolidate callchain print functions in TUI
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Currently there're two callchain print functions in TUI - one for the hists browser and another for file dump. They do almost same job so it'd be better consolidate the codes.
To do that, provide two callbacks to the generic logic - one for printing and another for checking whether it should stop.
--- tools/perf/ui/browsers/hists.c | 203 ++++++++++++++++------------------------- 1 file changed, 80 insertions(+), 123 deletions(-)
tools/perf/ui/browsers/hists.c +80 -123
@@ -477,20 +477,37 @@ static char *callchain_list__sym_name(struct callchain_list *cl,return bf; } +struct callchain_print_arg { +/* for hists browser */ +off_t row_offset; +bool is_current_entry; + +/* for file dump */ +FILE *fp; +int printed; +}; + +typedef void (*print_callchain_entry_fn )(struct hist_browser *browser, +struct callchain_list *chain, +const char *str,int offset, +unsigned short row, +struct callchain_print_arg *arg); +static void hist_browser__show_callchain_entry (struct hist_browser *browser,struct callchain_list *chain, -unsigned short row,int offset, -char folded_sign,const char *str, -bool *is_current_entry) +const char *str,int offset, +unsigned short row, +struct callchain_print_arg *arg) {int color, width; +char folded_sign =callchain_list__folded (chain); color =HE_COLORSET_NORMAL ; width = browser->b.width - (offset +2 );if (ui_browser__is_current_entry (&browser->b, row)) { browser->selection = &chain->ms; color =HE_COLORSET_SELECTED ; - *is_current_entry = true; + arg->is_current_entry = true; }ui_browser__set_color (&browser->b, color);
@@ -500,12 +517,41 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,slsmg_write_nstring (str, width); } +static void hist_browser__fprintf_callchain_entry (struct hist_browser *b__maybe_unused , +struct callchain_list *chain, +const char *str,int offset, +unsigned short row__maybe_unused , +struct callchain_print_arg *arg) +{ +char folded_sign =callchain_list__folded (chain); + + arg->printed +=fprintf (arg->fp,"%*s%c %s\n" , offset," " , + folded_sign, str); +} + +typedef bool (*check_output_full_fn )(struct hist_browser *browser, +unsigned short row); + +static bool hist_browser__check_output_full (struct hist_browser *browser, +unsigned short row) +{ +return browser->b.rows == row; +} + +static bool hist_browser__check_dump_full (struct hist_browser *browser__maybe_unused , +unsigned short row__maybe_unused ) +{ +return false; +} +#define LEVEL_OFFSET_STEP 3static int hist_browser__show_callchain (struct hist_browser *browser,struct rb_root *root,int level, -unsigned short row,off_t *row_offset, -u64 total,bool *is_current_entry) +unsigned short row,u64 total, +print_callchain_entry_fn print, +struct callchain_print_arg *arg, +check_output_full_fn is_output_full) {struct rb_node *node;int first_row = row, offset = level *LEVEL_OFFSET_STEP ;
@@ -532,8 +578,8 @@ static int hist_browser__show_callchain(struct hist_browser *browser, extra_offset =LEVEL_OFFSET_STEP ; folded_sign =callchain_list__folded (chain); -if (*row_offset !=0 ) { - --*row_offset; +if (arg->row_offset !=0 ) { + arg->row_offset--; goto do_next; }
@@ -550,13 +596,11 @@ static int hist_browser__show_callchain(struct hist_browser *browser, str = alloc_str; } -hist_browser__show_callchain_entry (browser, chain, row, - offset + extra_offset, - folded_sign, str, - is_current_entry); +free (alloc_str); -if (++row == browser->b.rows) +if (is_output_full (browser, ++row)) goto out; do_next:if (folded_sign =='+' )
@@ -572,12 +616,10 @@ do_next: new_total = total; row +=hist_browser__show_callchain (browser, &child->rb_root, - new_level, - row, row_offset, - new_total, - is_current_entry); + new_level, row, new_total, + print, arg, is_output_full); } -if (row == browser->b.rows) +if (is_output_full (browser, row))break ; node = next; }
@@ -757,16 +799,20 @@ static int hist_browser__show_entry(struct hist_browser *browser,if (folded_sign =='-' && row != browser->b.rows) {u64 total =hists__total_period (entry->hists); +struct callchain_print_arg arg = { + .row_offset = row_offset, + .is_current_entry = current_entry, + };if (symbol_conf.cumulate_callchain) total = entry->stat_acc->period; printed +=hist_browser__show_callchain (browser, - &entry->sorted_chain, -1 , row, &row_offset, - total, ¤t_entry); + &entry->sorted_chain,1 , row, total, + hist_browser__show_callchain_entry, &arg, + hist_browser__check_output_full); -if (current_entry) +if (arg.is_current_entry) browser->he_selection = entry; }
@@ -1022,110 +1068,21 @@ do_offset: } } -static int hist_browser__fprintf_callchain_node_rb_tree (struct hist_browser *browser, -struct callchain_node *chain_node, -u64 total,int level, -FILE *fp) -{ -struct rb_node *node; -int offset = level *LEVEL_OFFSET_STEP ; -u64 new_total; -int printed =0 ; - -if (callchain_param.mode ==CHAIN_GRAPH_REL ) - new_total = chain_node->children_hit; -else - new_total = total; - - node =rb_first (&chain_node->rb_root); -while (node) { - struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); -struct rb_node *next =rb_next (node); -u64 cumul =callchain_cumul_hits (child); -struct callchain_list *chain; -char folded_sign =' ' ; -int first = true; -int extra_offset =0 ; - -list_for_each_entry (chain, &child->val, list) { -char bf[1024 ], *alloc_str; -const char *str; -bool was_first = first; - -if (first) - first = false; -else - extra_offset =LEVEL_OFFSET_STEP ; - - folded_sign =callchain_list__folded (chain); - - alloc_str =NULL ; - str =callchain_list__sym_name (chain, bf,sizeof (bf), - browser->show_dso); -if (was_first) { -double percent = cumul *100.0 / new_total; - -if (asprintf (&alloc_str,"%2.2f%% %s" , percent, str) <0 ) - str ="Not enough memory!" ; -else - str = alloc_str; - } - - printed +=fprintf (fp,"%*s%c %s\n" , offset + extra_offset," " , folded_sign, str); -free (alloc_str); -if (folded_sign =='+' ) -break ; - } - -if (folded_sign =='-' ) { -const int new_level = level + (extra_offset ?2 :1 ); - printed +=hist_browser__fprintf_callchain_node_rb_tree (browser, child, new_total, - new_level, fp); - } - - node = next; - } - -return printed; -} - -static int hist_browser__fprintf_callchain_node (struct hist_browser *browser, -struct callchain_node *node, -int level,FILE *fp) -{ -struct callchain_list *chain; -int offset = level *LEVEL_OFFSET_STEP ; -char folded_sign =' ' ; -int printed =0 ; - -list_for_each_entry (chain, &node->val, list) { -char bf[1024 ], *s; - - folded_sign =callchain_list__folded (chain); - s =callchain_list__sym_name (chain, bf,sizeof (bf), browser->show_dso); - printed +=fprintf (fp,"%*s%c %s\n" , offset," " , folded_sign, s); - } - -if (folded_sign =='-' ) - printed +=hist_browser__fprintf_callchain_node_rb_tree (browser, node, - browser->hists->stats.total_period, - level +1 , fp); -return printed; -} -static int hist_browser__fprintf_callchain (struct hist_browser *browser, -struct rb_root *chain,int level,FILE *fp) +struct hist_entry *he,FILE *fp) { -struct rb_node *nd; -int printed =0 ; - -for (nd =rb_first (chain); nd; nd =rb_next (nd)) { - struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); +u64 total =hists__total_period (he->hists); +struct callchain_print_arg arg = { + .fp = fp, + }; - printed +=hist_browser__fprintf_callchain_node (browser, node, level, fp); - } +if (symbol_conf.cumulate_callchain) + total = he->stat_acc->period; -return printed; +hist_browser__show_callchain (browser, &he->sorted_chain,1 ,0 , total, + hist_browser__fprintf_callchain_entry, &arg, + hist_browser__check_dump_full); +return arg.printed; } static int hist_browser__fprintf_entry(struct hist_browser *browser,
@@ -1164,7 +1121,7 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, printed +=fprintf (fp,"%s\n" ,rtrim (s));if (folded_sign =='-' ) - printed +=hist_browser__fprintf_callchain (browser, &he->sorted_chain,1 , fp); + printed +=hist_browser__fprintf_callchain (browser, he, fp);return printed; }
Signature · 1 line
1.9.3
Quoted 24 lines · Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit
af924aa35129edf338ebc8da6a4eae08cf7cb297:Merge tag 'perf-core-for-mingo' of
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linuxinto perf/core (2014-08-18 10:14:43 +0200)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-core-for-mingofor you to fetch changes up to
141da74d2eff8de134c5a5ffaf2800a8a1b27517:perf hists browser: Consolidate callchain print functions in TUI (2014-08-22 13:12:15 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:User visible:
Quoted 8 lines
o Don't try to find DSOs in SYSV maps (Don Zickus)
o Fallback to
MAP__FUNCTIONif daddr maps are NULL, i.e. addresses get looked upon more maps (Don Zickus)o Kernel fix to properly handle exited tasks, by returning POLLHUP values on perf event file descriptors. Tooling changes will come next, but were tested with this kernel fix. (Jiri Olsa)
So the signoffs are really weird (and invalid) here:
commit ce1d77c667e40631d6673717e65e72f72265bf10
Author: Jiri Olsa <[email protected]> Date: Fri Aug 15 16:24:45 2014 -0300
perf top: Use set_term_quiet() instead of open coded equivalent
...
and in 7713886adc15 and f017bf0a8d92 - results of a rebase gone wrong?
Thanks,
Ingo
Arnaldo Carvalho de Melo
maintainerEm Sun, Aug 24, 2014 at 12:11:24PM +0200, Ingo Molnar escreveu:
Quoted 22 lines · Arnaldo Carvalho de Melo
Quoted 3 lines
o Kernel fix to properly handle exited tasks, by returning POLLHUP values on perf event file descriptors. Tooling changes will come next, but were tested with this kernel fix. (Jiri Olsa)
So the signoffs are really weird (and invalid) here:
commit
ce1d77c667e40631d6673717e65e72f72265bf10Author: Jiri Olsa <[email protected]> Date: Fri Aug 15 16:24:45 2014 -0300perf top: Use
set_term_quiet()instead of open coded equivalent...
Cc Jiri Olsa <[email protected]>Cc Namhyung Kim <[email protected]>Cc Paul Mackerras <[email protected]>Cc Peter Zijlstra <[email protected]>[ Yanked this out of a patch containing this and some other change ]Signed-off-by Arnaldo Carvalho de Melo <[email protected]>
Quoted 1 line
and in
7713886adc15andf017bf0a8d92- results of a rebase gone wrong?
Should be ok now, I recreated the perf-core-for-mingo signed tag, please let me know if there are still any problems,
Thanks!
- Arnaldo
Quoted 23 lines · Arnaldo Carvalho de Melo
Em Sun, Aug 24, 2014 at 12:11:24PM +0200, Ingo Molnar escreveu:
Quoted 21 lines · Arnaldo Carvalho de Melo
Quoted 3 lines
o Kernel fix to properly handle exited tasks, by returning POLLHUP values on perf event file descriptors. Tooling changes will come next, but were tested with this kernel fix. (Jiri Olsa)
So the signoffs are really weird (and invalid) here:
commit
ce1d77c667e40631d6673717e65e72f72265bf10Author: Jiri Olsa <[email protected]> Date: Fri Aug 15 16:24:45 2014 -0300perf top: Use
set_term_quiet()instead of open coded equivalent...
Cc Jiri Olsa <[email protected]>Cc Namhyung Kim <[email protected]>Cc Paul Mackerras <[email protected]>Cc Peter Zijlstra <[email protected]>[ Yanked this out of a patch containing this and some other change ]Signed-off-by Arnaldo Carvalho de Melo <[email protected]>
Quoted 4 lines
Quoted 1 line
and in
7713886adc15andf017bf0a8d92- results of a rebase gone wrong?Should be ok now, I recreated the perf-core-for-mingo signed tag, please let me know if there are still any problems,
Looks good now. Pulled, thanks a lot Arnaldo!
Ingo