Commit e9363dee authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo' of...

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

  - Use the alternative with the most descriptive filename containing
    a vmlinux file for a given build-id, providing a better title line
    for tools such as 'annotate'. (Arnaldo Carvalho de Melo)

  - Remove help messages about previous right and left arrow keybidings, that
    were repurposed for horizontal scrolling. (Arnaldo Carvalho de Melo)

  - Inform how to reset the symbol filter in the hists browser. (top & report)
    (Arnaldo Carvalho de Melo)

  - Add 'm' key for context menu display in the hists browser, that became
    inacessible with the repurposing of the right arrow key for horizontal
    scrolling. (Namhyung Kim)

  - Use debug_frame for callchains if eh_frame is unusable. (Rabin Vicent)

Build fixes:

  - Fix strict-aliasing breakage with gcc 4.4 in the READ_ONCE/WRITE_ONCE code
    adopted from the kernel tree, that builds with -fno-strict-aliasing while
    tools/perf/ uses -Wstrict-aliasing=3. (Jiri Olsa)

  - Fix unw_word_t pointer casts in code using libunwind for callchains,
    fixing the build in at least 32-bit MIPS systems. (Rabin Vicent)

  - Work around cross compile build problems related to fixdep. (Jiri Olsa)
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 0e537fef 3a70fcd3
build := -f $(srctree)/tools/build/Makefile.build dir=. obj build := -f $(srctree)/tools/build/Makefile.build dir=. obj
ifdef CROSS_COMPILE
fixdep:
else
fixdep: fixdep:
$(Q)$(MAKE) -C $(srctree)/tools/build fixdep $(Q)$(MAKE) -C $(srctree)/tools/build fixdep
endif
.PHONY: fixdep .PHONY: fixdep
...@@ -43,13 +43,29 @@ ...@@ -43,13 +43,29 @@
#include <linux/types.h> #include <linux/types.h>
/*
* Following functions are taken from kernel sources and
* break aliasing rules in their original form.
*
* While kernel is compiled with -fno-strict-aliasing,
* perf uses -Wstrict-aliasing=3 which makes build fail
* under gcc 4.4.
*
* Using extra __may_alias__ type to allow aliasing
* in this case.
*/
typedef __u8 __attribute__((__may_alias__)) __u8_alias_t;
typedef __u16 __attribute__((__may_alias__)) __u16_alias_t;
typedef __u32 __attribute__((__may_alias__)) __u32_alias_t;
typedef __u64 __attribute__((__may_alias__)) __u64_alias_t;
static __always_inline void __read_once_size(const volatile void *p, void *res, int size) static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
{ {
switch (size) { switch (size) {
case 1: *(__u8 *)res = *(volatile __u8 *)p; break; case 1: *(__u8_alias_t *) res = *(volatile __u8_alias_t *) p; break;
case 2: *(__u16 *)res = *(volatile __u16 *)p; break; case 2: *(__u16_alias_t *) res = *(volatile __u16_alias_t *) p; break;
case 4: *(__u32 *)res = *(volatile __u32 *)p; break; case 4: *(__u32_alias_t *) res = *(volatile __u32_alias_t *) p; break;
case 8: *(__u64 *)res = *(volatile __u64 *)p; break; case 8: *(__u64_alias_t *) res = *(volatile __u64_alias_t *) p; break;
default: default:
barrier(); barrier();
__builtin_memcpy((void *)res, (const void *)p, size); __builtin_memcpy((void *)res, (const void *)p, size);
...@@ -60,10 +76,10 @@ static __always_inline void __read_once_size(const volatile void *p, void *res, ...@@ -60,10 +76,10 @@ static __always_inline void __read_once_size(const volatile void *p, void *res,
static __always_inline void __write_once_size(volatile void *p, void *res, int size) static __always_inline void __write_once_size(volatile void *p, void *res, int size)
{ {
switch (size) { switch (size) {
case 1: *(volatile __u8 *)p = *(__u8 *)res; break; case 1: *(volatile __u8_alias_t *) p = *(__u8_alias_t *) res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break; case 2: *(volatile __u16_alias_t *) p = *(__u16_alias_t *) res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break; case 4: *(volatile __u32_alias_t *) p = *(__u32_alias_t *) res; break;
case 8: *(volatile __u64 *)p = *(__u64 *)res; break; case 8: *(volatile __u64_alias_t *) p = *(__u64_alias_t *) res; break;
default: default:
barrier(); barrier();
__builtin_memcpy((void *)p, (const void *)res, size); __builtin_memcpy((void *)p, (const void *)res, size);
......
...@@ -768,8 +768,8 @@ static int annotate_browser__run(struct annotate_browser *browser, ...@@ -768,8 +768,8 @@ static int annotate_browser__run(struct annotate_browser *browser,
"UP/DOWN/PGUP\n" "UP/DOWN/PGUP\n"
"PGDN/SPACE Navigate\n" "PGDN/SPACE Navigate\n"
"q/ESC/CTRL+C Exit\n\n" "q/ESC/CTRL+C Exit\n\n"
"-> Go to target\n" "ENTER Go to target\n"
"<- Exit\n" "ESC Exit\n"
"H Cycle thru hottest instructions\n" "H Cycle thru hottest instructions\n"
"j Toggle showing jump to target arrows\n" "j Toggle showing jump to target arrows\n"
"J Toggle showing number of jump sources on targets\n" "J Toggle showing number of jump sources on targets\n"
...@@ -1056,7 +1056,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, ...@@ -1056,7 +1056,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
goto out_free_offsets; goto out_free_offsets;
} }
ui_helpline__push("Press <- or ESC to exit"); ui_helpline__push("Press ESC to exit");
notes = symbol__annotation(sym); notes = symbol__annotation(sym);
browser.start = map__rip_2objdump(map, sym->start); browser.start = map__rip_2objdump(map, sym->start);
......
...@@ -1496,7 +1496,7 @@ do_zoom_thread(struct hist_browser *browser, struct popup_action *act) ...@@ -1496,7 +1496,7 @@ do_zoom_thread(struct hist_browser *browser, struct popup_action *act)
thread__zput(browser->hists->thread_filter); thread__zput(browser->hists->thread_filter);
ui_helpline__pop(); ui_helpline__pop();
} else { } else {
ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"", ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s(%d) thread\"",
thread->comm_set ? thread__comm_str(thread) : "", thread->comm_set ? thread__comm_str(thread) : "",
thread->tid); thread->tid);
browser->hists->thread_filter = thread__get(thread); browser->hists->thread_filter = thread__get(thread);
...@@ -1540,7 +1540,7 @@ do_zoom_dso(struct hist_browser *browser, struct popup_action *act) ...@@ -1540,7 +1540,7 @@ do_zoom_dso(struct hist_browser *browser, struct popup_action *act)
} else { } else {
if (map == NULL) if (map == NULL)
return 0; return 0;
ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"", ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DSO\"",
__map__is_kernel(map) ? "the Kernel" : map->dso->short_name); __map__is_kernel(map) ? "the Kernel" : map->dso->short_name);
browser->hists->dso_filter = map->dso; browser->hists->dso_filter = map->dso;
perf_hpp__set_elide(HISTC_DSO, true); perf_hpp__set_elide(HISTC_DSO, true);
...@@ -1761,14 +1761,15 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1761,14 +1761,15 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
"For multiple event sessions:\n\n" \ "For multiple event sessions:\n\n" \
"TAB/UNTAB Switch events\n\n" \ "TAB/UNTAB Switch events\n\n" \
"For symbolic views (--sort has sym):\n\n" \ "For symbolic views (--sort has sym):\n\n" \
"-> Zoom into DSO/Threads & Annotate current symbol\n" \ "ENTER Zoom into DSO/Threads & Annotate current symbol\n" \
"<- Zoom out\n" \ "ESC Zoom out\n" \
"a Annotate current symbol\n" \ "a Annotate current symbol\n" \
"C Collapse all callchains\n" \ "C Collapse all callchains\n" \
"d Zoom into current DSO\n" \ "d Zoom into current DSO\n" \
"E Expand all callchains\n" \ "E Expand all callchains\n" \
"F Toggle percentage of filtered entries\n" \ "F Toggle percentage of filtered entries\n" \
"H Display column headers\n" \ "H Display column headers\n" \
"m Display context menu\n" \
"S Zoom into current Processor Socket\n" \ "S Zoom into current Processor Socket\n" \
/* help messages are sorted by lexical order of the hotkey */ /* help messages are sorted by lexical order of the hotkey */
...@@ -1889,7 +1890,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1889,7 +1890,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
continue; continue;
case '/': case '/':
if (ui_browser__input_window("Symbol to show", if (ui_browser__input_window("Symbol to show",
"Please enter the name of symbol you want to see", "Please enter the name of symbol you want to see.\n"
"To remove the filter later, press / + ENTER.",
buf, "ENTER: OK, ESC: Cancel", buf, "ENTER: OK, ESC: Cancel",
delay_secs * 2) == K_ENTER) { delay_secs * 2) == K_ENTER) {
hists->symbol_filter_str = *buf ? buf : NULL; hists->symbol_filter_str = *buf ? buf : NULL;
...@@ -1934,6 +1936,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1934,6 +1936,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
continue; continue;
case K_ENTER: case K_ENTER:
case K_RIGHT: case K_RIGHT:
case 'm':
/* menu */ /* menu */
break; break;
case K_ESC: case K_ESC:
......
...@@ -72,7 +72,7 @@ static int map_browser__run(struct map_browser *browser) ...@@ -72,7 +72,7 @@ static int map_browser__run(struct map_browser *browser)
int key; int key;
if (ui_browser__show(&browser->b, browser->map->dso->long_name, if (ui_browser__show(&browser->b, browser->map->dso->long_name,
"Press <- or ESC to exit, %s / to search", "Press ESC to exit, %s / to search",
verbose ? "" : "restart with -v to use") < 0) verbose ? "" : "restart with -v to use") < 0)
return -1; return -1;
......
...@@ -89,7 +89,7 @@ static int script_browser__run(struct perf_script_browser *browser) ...@@ -89,7 +89,7 @@ static int script_browser__run(struct perf_script_browser *browser)
int key; int key;
if (ui_browser__show(&browser->b, browser->script_name, if (ui_browser__show(&browser->b, browser->script_name,
"Press <- or ESC to exit") < 0) "Press ESC to exit") < 0)
return -1; return -1;
while (1) { while (1) {
......
...@@ -1607,6 +1607,15 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map, ...@@ -1607,6 +1607,15 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map,
int i, err = 0; int i, err = 0;
char *filename = NULL; char *filename = NULL;
pr_debug("Looking at the vmlinux_path (%d entries long)\n",
vmlinux_path__nr_entries + 1);
for (i = 0; i < vmlinux_path__nr_entries; ++i) {
err = dso__load_vmlinux(dso, map, vmlinux_path[i], false, filter);
if (err > 0)
goto out;
}
if (!symbol_conf.ignore_vmlinux_buildid) if (!symbol_conf.ignore_vmlinux_buildid)
filename = dso__build_id_filename(dso, NULL, 0); filename = dso__build_id_filename(dso, NULL, 0);
if (filename != NULL) { if (filename != NULL) {
...@@ -1615,15 +1624,6 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map, ...@@ -1615,15 +1624,6 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map,
goto out; goto out;
free(filename); free(filename);
} }
pr_debug("Looking at the vmlinux_path (%d entries long)\n",
vmlinux_path__nr_entries + 1);
for (i = 0; i < vmlinux_path__nr_entries; ++i) {
err = dso__load_vmlinux(dso, map, vmlinux_path[i], false, filter);
if (err > 0)
break;
}
out: out:
return err; return err;
} }
......
...@@ -330,6 +330,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, ...@@ -330,6 +330,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
struct map *map; struct map *map;
unw_dyn_info_t di; unw_dyn_info_t di;
u64 table_data, segbase, fde_count; u64 table_data, segbase, fde_count;
int ret = -EINVAL;
map = find_map(ip, ui); map = find_map(ip, ui);
if (!map || !map->dso) if (!map || !map->dso)
...@@ -348,13 +349,14 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, ...@@ -348,13 +349,14 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
di.u.rti.table_data = map->start + table_data; di.u.rti.table_data = map->start + table_data;
di.u.rti.table_len = fde_count * sizeof(struct table_entry) di.u.rti.table_len = fde_count * sizeof(struct table_entry)
/ sizeof(unw_word_t); / sizeof(unw_word_t);
return dwarf_search_unwind_table(as, ip, &di, pi, ret = dwarf_search_unwind_table(as, ip, &di, pi,
need_unwind_info, arg); need_unwind_info, arg);
} }
#ifndef NO_LIBUNWIND_DEBUG_FRAME #ifndef NO_LIBUNWIND_DEBUG_FRAME
/* Check the .debug_frame section for unwinding info */ /* Check the .debug_frame section for unwinding info */
if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { if (ret < 0 &&
!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
int fd = dso__data_get_fd(map->dso, ui->machine); int fd = dso__data_get_fd(map->dso, ui->machine);
int is_exec = elf_is_exec(fd, map->dso->name); int is_exec = elf_is_exec(fd, map->dso->name);
unw_word_t base = is_exec ? 0 : map->start; unw_word_t base = is_exec ? 0 : map->start;
...@@ -370,7 +372,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, ...@@ -370,7 +372,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
} }
#endif #endif
return -EINVAL; return ret;
} }
static int access_fpreg(unw_addr_space_t __maybe_unused as, static int access_fpreg(unw_addr_space_t __maybe_unused as,
...@@ -461,7 +463,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as, ...@@ -461,7 +463,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as,
if (ret) { if (ret) {
pr_debug("unwind: access_mem %p not inside range" pr_debug("unwind: access_mem %p not inside range"
" 0x%" PRIx64 "-0x%" PRIx64 "\n", " 0x%" PRIx64 "-0x%" PRIx64 "\n",
(void *) addr, start, end); (void *) (uintptr_t) addr, start, end);
*valp = 0; *valp = 0;
return ret; return ret;
} }
...@@ -471,7 +473,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as, ...@@ -471,7 +473,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as,
offset = addr - start; offset = addr - start;
*valp = *(unw_word_t *)&stack->data[offset]; *valp = *(unw_word_t *)&stack->data[offset];
pr_debug("unwind: access_mem addr %p val %lx, offset %d\n", pr_debug("unwind: access_mem addr %p val %lx, offset %d\n",
(void *) addr, (unsigned long)*valp, offset); (void *) (uintptr_t) addr, (unsigned long)*valp, offset);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment