aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2018-11-06 07:57:02 -0500
committerJiri Kosina <jkosina@suse.cz>2018-11-06 07:57:02 -0500
commit0c7244209588630a9b45e52490ef1390e04499a6 (patch)
treed60f5610f9b36ff05ed5202396c811628bacdb61 /tools/perf
parent399474e4c1100bca264ed14fa3ad0d68fab484d8 (diff)
parenteb7046e9bf466cebfcfbcdf640e41d9e3a80086c (diff)
Merge branch 'master' into for-4.20/upstream-fixes
Pull in a merge commit that brought in 3b692c55e58d ("HID: asus: only support backlight when it's not driven by WMI") so that fixup could be applied on top of it.
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/arch/powerpc/util/book3s_hv_exits.h1
-rw-r--r--tools/perf/util/probe-event.c39
-rw-r--r--tools/perf/util/probe-event.h1
-rw-r--r--tools/perf/util/probe-file.c34
-rw-r--r--tools/perf/util/probe-file.h1
-rw-r--r--tools/perf/util/symbol-elf.c46
-rw-r--r--tools/perf/util/symbol.h7
7 files changed, 106 insertions, 23 deletions
diff --git a/tools/perf/arch/powerpc/util/book3s_hv_exits.h b/tools/perf/arch/powerpc/util/book3s_hv_exits.h
index 853b95d1e139..2011376c7ab5 100644
--- a/tools/perf/arch/powerpc/util/book3s_hv_exits.h
+++ b/tools/perf/arch/powerpc/util/book3s_hv_exits.h
@@ -15,7 +15,6 @@
15 {0x400, "INST_STORAGE"}, \ 15 {0x400, "INST_STORAGE"}, \
16 {0x480, "INST_SEGMENT"}, \ 16 {0x480, "INST_SEGMENT"}, \
17 {0x500, "EXTERNAL"}, \ 17 {0x500, "EXTERNAL"}, \
18 {0x501, "EXTERNAL_LEVEL"}, \
19 {0x502, "EXTERNAL_HV"}, \ 18 {0x502, "EXTERNAL_HV"}, \
20 {0x600, "ALIGNMENT"}, \ 19 {0x600, "ALIGNMENT"}, \
21 {0x700, "PROGRAM"}, \ 20 {0x700, "PROGRAM"}, \
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f119eb628dbb..e86f8be89157 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1819,6 +1819,12 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
1819 tp->offset = strtoul(fmt2_str, NULL, 10); 1819 tp->offset = strtoul(fmt2_str, NULL, 10);
1820 } 1820 }
1821 1821
1822 if (tev->uprobes) {
1823 fmt2_str = strchr(p, '(');
1824 if (fmt2_str)
1825 tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0);
1826 }
1827
1822 tev->nargs = argc - 2; 1828 tev->nargs = argc - 2;
1823 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1829 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1824 if (tev->args == NULL) { 1830 if (tev->args == NULL) {
@@ -2012,6 +2018,22 @@ static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
2012 return err; 2018 return err;
2013} 2019}
2014 2020
2021static int
2022synthesize_uprobe_trace_def(struct probe_trace_event *tev, struct strbuf *buf)
2023{
2024 struct probe_trace_point *tp = &tev->point;
2025 int err;
2026
2027 err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address);
2028
2029 if (err >= 0 && tp->ref_ctr_offset) {
2030 if (!uprobe_ref_ctr_is_supported())
2031 return -1;
2032 err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset);
2033 }
2034 return err >= 0 ? 0 : -1;
2035}
2036
2015char *synthesize_probe_trace_command(struct probe_trace_event *tev) 2037char *synthesize_probe_trace_command(struct probe_trace_event *tev)
2016{ 2038{
2017 struct probe_trace_point *tp = &tev->point; 2039 struct probe_trace_point *tp = &tev->point;
@@ -2041,15 +2063,17 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
2041 } 2063 }
2042 2064
2043 /* Use the tp->address for uprobes */ 2065 /* Use the tp->address for uprobes */
2044 if (tev->uprobes) 2066 if (tev->uprobes) {
2045 err = strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address); 2067 err = synthesize_uprobe_trace_def(tev, &buf);
2046 else if (!strncmp(tp->symbol, "0x", 2)) 2068 } else if (!strncmp(tp->symbol, "0x", 2)) {
2047 /* Absolute address. See try_to_find_absolute_address() */ 2069 /* Absolute address. See try_to_find_absolute_address() */
2048 err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "", 2070 err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "",
2049 tp->module ? ":" : "", tp->address); 2071 tp->module ? ":" : "", tp->address);
2050 else 2072 } else {
2051 err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "", 2073 err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "",
2052 tp->module ? ":" : "", tp->symbol, tp->offset); 2074 tp->module ? ":" : "", tp->symbol, tp->offset);
2075 }
2076
2053 if (err) 2077 if (err)
2054 goto error; 2078 goto error;
2055 2079
@@ -2633,6 +2657,13 @@ static void warn_uprobe_event_compat(struct probe_trace_event *tev)
2633{ 2657{
2634 int i; 2658 int i;
2635 char *buf = synthesize_probe_trace_command(tev); 2659 char *buf = synthesize_probe_trace_command(tev);
2660 struct probe_trace_point *tp = &tev->point;
2661
2662 if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) {
2663 pr_warning("A semaphore is associated with %s:%s and "
2664 "seems your kernel doesn't support it.\n",
2665 tev->group, tev->event);
2666 }
2636 2667
2637 /* Old uprobe event doesn't support memory dereference */ 2668 /* Old uprobe event doesn't support memory dereference */
2638 if (!tev->uprobes || tev->nargs == 0 || !buf) 2669 if (!tev->uprobes || tev->nargs == 0 || !buf)
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 45b14f020558..15a98c3a2a2f 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -27,6 +27,7 @@ struct probe_trace_point {
27 char *symbol; /* Base symbol */ 27 char *symbol; /* Base symbol */
28 char *module; /* Module name */ 28 char *module; /* Module name */
29 unsigned long offset; /* Offset from symbol */ 29 unsigned long offset; /* Offset from symbol */
30 unsigned long ref_ctr_offset; /* SDT reference counter offset */
30 unsigned long address; /* Actual address of the trace point */ 31 unsigned long address; /* Actual address of the trace point */
31 bool retprobe; /* Return probe flag */ 32 bool retprobe; /* Return probe flag */
32}; 33};
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index b76088fadf3d..aac7817d9e14 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -696,8 +696,16 @@ out_err:
696#ifdef HAVE_GELF_GETNOTE_SUPPORT 696#ifdef HAVE_GELF_GETNOTE_SUPPORT
697static unsigned long long sdt_note__get_addr(struct sdt_note *note) 697static unsigned long long sdt_note__get_addr(struct sdt_note *note)
698{ 698{
699 return note->bit32 ? (unsigned long long)note->addr.a32[0] 699 return note->bit32 ?
700 : (unsigned long long)note->addr.a64[0]; 700 (unsigned long long)note->addr.a32[SDT_NOTE_IDX_LOC] :
701 (unsigned long long)note->addr.a64[SDT_NOTE_IDX_LOC];
702}
703
704static unsigned long long sdt_note__get_ref_ctr_offset(struct sdt_note *note)
705{
706 return note->bit32 ?
707 (unsigned long long)note->addr.a32[SDT_NOTE_IDX_REFCTR] :
708 (unsigned long long)note->addr.a64[SDT_NOTE_IDX_REFCTR];
701} 709}
702 710
703static const char * const type_to_suffix[] = { 711static const char * const type_to_suffix[] = {
@@ -775,14 +783,21 @@ static char *synthesize_sdt_probe_command(struct sdt_note *note,
775{ 783{
776 struct strbuf buf; 784 struct strbuf buf;
777 char *ret = NULL, **args; 785 char *ret = NULL, **args;
778 int i, args_count; 786 int i, args_count, err;
787 unsigned long long ref_ctr_offset;
779 788
780 if (strbuf_init(&buf, 32) < 0) 789 if (strbuf_init(&buf, 32) < 0)
781 return NULL; 790 return NULL;
782 791
783 if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", 792 err = strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
784 sdtgrp, note->name, pathname, 793 sdtgrp, note->name, pathname,
785 sdt_note__get_addr(note)) < 0) 794 sdt_note__get_addr(note));
795
796 ref_ctr_offset = sdt_note__get_ref_ctr_offset(note);
797 if (ref_ctr_offset && err >= 0)
798 err = strbuf_addf(&buf, "(0x%llx)", ref_ctr_offset);
799
800 if (err < 0)
786 goto error; 801 goto error;
787 802
788 if (!note->args) 803 if (!note->args)
@@ -998,6 +1013,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)
998enum ftrace_readme { 1013enum ftrace_readme {
999 FTRACE_README_PROBE_TYPE_X = 0, 1014 FTRACE_README_PROBE_TYPE_X = 0,
1000 FTRACE_README_KRETPROBE_OFFSET, 1015 FTRACE_README_KRETPROBE_OFFSET,
1016 FTRACE_README_UPROBE_REF_CTR,
1001 FTRACE_README_END, 1017 FTRACE_README_END,
1002}; 1018};
1003 1019
@@ -1009,6 +1025,7 @@ static struct {
1009 [idx] = {.pattern = pat, .avail = false} 1025 [idx] = {.pattern = pat, .avail = false}
1010 DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"), 1026 DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
1011 DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"), 1027 DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
1028 DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"),
1012}; 1029};
1013 1030
1014static bool scan_ftrace_readme(enum ftrace_readme type) 1031static bool scan_ftrace_readme(enum ftrace_readme type)
@@ -1064,3 +1081,8 @@ bool kretprobe_offset_is_supported(void)
1064{ 1081{
1065 return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET); 1082 return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
1066} 1083}
1084
1085bool uprobe_ref_ctr_is_supported(void)
1086{
1087 return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR);
1088}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index 63f29b1d22c1..2a249182f2a6 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -69,6 +69,7 @@ struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache,
69int probe_cache__show_all_caches(struct strfilter *filter); 69int probe_cache__show_all_caches(struct strfilter *filter);
70bool probe_type_is_available(enum probe_type type); 70bool probe_type_is_available(enum probe_type type);
71bool kretprobe_offset_is_supported(void); 71bool kretprobe_offset_is_supported(void);
72bool uprobe_ref_ctr_is_supported(void);
72#else /* ! HAVE_LIBELF_SUPPORT */ 73#else /* ! HAVE_LIBELF_SUPPORT */
73static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused) 74static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused)
74{ 75{
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 29770ea61768..0281d5e2cd67 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1947,6 +1947,34 @@ void kcore_extract__delete(struct kcore_extract *kce)
1947} 1947}
1948 1948
1949#ifdef HAVE_GELF_GETNOTE_SUPPORT 1949#ifdef HAVE_GELF_GETNOTE_SUPPORT
1950
1951static void sdt_adjust_loc(struct sdt_note *tmp, GElf_Addr base_off)
1952{
1953 if (!base_off)
1954 return;
1955
1956 if (tmp->bit32)
1957 tmp->addr.a32[SDT_NOTE_IDX_LOC] =
1958 tmp->addr.a32[SDT_NOTE_IDX_LOC] + base_off -
1959 tmp->addr.a32[SDT_NOTE_IDX_BASE];
1960 else
1961 tmp->addr.a64[SDT_NOTE_IDX_LOC] =
1962 tmp->addr.a64[SDT_NOTE_IDX_LOC] + base_off -
1963 tmp->addr.a64[SDT_NOTE_IDX_BASE];
1964}
1965
1966static void sdt_adjust_refctr(struct sdt_note *tmp, GElf_Addr base_addr,
1967 GElf_Addr base_off)
1968{
1969 if (!base_off)
1970 return;
1971
1972 if (tmp->bit32 && tmp->addr.a32[SDT_NOTE_IDX_REFCTR])
1973 tmp->addr.a32[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
1974 else if (tmp->addr.a64[SDT_NOTE_IDX_REFCTR])
1975 tmp->addr.a64[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
1976}
1977
1950/** 1978/**
1951 * populate_sdt_note : Parse raw data and identify SDT note 1979 * populate_sdt_note : Parse raw data and identify SDT note
1952 * @elf: elf of the opened file 1980 * @elf: elf of the opened file
@@ -1964,7 +1992,6 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
1964 const char *provider, *name, *args; 1992 const char *provider, *name, *args;
1965 struct sdt_note *tmp = NULL; 1993 struct sdt_note *tmp = NULL;
1966 GElf_Ehdr ehdr; 1994 GElf_Ehdr ehdr;
1967 GElf_Addr base_off = 0;
1968 GElf_Shdr shdr; 1995 GElf_Shdr shdr;
1969 int ret = -EINVAL; 1996 int ret = -EINVAL;
1970 1997
@@ -2060,17 +2087,12 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
2060 * base address in the description of the SDT note. If its different, 2087 * base address in the description of the SDT note. If its different,
2061 * then accordingly, adjust the note location. 2088 * then accordingly, adjust the note location.
2062 */ 2089 */
2063 if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL)) { 2090 if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL))
2064 base_off = shdr.sh_offset; 2091 sdt_adjust_loc(tmp, shdr.sh_offset);
2065 if (base_off) { 2092
2066 if (tmp->bit32) 2093 /* Adjust reference counter offset */
2067 tmp->addr.a32[0] = tmp->addr.a32[0] + base_off - 2094 if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_PROBES_SCN, NULL))
2068 tmp->addr.a32[1]; 2095 sdt_adjust_refctr(tmp, shdr.sh_addr, shdr.sh_offset);
2069 else
2070 tmp->addr.a64[0] = tmp->addr.a64[0] + base_off -
2071 tmp->addr.a64[1];
2072 }
2073 }
2074 2096
2075 list_add_tail(&tmp->note_list, sdt_notes); 2097 list_add_tail(&tmp->note_list, sdt_notes);
2076 return 0; 2098 return 0;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index f25fae4b5743..20f49779116b 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -379,12 +379,19 @@ int get_sdt_note_list(struct list_head *head, const char *target);
379int cleanup_sdt_note_list(struct list_head *sdt_notes); 379int cleanup_sdt_note_list(struct list_head *sdt_notes);
380int sdt_notes__get_count(struct list_head *start); 380int sdt_notes__get_count(struct list_head *start);
381 381
382#define SDT_PROBES_SCN ".probes"
382#define SDT_BASE_SCN ".stapsdt.base" 383#define SDT_BASE_SCN ".stapsdt.base"
383#define SDT_NOTE_SCN ".note.stapsdt" 384#define SDT_NOTE_SCN ".note.stapsdt"
384#define SDT_NOTE_TYPE 3 385#define SDT_NOTE_TYPE 3
385#define SDT_NOTE_NAME "stapsdt" 386#define SDT_NOTE_NAME "stapsdt"
386#define NR_ADDR 3 387#define NR_ADDR 3
387 388
389enum {
390 SDT_NOTE_IDX_LOC = 0,
391 SDT_NOTE_IDX_BASE,
392 SDT_NOTE_IDX_REFCTR,
393};
394
388struct mem_info *mem_info__new(void); 395struct mem_info *mem_info__new(void);
389struct mem_info *mem_info__get(struct mem_info *mi); 396struct mem_info *mem_info__get(struct mem_info *mi);
390void mem_info__put(struct mem_info *mi); 397void mem_info__put(struct mem_info *mi);