* [PATCH 0/2] perf: add support of SDT probes arguments @ 2016-11-16 23:55 Alexis Berlemont 2016-11-16 23:56 ` [PATCH 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2016-11-16 23:56 ` [PATCH 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 0 siblings, 2 replies; 77+ messages in thread From: Alexis Berlemont @ 2016-11-16 23:55 UTC (permalink / raw) To: linux-kernel; +Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin Hi, In the perf todo list (https://perf.wiki.kernel.org/index.php/Todo), there is an entry related with SDT markers support; SDT tracepoints were already supported by perf but, so far, the probes arguments are skipped. Here are 2 small patches which adds support of SDT probes arguments: $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt $ perf script test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 The patches were generated against tip/perf/core. Alexis. Alexis Berlemont (2): perf sdt: add scanning of sdt probles arguments perf probe: add sdt probes arguments into the uprobe cmd string tools/perf/util/probe-file.c | 176 ++++++++++++++++++++++++++++++++++++++++++- tools/perf/util/symbol-elf.c | 16 +++- tools/perf/util/symbol.h | 1 + 3 files changed, 188 insertions(+), 5 deletions(-) -- 2.10.2 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH 1/2] perf sdt: add scanning of sdt probles arguments 2016-11-16 23:55 [PATCH 0/2] perf: add support of SDT probes arguments Alexis Berlemont @ 2016-11-16 23:56 ` Alexis Berlemont 2016-11-16 23:56 ` [PATCH 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 1 sibling, 0 replies; 77+ messages in thread From: Alexis Berlemont @ 2016-11-16 23:56 UTC (permalink / raw) To: linux-kernel; +Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin During a "perf buildid-cache --add" command, the section ".note.stapsdt" of the "added" binary is scanned in order to list the available SDT markers available in a binary. The parts containing the probes arguments were left unscanned. The whole section is now parsed; the probe arguments are extracted for later use. Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/util/symbol-elf.c | 16 +++++++++++++++- tools/perf/util/symbol.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 99400b0..0fbe0b2 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1822,7 +1822,7 @@ void kcore_extract__delete(struct kcore_extract *kce) static int populate_sdt_note(Elf **elf, const char *data, size_t len, struct list_head *sdt_notes) { - const char *provider, *name; + const char *provider, *name, *args; struct sdt_note *tmp = NULL; GElf_Ehdr ehdr; GElf_Addr base_off = 0; @@ -1881,6 +1881,20 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, goto out_free_prov; } + args = (const char *)memchr(name, '\0', data + len - name); + + /* + * There is no argument if: + * - We reached the end of the note; + * - There is not enough room to hold a potential string; + * - The argument string is empty or just contains ':'. + */ + if (args == NULL || data + len - args < 2 || + args[1] == ':' || args[1] == '\0') + tmp->args = NULL; + else + tmp->args = strdup(++args); + if (gelf_getclass(*elf) == ELFCLASS32) { memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); tmp->bit32 = true; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2d0a905..913be07 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -347,6 +347,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); struct sdt_note { char *name; /* name of the note*/ char *provider; /* provider name */ + char *args; bool bit32; /* whether the location is 32 bits? */ union { /* location, base and semaphore addrs */ Elf64_Addr a64[3]; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* [PATCH 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-16 23:55 [PATCH 0/2] perf: add support of SDT probes arguments Alexis Berlemont 2016-11-16 23:56 ` [PATCH 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont @ 2016-11-16 23:56 ` Alexis Berlemont 2016-11-17 9:04 ` Hemant Kumar 1 sibling, 1 reply; 77+ messages in thread From: Alexis Berlemont @ 2016-11-16 23:56 UTC (permalink / raw) To: linux-kernel; +Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin An sdt probe can be associated with arguments but they were not passed to the user probe tracing interface (uprobe_events); this patch adapts the sdt argument descriptors according to the uprobe input format. As the uprobe parser does not support scaled address mode, perf will skip arguments which cannot be adapted to the uprobe format. Here are the results: $ perf buildid-cache -v --add test_sdt $ perf probe -x test_sdt sdt_libfoo:table_frob $ perf probe -x test_sdt sdt_libfoo:table_diddle $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt $ perf script test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/util/probe-file.c | 176 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 172 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 436b647..a97a170 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -28,6 +28,46 @@ #include "probe-file.h" #include "session.h" +#ifdef HAVE_GELF_GETNOTE_SUPPORT + +/* + * Local declarations needed for adjusting gcc/gas-generated registers + * before filling the uprobe tracer interface. + */ + +struct sdt_reg_renaming { + const char *sdt_name; + const char *uprobe_name; +}; + +#define REG_RENAMING(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} +#define REG_RENAMING_END {.sdt_name = NULL, .uprobe_name = NULL} + +static const struct sdt_reg_renaming sdt_reg_renaming_table[] = { + REG_RENAMING(eax, ax), + REG_RENAMING(rax, ax), + REG_RENAMING(ebx, bx), + REG_RENAMING(rbx, bx), + REG_RENAMING(ecx, cx), + REG_RENAMING(rcx, cx), + REG_RENAMING(edx, dx), + REG_RENAMING(rdx, dx), + REG_RENAMING(esi, si), + REG_RENAMING(rsi, si), + REG_RENAMING(edi, di), + REG_RENAMING(rdi, di), + REG_RENAMING(ebp, bp), + REG_RENAMING(rbp, bp), + REG_RENAMING_END, +}; + +static const char * const type_to_suffix[] = { + ":s64", "", "", "", ":s32", "", ":s16", ":s8", + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" +}; + +#endif /* HAVE_GELF_GETNOTE_SUPPORT */ + #define MAX_CMDLEN 256 static void print_open_warning(int err, bool uprobe) @@ -687,6 +727,133 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) : (unsigned long long)note->addr.a64[0]; } +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) +{ + const struct sdt_reg_renaming *rnames; + char *tmp, *desc = strdup(arg); + const char *suffix = ""; + int ret = -1; + + if (desc == NULL) { + pr_debug4("Allocation error\n"); + return ret; + } + + /* + * The uprobe tracer format does not support all the + * addressing modes (notably: in x86 the scaled mode); so, we + * detect ',' characters, if there is just one, there is no + * use converting the sdt arg into a uprobe one. + */ + if (strchr(desc, ',')) { + pr_debug4("SDT argument format not supported\n"); + goto out; + } + + tmp = strchr(desc, '@'); + if (tmp) { + long type_idx; + /* + * Isolate the string number and convert it into a + * binary value; this will be an index to get suffix + * of the uprobe name (defining the type) + */ + tmp[0] = '\0'; + type_idx = strtol(desc, NULL, 10); + if (type_idx == LONG_MIN || + type_idx == LONG_MAX) { + pr_debug4("Failed to get sdt type\n"); + goto error; + } + suffix = type_to_suffix[type_idx + 8]; + /* Get rid of the sdt prefix which is now useless */ + tmp++; + memmove(desc, tmp, strlen(tmp) + 1); + } + + /* + * The uprobe parser does not support all gas register names; + * so, we have to replace them (ex. for x86_64: %rax -> %ax); + * the loop below performs all the needed renamings if needed. + */ + + for (rnames = sdt_reg_renaming_table; + rnames->sdt_name != NULL; rnames++) { + char *new_desc, *sdt_name; + size_t prefix_len, uprobe_len, mid_ofs, desc_len; + + sdt_name = strstr(desc, rnames->sdt_name); + if (sdt_name == NULL) + continue; + + new_desc = zalloc(strlen(desc) + 1 + + strlen(rnames->uprobe_name) - + strlen(rnames->sdt_name)); + if (new_desc == NULL) + goto error; + + prefix_len = sdt_name - desc; + if (prefix_len != 0) + memcpy(new_desc, desc, prefix_len); + + uprobe_len = strlen(rnames->uprobe_name); + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); + + mid_ofs = prefix_len + strlen(rnames->sdt_name); + desc_len = strlen(desc); + if (mid_ofs < desc_len) + memcpy(new_desc + prefix_len + uprobe_len, + desc + mid_ofs, desc_len - mid_ofs); + + free(desc); + desc = new_desc; + } + + if (strbuf_addf(buf, " arg%d=%s%s", i, desc, suffix) < 0) + goto error; + +out: + ret = 0; +error: + free(desc); + return ret; +} + +static char *synthesize_sdt_probe_command(struct sdt_note *note, + const char *pathname, + const char *sdtgrp) +{ + struct strbuf buf; + char *ret = NULL, **args; + int i, args_count; + + if (strbuf_init(&buf, 32) < 0) + return NULL; + + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", + sdtgrp, note->name, pathname, + sdt_note__get_addr(note)) < 0) + goto error; + + if (!note->args) + goto out; + + if (note->args) { + args = argv_split(note->args, &args_count); + + for (i = 0; i < args_count; ++i) { + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) + goto error; + } + } + +out: + ret = strbuf_detach(&buf, NULL); +error: + strbuf_release(&buf); + return ret; +} + int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) { struct probe_cache_entry *entry = NULL; @@ -723,11 +890,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) entry->pev.group = strdup(sdtgrp); list_add_tail(&entry->node, &pcache->entries); } - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", - sdtgrp, note->name, pathname, - sdt_note__get_addr(note)); - if (ret < 0) + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); + if (!buf) { + ret = -ENOMEM; break; + } + strlist__add(entry->tevlist, buf); free(buf); entry = NULL; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-16 23:56 ` [PATCH 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont @ 2016-11-17 9:04 ` Hemant Kumar 2016-11-18 23:56 ` [PATCH v2 0/2] " Alexis Berlemont ` (2 more replies) 0 siblings, 3 replies; 77+ messages in thread From: Hemant Kumar @ 2016-11-17 9:04 UTC (permalink / raw) To: Alexis Berlemont, linux-kernel; +Cc: peterz, mingo, acme, alexander.shishkin Hi Alexis, On 11/17/2016 05:26 AM, Alexis Berlemont wrote: > An sdt probe can be associated with arguments but they were not passed > to the user probe tracing interface (uprobe_events); this patch adapts > the sdt argument descriptors according to the uprobe input format. > > As the uprobe parser does not support scaled address mode, perf will > skip arguments which cannot be adapted to the uprobe format. > > Here are the results: > > $ perf buildid-cache -v --add test_sdt > $ perf probe -x test_sdt sdt_libfoo:table_frob > $ perf probe -x test_sdt sdt_libfoo:table_diddle > $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt > $ perf script > test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 > test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 > test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 > test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 > test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 > test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 Cool! Thanks for working on this. I have a comment below. > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > --- > tools/perf/util/probe-file.c | 176 ++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 172 insertions(+), 4 deletions(-) > > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index 436b647..a97a170 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -28,6 +28,46 @@ > #include "probe-file.h" > #include "session.h" > > +#ifdef HAVE_GELF_GETNOTE_SUPPORT > + > +/* > + * Local declarations needed for adjusting gcc/gas-generated registers > + * before filling the uprobe tracer interface. > + */ > + > +struct sdt_reg_renaming { > + const char *sdt_name; > + const char *uprobe_name; > +}; > + > +#define REG_RENAMING(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} > +#define REG_RENAMING_END {.sdt_name = NULL, .uprobe_name = NULL} > + > +static const struct sdt_reg_renaming sdt_reg_renaming_table[] = { > + REG_RENAMING(eax, ax), > + REG_RENAMING(rax, ax), > + REG_RENAMING(ebx, bx), > + REG_RENAMING(rbx, bx), > + REG_RENAMING(ecx, cx), > + REG_RENAMING(rcx, cx), > + REG_RENAMING(edx, dx), > + REG_RENAMING(rdx, dx), > + REG_RENAMING(esi, si), > + REG_RENAMING(rsi, si), > + REG_RENAMING(edi, di), > + REG_RENAMING(rdi, di), > + REG_RENAMING(ebp, bp), > + REG_RENAMING(rbp, bp), > + REG_RENAMING_END, > +}; Please put the above in arch helper headers for x86, as these register names and their conversions are specific to x86. [SNIP] -- Thanks, Hemant Kumar ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v2 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-17 9:04 ` Hemant Kumar @ 2016-11-18 23:56 ` Alexis Berlemont 2016-11-18 23:56 ` [PATCH v2 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2016-11-18 23:56 ` [PATCH v2 2/2] perf probe: add " Alexis Berlemont 2 siblings, 0 replies; 77+ messages in thread From: Alexis Berlemont @ 2016-11-18 23:56 UTC (permalink / raw) To: linux-kernel Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin, hemant Hi Hemant, Many thanks for your answer. Here is another proposal in which the x86 register renaming table has been moved into the x86-specific part. Thanks, Alexis. Alexis Berlemont (2): perf sdt: add scanning of sdt probles arguments perf probe: add sdt probes arguments into the uprobe cmd string tools/perf/arch/x86/util/perf_regs.c | 18 +++++ tools/perf/util/perf_regs.c | 4 + tools/perf/util/perf_regs.h | 13 ++++ tools/perf/util/probe-file.c | 141 ++++++++++++++++++++++++++++++++++- tools/perf/util/symbol-elf.c | 16 +++- tools/perf/util/symbol.h | 1 + 6 files changed, 188 insertions(+), 5 deletions(-) -- 2.10.2 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v2 1/2] perf sdt: add scanning of sdt probles arguments 2016-11-17 9:04 ` Hemant Kumar 2016-11-18 23:56 ` [PATCH v2 0/2] " Alexis Berlemont @ 2016-11-18 23:56 ` Alexis Berlemont 2016-11-25 14:40 ` Arnaldo Carvalho de Melo 2016-11-18 23:56 ` [PATCH v2 2/2] perf probe: add " Alexis Berlemont 2 siblings, 1 reply; 77+ messages in thread From: Alexis Berlemont @ 2016-11-18 23:56 UTC (permalink / raw) To: linux-kernel Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin, hemant During a "perf buildid-cache --add" command, the section ".note.stapsdt" of the "added" binary is scanned in order to list the available SDT markers available in a binary. The parts containing the probes arguments were left unscanned. The whole section is now parsed; the probe arguments are extracted for later use. Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/util/symbol-elf.c | 16 +++++++++++++++- tools/perf/util/symbol.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 99400b0..0fbe0b2 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1822,7 +1822,7 @@ void kcore_extract__delete(struct kcore_extract *kce) static int populate_sdt_note(Elf **elf, const char *data, size_t len, struct list_head *sdt_notes) { - const char *provider, *name; + const char *provider, *name, *args; struct sdt_note *tmp = NULL; GElf_Ehdr ehdr; GElf_Addr base_off = 0; @@ -1881,6 +1881,20 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, goto out_free_prov; } + args = (const char *)memchr(name, '\0', data + len - name); + + /* + * There is no argument if: + * - We reached the end of the note; + * - There is not enough room to hold a potential string; + * - The argument string is empty or just contains ':'. + */ + if (args == NULL || data + len - args < 2 || + args[1] == ':' || args[1] == '\0') + tmp->args = NULL; + else + tmp->args = strdup(++args); + if (gelf_getclass(*elf) == ELFCLASS32) { memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); tmp->bit32 = true; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2d0a905..913be07 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -347,6 +347,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); struct sdt_note { char *name; /* name of the note*/ char *provider; /* provider name */ + char *args; bool bit32; /* whether the location is 32 bits? */ union { /* location, base and semaphore addrs */ Elf64_Addr a64[3]; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH v2 1/2] perf sdt: add scanning of sdt probles arguments 2016-11-18 23:56 ` [PATCH v2 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont @ 2016-11-25 14:40 ` Arnaldo Carvalho de Melo 2016-11-26 0:58 ` [PATCH v4 0/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont ` (2 more replies) 0 siblings, 3 replies; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2016-11-25 14:40 UTC (permalink / raw) To: Alexis Berlemont; +Cc: linux-kernel, peterz, mingo, alexander.shishkin, hemant Em Sat, Nov 19, 2016 at 12:56:36AM +0100, Alexis Berlemont escreveu: > During a "perf buildid-cache --add" command, the section > ".note.stapsdt" of the "added" binary is scanned in order to list the > available SDT markers available in a binary. The parts containing the > probes arguments were left unscanned. > > The whole section is now parsed; the probe arguments are extracted for > later use. > > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > --- > tools/perf/util/symbol-elf.c | 16 +++++++++++++++- > tools/perf/util/symbol.h | 1 + > 2 files changed, 16 insertions(+), 1 deletion(-) > > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c > index 99400b0..0fbe0b2 100644 > --- a/tools/perf/util/symbol-elf.c > +++ b/tools/perf/util/symbol-elf.c > @@ -1822,7 +1822,7 @@ void kcore_extract__delete(struct kcore_extract *kce) > static int populate_sdt_note(Elf **elf, const char *data, size_t len, > struct list_head *sdt_notes) > { > - const char *provider, *name; > + const char *provider, *name, *args; > struct sdt_note *tmp = NULL; > GElf_Ehdr ehdr; > GElf_Addr base_off = 0; > @@ -1881,6 +1881,20 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > goto out_free_prov; > } > > + args = (const char *)memchr(name, '\0', data + len - name); Humm, no need for casting? > + > + /* > + * There is no argument if: > + * - We reached the end of the note; > + * - There is not enough room to hold a potential string; > + * - The argument string is empty or just contains ':'. > + */ > + if (args == NULL || data + len - args < 2 || > + args[1] == ':' || args[1] == '\0') > + tmp->args = NULL; > + else > + tmp->args = strdup(++args); Shouldn't we check this and do error back propagation? I.e. if there are args and we don't handle them, silently, that looks bad > + > if (gelf_getclass(*elf) == ELFCLASS32) { > memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); > tmp->bit32 = true; > diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h > index 2d0a905..913be07 100644 > --- a/tools/perf/util/symbol.h > +++ b/tools/perf/util/symbol.h > @@ -347,6 +347,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); > struct sdt_note { > char *name; /* name of the note*/ > char *provider; /* provider name */ > + char *args; > bool bit32; /* whether the location is 32 bits? */ > union { /* location, base and semaphore addrs */ > Elf64_Addr a64[3]; > -- > 2.10.2 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-25 14:40 ` Arnaldo Carvalho de Melo @ 2016-11-26 0:58 ` Alexis Berlemont 2016-12-05 23:42 ` Alexis Berlemont 2016-11-26 0:58 ` [PATCH v4 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2016-11-26 0:58 ` [PATCH v4 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2 siblings, 1 reply; 77+ messages in thread From: Alexis Berlemont @ 2016-11-26 0:58 UTC (permalink / raw) To: linux-kernel Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin, hemant Hi Arnaldo, Here is another patch set which fixes the issues you noticed. Thank you. Alexis. Alexis Berlemont (2): perf sdt: add scanning of sdt probles arguments perf probe: add sdt probes arguments into the uprobe cmd string tools/perf/arch/x86/util/perf_regs.c | 18 ++++ tools/perf/util/perf_regs.c | 4 + tools/perf/util/perf_regs.h | 13 +++ tools/perf/util/probe-file.c | 169 ++++++++++++++++++++++++++++++++++- tools/perf/util/symbol-elf.c | 25 +++++- tools/perf/util/symbol.h | 1 + 6 files changed, 224 insertions(+), 6 deletions(-) -- 2.10.2 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v4 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-26 0:58 ` [PATCH v4 0/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont @ 2016-12-05 23:42 ` Alexis Berlemont 2016-12-06 14:45 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 77+ messages in thread From: Alexis Berlemont @ 2016-12-05 23:42 UTC (permalink / raw) To: linux-kernel; +Cc: peterz, mingo, acme, alexander.shishkin, hemant Alexis Berlemont wrote: > Hi Arnaldo, > > Here is another patch set which fixes the issues you noticed. > Could you indicate me a way to improve these patches so as to move forward ? Regards, Alexis. > Thank you. > > Alexis. > > Alexis Berlemont (2): > perf sdt: add scanning of sdt probles arguments > perf probe: add sdt probes arguments into the uprobe cmd string > > tools/perf/arch/x86/util/perf_regs.c | 18 ++++ > tools/perf/util/perf_regs.c | 4 + > tools/perf/util/perf_regs.h | 13 +++ > tools/perf/util/probe-file.c | 169 ++++++++++++++++++++++++++++++++++- > tools/perf/util/symbol-elf.c | 25 +++++- > tools/perf/util/symbol.h | 1 + > 6 files changed, 224 insertions(+), 6 deletions(-) > > -- > 2.10.2 > ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v4 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-05 23:42 ` Alexis Berlemont @ 2016-12-06 14:45 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2016-12-06 14:45 UTC (permalink / raw) To: Alexis Berlemont Cc: linux-kernel, peterz, mingo, alexander.shishkin, hemant, Masami Hiramatsu Em Tue, Dec 06, 2016 at 12:42:45AM +0100, Alexis Berlemont escreveu: > Alexis Berlemont wrote: > > Hi Arnaldo, > > > > Here is another patch set which fixes the issues you noticed. > > > > Could you indicate me a way to improve these patches so as to move > forward ? Masami, Hemant, are you guys ok with this? Can I have your Acked-by or Tested-by, etc? - Arnaldo > Regards, > > Alexis. > > > Thank you. > > > > Alexis. > > > > Alexis Berlemont (2): > > perf sdt: add scanning of sdt probles arguments > > perf probe: add sdt probes arguments into the uprobe cmd string > > > > tools/perf/arch/x86/util/perf_regs.c | 18 ++++ > > tools/perf/util/perf_regs.c | 4 + > > tools/perf/util/perf_regs.h | 13 +++ > > tools/perf/util/probe-file.c | 169 ++++++++++++++++++++++++++++++++++- > > tools/perf/util/symbol-elf.c | 25 +++++- > > tools/perf/util/symbol.h | 1 + > > 6 files changed, 224 insertions(+), 6 deletions(-) > > > > -- > > 2.10.2 > > ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 1/2] perf sdt: add scanning of sdt probles arguments 2016-11-25 14:40 ` Arnaldo Carvalho de Melo 2016-11-26 0:58 ` [PATCH v4 0/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont @ 2016-11-26 0:58 ` Alexis Berlemont 2016-12-07 2:44 ` Masami Hiramatsu 2016-11-26 0:58 ` [PATCH v4 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2 siblings, 1 reply; 77+ messages in thread From: Alexis Berlemont @ 2016-11-26 0:58 UTC (permalink / raw) To: linux-kernel Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin, hemant During a "perf buildid-cache --add" command, the section ".note.stapsdt" of the "added" binary is scanned in order to list the available SDT markers available in a binary. The parts containing the probes arguments were left unscanned. The whole section is now parsed; the probe arguments are extracted for later use. Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/util/symbol-elf.c | 25 +++++++++++++++++++++++-- tools/perf/util/symbol.h | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 99400b0..7725c3f 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1822,7 +1822,7 @@ void kcore_extract__delete(struct kcore_extract *kce) static int populate_sdt_note(Elf **elf, const char *data, size_t len, struct list_head *sdt_notes) { - const char *provider, *name; + const char *provider, *name, *args; struct sdt_note *tmp = NULL; GElf_Ehdr ehdr; GElf_Addr base_off = 0; @@ -1881,6 +1881,25 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, goto out_free_prov; } + args = memchr(name, '\0', data + len - name); + + /* + * There is no argument if: + * - We reached the end of the note; + * - There is not enough room to hold a potential string; + * - The argument string is empty or just contains ':'. + */ + if (args == NULL || data + len - args < 2 || + args[1] == ':' || args[1] == '\0') + tmp->args = NULL; + else { + tmp->args = strdup(++args); + if (!tmp->args) { + ret = -ENOMEM; + goto out_free_name; + } + } + if (gelf_getclass(*elf) == ELFCLASS32) { memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); tmp->bit32 = true; @@ -1892,7 +1911,7 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, if (!gelf_getehdr(*elf, &ehdr)) { pr_debug("%s : cannot get elf header.\n", __func__); ret = -EBADF; - goto out_free_name; + goto out_free_args; } /* Adjust the prelink effect : @@ -1917,6 +1936,8 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, list_add_tail(&tmp->note_list, sdt_notes); return 0; +out_free_args: + free(tmp->args); out_free_name: free(tmp->name); out_free_prov: diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index dec7e2d4..db1953e 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -348,6 +348,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); struct sdt_note { char *name; /* name of the note*/ char *provider; /* provider name */ + char *args; bool bit32; /* whether the location is 32 bits? */ union { /* location, base and semaphore addrs */ Elf64_Addr a64[3]; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH v4 1/2] perf sdt: add scanning of sdt probles arguments 2016-11-26 0:58 ` [PATCH v4 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont @ 2016-12-07 2:44 ` Masami Hiramatsu 0 siblings, 0 replies; 77+ messages in thread From: Masami Hiramatsu @ 2016-12-07 2:44 UTC (permalink / raw) To: Alexis Berlemont Cc: linux-kernel, peterz, mingo, acme, alexander.shishkin, hemant On Sat, 26 Nov 2016 01:58:02 +0100 Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > During a "perf buildid-cache --add" command, the section > ".note.stapsdt" of the "added" binary is scanned in order to list the > available SDT markers available in a binary. The parts containing the > probes arguments were left unscanned. > > The whole section is now parsed; the probe arguments are extracted for > later use. > Looks OK for me :) Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Thanks! > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > --- > tools/perf/util/symbol-elf.c | 25 +++++++++++++++++++++++-- > tools/perf/util/symbol.h | 1 + > 2 files changed, 24 insertions(+), 2 deletions(-) > > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c > index 99400b0..7725c3f 100644 > --- a/tools/perf/util/symbol-elf.c > +++ b/tools/perf/util/symbol-elf.c > @@ -1822,7 +1822,7 @@ void kcore_extract__delete(struct kcore_extract *kce) > static int populate_sdt_note(Elf **elf, const char *data, size_t len, > struct list_head *sdt_notes) > { > - const char *provider, *name; > + const char *provider, *name, *args; > struct sdt_note *tmp = NULL; > GElf_Ehdr ehdr; > GElf_Addr base_off = 0; > @@ -1881,6 +1881,25 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > goto out_free_prov; > } > > + args = memchr(name, '\0', data + len - name); > + > + /* > + * There is no argument if: > + * - We reached the end of the note; > + * - There is not enough room to hold a potential string; > + * - The argument string is empty or just contains ':'. > + */ > + if (args == NULL || data + len - args < 2 || > + args[1] == ':' || args[1] == '\0') > + tmp->args = NULL; > + else { > + tmp->args = strdup(++args); > + if (!tmp->args) { > + ret = -ENOMEM; > + goto out_free_name; > + } > + } > + > if (gelf_getclass(*elf) == ELFCLASS32) { > memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); > tmp->bit32 = true; > @@ -1892,7 +1911,7 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > if (!gelf_getehdr(*elf, &ehdr)) { > pr_debug("%s : cannot get elf header.\n", __func__); > ret = -EBADF; > - goto out_free_name; > + goto out_free_args; > } > > /* Adjust the prelink effect : > @@ -1917,6 +1936,8 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > list_add_tail(&tmp->note_list, sdt_notes); > return 0; > > +out_free_args: > + free(tmp->args); > out_free_name: > free(tmp->name); > out_free_prov: > diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h > index dec7e2d4..db1953e 100644 > --- a/tools/perf/util/symbol.h > +++ b/tools/perf/util/symbol.h > @@ -348,6 +348,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); > struct sdt_note { > char *name; /* name of the note*/ > char *provider; /* provider name */ > + char *args; > bool bit32; /* whether the location is 32 bits? */ > union { /* location, base and semaphore addrs */ > Elf64_Addr a64[3]; > -- > 2.10.2 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-25 14:40 ` Arnaldo Carvalho de Melo 2016-11-26 0:58 ` [PATCH v4 0/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2016-11-26 0:58 ` [PATCH v4 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont @ 2016-11-26 0:58 ` Alexis Berlemont 2016-12-07 3:26 ` Masami Hiramatsu 2 siblings, 1 reply; 77+ messages in thread From: Alexis Berlemont @ 2016-11-26 0:58 UTC (permalink / raw) To: linux-kernel Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin, hemant An sdt probe can be associated with arguments but they were not passed to the user probe tracing interface (uprobe_events); this patch adapts the sdt argument descriptors according to the uprobe input format. As the uprobe parser does not support scaled address mode, perf will skip arguments which cannot be adapted to the uprobe format. Here are the results: $ perf buildid-cache -v --add test_sdt $ perf probe -x test_sdt sdt_libfoo:table_frob $ perf probe -x test_sdt sdt_libfoo:table_diddle $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt $ perf script test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/arch/x86/util/perf_regs.c | 18 ++++ tools/perf/util/perf_regs.c | 4 + tools/perf/util/perf_regs.h | 13 +++ tools/perf/util/probe-file.c | 169 ++++++++++++++++++++++++++++++++++- 4 files changed, 200 insertions(+), 4 deletions(-) diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index c5db14f..52a1e65 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -26,3 +26,21 @@ const struct sample_reg sample_reg_masks[] = { #endif SMPL_REG_END }; + +const struct sdt_name_reg sdt_reg_renamings[] = { + SDT_NAME_REG(eax, ax), + SDT_NAME_REG(rax, ax), + SDT_NAME_REG(ebx, bx), + SDT_NAME_REG(rbx, bx), + SDT_NAME_REG(ecx, cx), + SDT_NAME_REG(rcx, cx), + SDT_NAME_REG(edx, dx), + SDT_NAME_REG(rdx, dx), + SDT_NAME_REG(esi, si), + SDT_NAME_REG(rsi, si), + SDT_NAME_REG(edi, di), + SDT_NAME_REG(rdi, di), + SDT_NAME_REG(ebp, bp), + SDT_NAME_REG(rbp, bp), + SDT_NAME_REG_END, +}; diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index c4023f2..1c21150 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -6,6 +6,10 @@ const struct sample_reg __weak sample_reg_masks[] = { SMPL_REG_END }; +const struct sdt_name_reg __weak sdt_reg_renamings[] = { + SDT_NAME_REG_END, +}; + #ifdef HAVE_PERF_REGS_SUPPORT int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) { diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 679d6e4..41815ca 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -15,6 +15,19 @@ struct sample_reg { extern const struct sample_reg sample_reg_masks[]; +struct sdt_name_reg { + const char *sdt_name; + const char *uprobe_name; +}; +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} + +/* + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated + * registers before filling the uprobe tracer interface. + */ +extern const struct sdt_name_reg sdt_reg_renamings[]; + #ifdef HAVE_PERF_REGS_SUPPORT #include <perf_regs.h> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 436b647..75033c7 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -27,6 +27,7 @@ #include "probe-event.h" #include "probe-file.h" #include "session.h" +#include "perf_regs.h" #define MAX_CMDLEN 256 @@ -687,6 +688,165 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) : (unsigned long long)note->addr.a64[0]; } +static const char * const type_to_suffix[] = { + ":s64", "", "", "", ":s32", "", ":s16", ":s8", + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" +}; + +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) +{ + const struct sdt_name_reg *rnames; + char *tmp, *desc = strdup(arg); + const char *prefix = "", *suffix = ""; + int ret = -1; + + if (desc == NULL) { + pr_debug4("Allocation error\n"); + return ret; + } + + tmp = strchr(desc, '@'); + if (tmp) { + long type_idx; + /* + * Isolate the string number and convert it into a + * binary value; this will be an index to get suffix + * of the uprobe name (defining the type) + */ + tmp[0] = '\0'; + type_idx = strtol(desc, NULL, 10); + if (type_idx == LONG_MIN || + type_idx == LONG_MAX) { + pr_debug4("Failed to get sdt type\n"); + goto error; + } + suffix = type_to_suffix[type_idx + 8]; + /* Get rid of the sdt prefix which is now useless */ + tmp++; + memmove(desc, tmp, strlen(tmp) + 1); + } + + /* + * The uprobe tracer format does not support all the + * addressing modes (notably: in x86 the scaled mode); so, we + * detect ',' characters, if there is just one, there is no + * use converting the sdt arg into a uprobe one. + */ + if (strchr(desc, ',')) { + pr_debug4("SDT argument format not supported\n"); + goto out; + } + + /* + * If the argument addressing mode is indirect, we must check + * a few things... + */ + tmp = strchr(desc, '('); + if (tmp) { + int j; + + /* + * ...if the addressing mode is indirect with a + * positive offset (ex.: "1608(%ax)"), we need to add + * a '+' prefix so as to be compliant with uprobe + * format. + */ + if (desc[0] != '+' && desc[0] != '-') + prefix = "+"; + + /* + * ...or if the addressing mode is indirect with a symbol + * as offset, the argument will not be supported by + * the uprobe tracer format; so, let's skip this one. + */ + for (j = 0; j < tmp - desc; j++) { + if (desc[j] != '+' && desc[j] != '-' && + !isdigit(desc[j])) + goto out; + } + } + + /* + * The uprobe parser does not support all gas register names; + * so, we have to replace them (ex. for x86_64: %rax -> %ax); + * the loop below performs all the needed renamings if needed. + */ + for (rnames = sdt_reg_renamings; rnames->sdt_name != NULL; rnames++) { + char *new_desc, *sdt_name; + size_t prefix_len, uprobe_len, mid_ofs, desc_len; + + sdt_name = strstr(desc, rnames->sdt_name); + if (sdt_name == NULL) + continue; + + new_desc = zalloc(strlen(desc) + 1 + + strlen(rnames->uprobe_name) - + strlen(rnames->sdt_name)); + if (new_desc == NULL) + goto error; + + prefix_len = sdt_name - desc; + if (prefix_len != 0) + memcpy(new_desc, desc, prefix_len); + + uprobe_len = strlen(rnames->uprobe_name); + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); + + mid_ofs = prefix_len + strlen(rnames->sdt_name); + desc_len = strlen(desc); + if (mid_ofs < desc_len) + memcpy(new_desc + prefix_len + uprobe_len, + desc + mid_ofs, desc_len - mid_ofs); + + free(desc); + desc = new_desc; + } + + if (strbuf_addf(buf, " arg%d=%s%s%s", i, prefix, desc, suffix) < 0) + goto error; + +out: + ret = 0; +error: + free(desc); + return ret; +} + +static char *synthesize_sdt_probe_command(struct sdt_note *note, + const char *pathname, + const char *sdtgrp) +{ + struct strbuf buf; + char *ret = NULL, **args; + int i, args_count; + + if (strbuf_init(&buf, 32) < 0) + return NULL; + + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", + sdtgrp, note->name, pathname, + sdt_note__get_addr(note)) < 0) + goto error; + + if (!note->args) + goto out; + + if (note->args) { + args = argv_split(note->args, &args_count); + + for (i = 0; i < args_count; ++i) { + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) + goto error; + } + } + +out: + ret = strbuf_detach(&buf, NULL); +error: + strbuf_release(&buf); + return ret; +} + int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) { struct probe_cache_entry *entry = NULL; @@ -723,11 +883,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) entry->pev.group = strdup(sdtgrp); list_add_tail(&entry->node, &pcache->entries); } - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", - sdtgrp, note->name, pathname, - sdt_note__get_addr(note)); - if (ret < 0) + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); + if (!buf) { + ret = -ENOMEM; break; + } + strlist__add(entry->tevlist, buf); free(buf); entry = NULL; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH v4 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-26 0:58 ` [PATCH v4 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont @ 2016-12-07 3:26 ` Masami Hiramatsu 2016-12-09 15:14 ` Arnaldo Carvalho de Melo ` (3 more replies) 0 siblings, 4 replies; 77+ messages in thread From: Masami Hiramatsu @ 2016-12-07 3:26 UTC (permalink / raw) To: Alexis Berlemont Cc: linux-kernel, peterz, mingo, acme, alexander.shishkin, hemant Hello Alexis, On Sat, 26 Nov 2016 01:58:03 +0100 Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > An sdt probe can be associated with arguments but they were not passed > to the user probe tracing interface (uprobe_events); this patch adapts > the sdt argument descriptors according to the uprobe input format. Great! > > As the uprobe parser does not support scaled address mode, perf will > skip arguments which cannot be adapted to the uprobe format. OK, it seems that skipping argument is a good idea :) I just tried to support fixed-number arguments in probe events, but skipping it is better with older kernel. I have some comments. > Here are the results: > > $ perf buildid-cache -v --add test_sdt > $ perf probe -x test_sdt sdt_libfoo:table_frob > $ perf probe -x test_sdt sdt_libfoo:table_diddle > $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt > $ perf script > test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 > test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 > test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 > test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 > test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 > test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 We'd better start with arg1, since sdt.h and original Dtrace SDT starts arguments from arg1 (I'm not sure why) and dtrace/systemtap scripts call it "arg1". > > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > --- > tools/perf/arch/x86/util/perf_regs.c | 18 ++++ > tools/perf/util/perf_regs.c | 4 + > tools/perf/util/perf_regs.h | 13 +++ > tools/perf/util/probe-file.c | 169 ++++++++++++++++++++++++++++++++++- > 4 files changed, 200 insertions(+), 4 deletions(-) > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > index c5db14f..52a1e65 100644 > --- a/tools/perf/arch/x86/util/perf_regs.c > +++ b/tools/perf/arch/x86/util/perf_regs.c > @@ -26,3 +26,21 @@ const struct sample_reg sample_reg_masks[] = { > #endif > SMPL_REG_END > }; > + > +const struct sdt_name_reg sdt_reg_renamings[] = { > + SDT_NAME_REG(eax, ax), > + SDT_NAME_REG(rax, ax), > + SDT_NAME_REG(ebx, bx), > + SDT_NAME_REG(rbx, bx), > + SDT_NAME_REG(ecx, cx), > + SDT_NAME_REG(rcx, cx), > + SDT_NAME_REG(edx, dx), > + SDT_NAME_REG(rdx, dx), > + SDT_NAME_REG(esi, si), > + SDT_NAME_REG(rsi, si), > + SDT_NAME_REG(edi, di), > + SDT_NAME_REG(rdi, di), > + SDT_NAME_REG(ebp, bp), > + SDT_NAME_REG(rbp, bp), > + SDT_NAME_REG_END, > +}; It is not enough, rNN registers also have to take care, since gcc adds 'd', 'w' or 'b'suffixes for those registers to indicate its size. e.g. r15d means r15 register with 32 lower bits. What we need is just cut them off, since probe event uses length modifiers (like :u32) > diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c > index c4023f2..1c21150 100644 > --- a/tools/perf/util/perf_regs.c > +++ b/tools/perf/util/perf_regs.c > @@ -6,6 +6,10 @@ const struct sample_reg __weak sample_reg_masks[] = { > SMPL_REG_END > }; > > +const struct sdt_name_reg __weak sdt_reg_renamings[] = { > + SDT_NAME_REG_END, > +}; > + > #ifdef HAVE_PERF_REGS_SUPPORT > int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) > { > diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h > index 679d6e4..41815ca 100644 > --- a/tools/perf/util/perf_regs.h > +++ b/tools/perf/util/perf_regs.h > @@ -15,6 +15,19 @@ struct sample_reg { > > extern const struct sample_reg sample_reg_masks[]; > > +struct sdt_name_reg { > + const char *sdt_name; > + const char *uprobe_name; > +}; > +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} > +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} > + > +/* > + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > + * registers before filling the uprobe tracer interface. > + */ > +extern const struct sdt_name_reg sdt_reg_renamings[]; > + > #ifdef HAVE_PERF_REGS_SUPPORT > #include <perf_regs.h> > > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index 436b647..75033c7 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -27,6 +27,7 @@ > #include "probe-event.h" > #include "probe-file.h" > #include "session.h" > +#include "perf_regs.h" > > #define MAX_CMDLEN 256 > > @@ -687,6 +688,165 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) > : (unsigned long long)note->addr.a64[0]; > } > > +static const char * const type_to_suffix[] = { > + ":s64", "", "", "", ":s32", "", ":s16", ":s8", > + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" > +}; > + > +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > +{ > + const struct sdt_name_reg *rnames; > + char *tmp, *desc = strdup(arg); > + const char *prefix = "", *suffix = ""; > + int ret = -1; > + > + if (desc == NULL) { > + pr_debug4("Allocation error\n"); > + return ret; > + } > + > + tmp = strchr(desc, '@'); > + if (tmp) { > + long type_idx; > + /* > + * Isolate the string number and convert it into a > + * binary value; this will be an index to get suffix > + * of the uprobe name (defining the type) > + */ > + tmp[0] = '\0'; > + type_idx = strtol(desc, NULL, 10); > + if (type_idx == LONG_MIN || > + type_idx == LONG_MAX) { > + pr_debug4("Failed to get sdt type\n"); > + goto error; > + } You must ensure 0 <= type_idx + 8 <= 16 here. > + suffix = type_to_suffix[type_idx + 8]; > + /* Get rid of the sdt prefix which is now useless */ > + tmp++; > + memmove(desc, tmp, strlen(tmp) + 1); > + } > + > + /* > + * The uprobe tracer format does not support all the > + * addressing modes (notably: in x86 the scaled mode); so, we > + * detect ',' characters, if there is just one, there is no > + * use converting the sdt arg into a uprobe one. > + */ > + if (strchr(desc, ',')) { > + pr_debug4("SDT argument format not supported\n"); Please print 'desc' by %s too. > + goto out; > + } > + > + /* > + * If the argument addressing mode is indirect, we must check > + * a few things... > + */ > + tmp = strchr(desc, '('); > + if (tmp) { > + int j; > + > + /* > + * ...if the addressing mode is indirect with a > + * positive offset (ex.: "1608(%ax)"), we need to add > + * a '+' prefix so as to be compliant with uprobe > + * format. > + */ > + if (desc[0] != '+' && desc[0] != '-') > + prefix = "+"; > + > + /* > + * ...or if the addressing mode is indirect with a symbol > + * as offset, the argument will not be supported by > + * the uprobe tracer format; so, let's skip this one. > + */ > + for (j = 0; j < tmp - desc; j++) { > + if (desc[j] != '+' && desc[j] != '-' && > + !isdigit(desc[j])) > + goto out; > + } > + } > + > + /* > + * The uprobe parser does not support all gas register names; > + * so, we have to replace them (ex. for x86_64: %rax -> %ax); > + * the loop below performs all the needed renamings if needed. > + */ > + for (rnames = sdt_reg_renamings; rnames->sdt_name != NULL; rnames++) { > + char *new_desc, *sdt_name; > + size_t prefix_len, uprobe_len, mid_ofs, desc_len; > + > + sdt_name = strstr(desc, rnames->sdt_name); > + if (sdt_name == NULL) > + continue; It is better to search '%' from the desc and parse it. And here, we also find fixed numbers which starts with '$', since that is not supported yet. For example, with your patch, I still see some entries which have fixed num. $ perf buildid-cache --add /usr/lib64/libglib-2.0.so $ grep \$[0-9] ~/.debug/usr/lib64/libglib-2.0.so.0.5000.2/fda1ca4181ba7135d41bf3cfadc813a432f31066/probes | tail -n 2 p:sdt_glib/mem__realloc /usr/lib64/libglib-2.0.so.0.5000.2:0x4f670 arg0=%ax:u64 arg1=%bx:u64 arg2=%bp:u32 arg3=$0:s32 p:sdt_glib/mem__realloc /usr/lib64/libglib-2.0.so.0.5000.2:0x4f75d arg0=%ax:u64 arg1=%bp:u64 arg2=%bx:u32 arg3=$1:s32 These arguments should be skipped. Thank you, > + > + new_desc = zalloc(strlen(desc) + 1 + > + strlen(rnames->uprobe_name) - > + strlen(rnames->sdt_name)); > + if (new_desc == NULL) > + goto error; > + > + prefix_len = sdt_name - desc; > + if (prefix_len != 0) > + memcpy(new_desc, desc, prefix_len); > + > + uprobe_len = strlen(rnames->uprobe_name); > + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); > + > + mid_ofs = prefix_len + strlen(rnames->sdt_name); > + desc_len = strlen(desc); > + if (mid_ofs < desc_len) > + memcpy(new_desc + prefix_len + uprobe_len, > + desc + mid_ofs, desc_len - mid_ofs); > + > + free(desc); > + desc = new_desc; > + } > + > + if (strbuf_addf(buf, " arg%d=%s%s%s", i, prefix, desc, suffix) < 0) > + goto error; > + > +out: > + ret = 0; > +error: > + free(desc); > + return ret; > +} > + > +static char *synthesize_sdt_probe_command(struct sdt_note *note, > + const char *pathname, > + const char *sdtgrp) > +{ > + struct strbuf buf; > + char *ret = NULL, **args; > + int i, args_count; > + > + if (strbuf_init(&buf, 32) < 0) > + return NULL; > + > + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", > + sdtgrp, note->name, pathname, > + sdt_note__get_addr(note)) < 0) > + goto error; > + > + if (!note->args) > + goto out; > + > + if (note->args) { > + args = argv_split(note->args, &args_count); > + > + for (i = 0; i < args_count; ++i) { > + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) > + goto error; > + } > + } > + > +out: > + ret = strbuf_detach(&buf, NULL); > +error: > + strbuf_release(&buf); > + return ret; > +} > + > int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > { > struct probe_cache_entry *entry = NULL; > @@ -723,11 +883,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > entry->pev.group = strdup(sdtgrp); > list_add_tail(&entry->node, &pcache->entries); > } > - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", > - sdtgrp, note->name, pathname, > - sdt_note__get_addr(note)); > - if (ret < 0) > + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); > + if (!buf) { > + ret = -ENOMEM; > break; > + } > + > strlist__add(entry->tevlist, buf); > free(buf); > entry = NULL; > -- > 2.10.2 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v4 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-07 3:26 ` Masami Hiramatsu @ 2016-12-09 15:14 ` Arnaldo Carvalho de Melo 2016-12-10 10:00 ` Masami Hiramatsu 2016-12-14 0:07 ` [PATCH v5 0/2] " Alexis Berlemont ` (2 subsequent siblings) 3 siblings, 1 reply; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2016-12-09 15:14 UTC (permalink / raw) To: Alexis Berlemont Cc: Masami Hiramatsu, linux-kernel, peterz, mingo, alexander.shishkin, hemant Em Wed, Dec 07, 2016 at 12:26:10PM +0900, Masami Hiramatsu escreveu: > Hello Alexis, > > On Sat, 26 Nov 2016 01:58:03 +0100 > Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > > > An sdt probe can be associated with arguments but they were not passed > > to the user probe tracing interface (uprobe_events); this patch adapts > > the sdt argument descriptors according to the uprobe input format. > > Great! Yeah, good to see work in this area! I applied the first patch, with Masami's ack, waiting for his concerns on this one to be addressed, ok? - Arnaldo > > > > As the uprobe parser does not support scaled address mode, perf will > > skip arguments which cannot be adapted to the uprobe format. > > OK, it seems that skipping argument is a good idea :) > I just tried to support fixed-number arguments in probe events, > but skipping it is better with older kernel. > > I have some comments. > > > Here are the results: > > > > $ perf buildid-cache -v --add test_sdt > > $ perf probe -x test_sdt sdt_libfoo:table_frob > > $ perf probe -x test_sdt sdt_libfoo:table_diddle > > $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt > > $ perf script > > test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 > > test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 > > test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 > > test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 > > test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 > > test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 > > We'd better start with arg1, since sdt.h and original Dtrace SDT starts > arguments from arg1 (I'm not sure why) and dtrace/systemtap scripts > call it "arg1". > > > > > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > > --- > > tools/perf/arch/x86/util/perf_regs.c | 18 ++++ > > tools/perf/util/perf_regs.c | 4 + > > tools/perf/util/perf_regs.h | 13 +++ > > tools/perf/util/probe-file.c | 169 ++++++++++++++++++++++++++++++++++- > > 4 files changed, 200 insertions(+), 4 deletions(-) > > > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > > index c5db14f..52a1e65 100644 > > --- a/tools/perf/arch/x86/util/perf_regs.c > > +++ b/tools/perf/arch/x86/util/perf_regs.c > > @@ -26,3 +26,21 @@ const struct sample_reg sample_reg_masks[] = { > > #endif > > SMPL_REG_END > > }; > > + > > +const struct sdt_name_reg sdt_reg_renamings[] = { > > + SDT_NAME_REG(eax, ax), > > + SDT_NAME_REG(rax, ax), > > + SDT_NAME_REG(ebx, bx), > > + SDT_NAME_REG(rbx, bx), > > + SDT_NAME_REG(ecx, cx), > > + SDT_NAME_REG(rcx, cx), > > + SDT_NAME_REG(edx, dx), > > + SDT_NAME_REG(rdx, dx), > > + SDT_NAME_REG(esi, si), > > + SDT_NAME_REG(rsi, si), > > + SDT_NAME_REG(edi, di), > > + SDT_NAME_REG(rdi, di), > > + SDT_NAME_REG(ebp, bp), > > + SDT_NAME_REG(rbp, bp), > > + SDT_NAME_REG_END, > > +}; > > It is not enough, rNN registers also have to take care, since > gcc adds 'd', 'w' or 'b'suffixes for those registers to indicate > its size. e.g. r15d means r15 register with 32 lower bits. > What we need is just cut them off, since probe event uses > length modifiers (like :u32) > > > diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c > > index c4023f2..1c21150 100644 > > --- a/tools/perf/util/perf_regs.c > > +++ b/tools/perf/util/perf_regs.c > > @@ -6,6 +6,10 @@ const struct sample_reg __weak sample_reg_masks[] = { > > SMPL_REG_END > > }; > > > > +const struct sdt_name_reg __weak sdt_reg_renamings[] = { > > + SDT_NAME_REG_END, > > +}; > > + > > #ifdef HAVE_PERF_REGS_SUPPORT > > int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) > > { > > diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h > > index 679d6e4..41815ca 100644 > > --- a/tools/perf/util/perf_regs.h > > +++ b/tools/perf/util/perf_regs.h > > @@ -15,6 +15,19 @@ struct sample_reg { > > > > extern const struct sample_reg sample_reg_masks[]; > > > > +struct sdt_name_reg { > > + const char *sdt_name; > > + const char *uprobe_name; > > +}; > > +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} > > +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} > > + > > +/* > > + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > > + * registers before filling the uprobe tracer interface. > > + */ > > +extern const struct sdt_name_reg sdt_reg_renamings[]; > > + > > #ifdef HAVE_PERF_REGS_SUPPORT > > #include <perf_regs.h> > > > > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > > index 436b647..75033c7 100644 > > --- a/tools/perf/util/probe-file.c > > +++ b/tools/perf/util/probe-file.c > > @@ -27,6 +27,7 @@ > > #include "probe-event.h" > > #include "probe-file.h" > > #include "session.h" > > +#include "perf_regs.h" > > > > #define MAX_CMDLEN 256 > > > > @@ -687,6 +688,165 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) > > : (unsigned long long)note->addr.a64[0]; > > } > > > > +static const char * const type_to_suffix[] = { > > + ":s64", "", "", "", ":s32", "", ":s16", ":s8", > > + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" > > +}; > > + > > +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > > +{ > > + const struct sdt_name_reg *rnames; > > + char *tmp, *desc = strdup(arg); > > + const char *prefix = "", *suffix = ""; > > + int ret = -1; > > + > > + if (desc == NULL) { > > + pr_debug4("Allocation error\n"); > > + return ret; > > + } > > + > > + tmp = strchr(desc, '@'); > > + if (tmp) { > > + long type_idx; > > + /* > > + * Isolate the string number and convert it into a > > + * binary value; this will be an index to get suffix > > + * of the uprobe name (defining the type) > > + */ > > + tmp[0] = '\0'; > > + type_idx = strtol(desc, NULL, 10); > > + if (type_idx == LONG_MIN || > > + type_idx == LONG_MAX) { > > + pr_debug4("Failed to get sdt type\n"); > > + goto error; > > + } > > You must ensure 0 <= type_idx + 8 <= 16 here. > > > + suffix = type_to_suffix[type_idx + 8]; > > + /* Get rid of the sdt prefix which is now useless */ > > + tmp++; > > + memmove(desc, tmp, strlen(tmp) + 1); > > + } > > + > > + /* > > + * The uprobe tracer format does not support all the > > + * addressing modes (notably: in x86 the scaled mode); so, we > > + * detect ',' characters, if there is just one, there is no > > + * use converting the sdt arg into a uprobe one. > > + */ > > + if (strchr(desc, ',')) { > > + pr_debug4("SDT argument format not supported\n"); > > Please print 'desc' by %s too. > > > + goto out; > > + } > > + > > + /* > > + * If the argument addressing mode is indirect, we must check > > + * a few things... > > + */ > > + tmp = strchr(desc, '('); > > + if (tmp) { > > + int j; > > + > > + /* > > + * ...if the addressing mode is indirect with a > > + * positive offset (ex.: "1608(%ax)"), we need to add > > + * a '+' prefix so as to be compliant with uprobe > > + * format. > > + */ > > + if (desc[0] != '+' && desc[0] != '-') > > + prefix = "+"; > > + > > + /* > > + * ...or if the addressing mode is indirect with a symbol > > + * as offset, the argument will not be supported by > > + * the uprobe tracer format; so, let's skip this one. > > + */ > > + for (j = 0; j < tmp - desc; j++) { > > + if (desc[j] != '+' && desc[j] != '-' && > > + !isdigit(desc[j])) > > + goto out; > > + } > > + } > > + > > + /* > > + * The uprobe parser does not support all gas register names; > > + * so, we have to replace them (ex. for x86_64: %rax -> %ax); > > + * the loop below performs all the needed renamings if needed. > > + */ > > + for (rnames = sdt_reg_renamings; rnames->sdt_name != NULL; rnames++) { > > + char *new_desc, *sdt_name; > > + size_t prefix_len, uprobe_len, mid_ofs, desc_len; > > + > > + sdt_name = strstr(desc, rnames->sdt_name); > > + if (sdt_name == NULL) > > + continue; > > It is better to search '%' from the desc and parse it. > And here, we also find fixed numbers which starts with '$', > since that is not supported yet. > > For example, with your patch, I still see some entries which have fixed num. > > $ perf buildid-cache --add /usr/lib64/libglib-2.0.so > $ grep \$[0-9] ~/.debug/usr/lib64/libglib-2.0.so.0.5000.2/fda1ca4181ba7135d41bf3cfadc813a432f31066/probes | tail -n 2 > p:sdt_glib/mem__realloc /usr/lib64/libglib-2.0.so.0.5000.2:0x4f670 arg0=%ax:u64 arg1=%bx:u64 arg2=%bp:u32 arg3=$0:s32 > p:sdt_glib/mem__realloc /usr/lib64/libglib-2.0.so.0.5000.2:0x4f75d arg0=%ax:u64 arg1=%bp:u64 arg2=%bx:u32 arg3=$1:s32 > > These arguments should be skipped. > > Thank you, > > > + > > + new_desc = zalloc(strlen(desc) + 1 + > > + strlen(rnames->uprobe_name) - > > + strlen(rnames->sdt_name)); > > + if (new_desc == NULL) > > + goto error; > > + > > + prefix_len = sdt_name - desc; > > + if (prefix_len != 0) > > + memcpy(new_desc, desc, prefix_len); > > + > > + uprobe_len = strlen(rnames->uprobe_name); > > + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); > > + > > + mid_ofs = prefix_len + strlen(rnames->sdt_name); > > + desc_len = strlen(desc); > > + if (mid_ofs < desc_len) > > + memcpy(new_desc + prefix_len + uprobe_len, > > + desc + mid_ofs, desc_len - mid_ofs); > > + > > + free(desc); > > + desc = new_desc; > > + } > > + > > + if (strbuf_addf(buf, " arg%d=%s%s%s", i, prefix, desc, suffix) < 0) > > + goto error; > > + > > +out: > > + ret = 0; > > +error: > > + free(desc); > > + return ret; > > +} > > + > > +static char *synthesize_sdt_probe_command(struct sdt_note *note, > > + const char *pathname, > > + const char *sdtgrp) > > +{ > > + struct strbuf buf; > > + char *ret = NULL, **args; > > + int i, args_count; > > + > > + if (strbuf_init(&buf, 32) < 0) > > + return NULL; > > + > > + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", > > + sdtgrp, note->name, pathname, > > + sdt_note__get_addr(note)) < 0) > > + goto error; > > + > > + if (!note->args) > > + goto out; > > + > > + if (note->args) { > > + args = argv_split(note->args, &args_count); > > + > > + for (i = 0; i < args_count; ++i) { > > + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) > > + goto error; > > + } > > + } > > + > > +out: > > + ret = strbuf_detach(&buf, NULL); > > +error: > > + strbuf_release(&buf); > > + return ret; > > +} > > + > > int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > > { > > struct probe_cache_entry *entry = NULL; > > @@ -723,11 +883,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > > entry->pev.group = strdup(sdtgrp); > > list_add_tail(&entry->node, &pcache->entries); > > } > > - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", > > - sdtgrp, note->name, pathname, > > - sdt_note__get_addr(note)); > > - if (ret < 0) > > + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); > > + if (!buf) { > > + ret = -ENOMEM; > > break; > > + } > > + > > strlist__add(entry->tevlist, buf); > > free(buf); > > entry = NULL; > > -- > > 2.10.2 > > > > > -- > Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v4 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-09 15:14 ` Arnaldo Carvalho de Melo @ 2016-12-10 10:00 ` Masami Hiramatsu 0 siblings, 0 replies; 77+ messages in thread From: Masami Hiramatsu @ 2016-12-10 10:00 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Alexis Berlemont, Masami Hiramatsu, linux-kernel, peterz, mingo, alexander.shishkin, hemant On Fri, 9 Dec 2016 12:14:30 -0300 Arnaldo Carvalho de Melo <acme@kernel.org> wrote: > Em Wed, Dec 07, 2016 at 12:26:10PM +0900, Masami Hiramatsu escreveu: > > Hello Alexis, > > > > On Sat, 26 Nov 2016 01:58:03 +0100 > > Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > > > > > An sdt probe can be associated with arguments but they were not passed > > > to the user probe tracing interface (uprobe_events); this patch adapts > > > the sdt argument descriptors according to the uprobe input format. > > > > Great! > > Yeah, good to see work in this area! > > I applied the first patch, with Masami's ack, waiting for his concerns > on this one to be addressed, ok? Yes, I'm OK. Alexis, I'm happy to review/ack your next version! :) Thank you, > > - Arnaldo > > > > > > > As the uprobe parser does not support scaled address mode, perf will > > > skip arguments which cannot be adapted to the uprobe format. > > > > OK, it seems that skipping argument is a good idea :) > > I just tried to support fixed-number arguments in probe events, > > but skipping it is better with older kernel. > > > > I have some comments. > > > > > Here are the results: > > > > > > $ perf buildid-cache -v --add test_sdt > > > $ perf probe -x test_sdt sdt_libfoo:table_frob > > > $ perf probe -x test_sdt sdt_libfoo:table_diddle > > > $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt > > > $ perf script > > > test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 > > > test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 > > > test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 > > > test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 > > > test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 > > > test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 > > > > We'd better start with arg1, since sdt.h and original Dtrace SDT starts > > arguments from arg1 (I'm not sure why) and dtrace/systemtap scripts > > call it "arg1". > > > > > > > > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > > > --- > > > tools/perf/arch/x86/util/perf_regs.c | 18 ++++ > > > tools/perf/util/perf_regs.c | 4 + > > > tools/perf/util/perf_regs.h | 13 +++ > > > tools/perf/util/probe-file.c | 169 ++++++++++++++++++++++++++++++++++- > > > 4 files changed, 200 insertions(+), 4 deletions(-) > > > > > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > > > index c5db14f..52a1e65 100644 > > > --- a/tools/perf/arch/x86/util/perf_regs.c > > > +++ b/tools/perf/arch/x86/util/perf_regs.c > > > @@ -26,3 +26,21 @@ const struct sample_reg sample_reg_masks[] = { > > > #endif > > > SMPL_REG_END > > > }; > > > + > > > +const struct sdt_name_reg sdt_reg_renamings[] = { > > > + SDT_NAME_REG(eax, ax), > > > + SDT_NAME_REG(rax, ax), > > > + SDT_NAME_REG(ebx, bx), > > > + SDT_NAME_REG(rbx, bx), > > > + SDT_NAME_REG(ecx, cx), > > > + SDT_NAME_REG(rcx, cx), > > > + SDT_NAME_REG(edx, dx), > > > + SDT_NAME_REG(rdx, dx), > > > + SDT_NAME_REG(esi, si), > > > + SDT_NAME_REG(rsi, si), > > > + SDT_NAME_REG(edi, di), > > > + SDT_NAME_REG(rdi, di), > > > + SDT_NAME_REG(ebp, bp), > > > + SDT_NAME_REG(rbp, bp), > > > + SDT_NAME_REG_END, > > > +}; > > > > It is not enough, rNN registers also have to take care, since > > gcc adds 'd', 'w' or 'b'suffixes for those registers to indicate > > its size. e.g. r15d means r15 register with 32 lower bits. > > What we need is just cut them off, since probe event uses > > length modifiers (like :u32) > > > > > diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c > > > index c4023f2..1c21150 100644 > > > --- a/tools/perf/util/perf_regs.c > > > +++ b/tools/perf/util/perf_regs.c > > > @@ -6,6 +6,10 @@ const struct sample_reg __weak sample_reg_masks[] = { > > > SMPL_REG_END > > > }; > > > > > > +const struct sdt_name_reg __weak sdt_reg_renamings[] = { > > > + SDT_NAME_REG_END, > > > +}; > > > + > > > #ifdef HAVE_PERF_REGS_SUPPORT > > > int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) > > > { > > > diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h > > > index 679d6e4..41815ca 100644 > > > --- a/tools/perf/util/perf_regs.h > > > +++ b/tools/perf/util/perf_regs.h > > > @@ -15,6 +15,19 @@ struct sample_reg { > > > > > > extern const struct sample_reg sample_reg_masks[]; > > > > > > +struct sdt_name_reg { > > > + const char *sdt_name; > > > + const char *uprobe_name; > > > +}; > > > +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} > > > +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} > > > + > > > +/* > > > + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > > > + * registers before filling the uprobe tracer interface. > > > + */ > > > +extern const struct sdt_name_reg sdt_reg_renamings[]; > > > + > > > #ifdef HAVE_PERF_REGS_SUPPORT > > > #include <perf_regs.h> > > > > > > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > > > index 436b647..75033c7 100644 > > > --- a/tools/perf/util/probe-file.c > > > +++ b/tools/perf/util/probe-file.c > > > @@ -27,6 +27,7 @@ > > > #include "probe-event.h" > > > #include "probe-file.h" > > > #include "session.h" > > > +#include "perf_regs.h" > > > > > > #define MAX_CMDLEN 256 > > > > > > @@ -687,6 +688,165 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) > > > : (unsigned long long)note->addr.a64[0]; > > > } > > > > > > +static const char * const type_to_suffix[] = { > > > + ":s64", "", "", "", ":s32", "", ":s16", ":s8", > > > + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" > > > +}; > > > + > > > +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > > > +{ > > > + const struct sdt_name_reg *rnames; > > > + char *tmp, *desc = strdup(arg); > > > + const char *prefix = "", *suffix = ""; > > > + int ret = -1; > > > + > > > + if (desc == NULL) { > > > + pr_debug4("Allocation error\n"); > > > + return ret; > > > + } > > > + > > > + tmp = strchr(desc, '@'); > > > + if (tmp) { > > > + long type_idx; > > > + /* > > > + * Isolate the string number and convert it into a > > > + * binary value; this will be an index to get suffix > > > + * of the uprobe name (defining the type) > > > + */ > > > + tmp[0] = '\0'; > > > + type_idx = strtol(desc, NULL, 10); > > > + if (type_idx == LONG_MIN || > > > + type_idx == LONG_MAX) { > > > + pr_debug4("Failed to get sdt type\n"); > > > + goto error; > > > + } > > > > You must ensure 0 <= type_idx + 8 <= 16 here. > > > > > + suffix = type_to_suffix[type_idx + 8]; > > > + /* Get rid of the sdt prefix which is now useless */ > > > + tmp++; > > > + memmove(desc, tmp, strlen(tmp) + 1); > > > + } > > > + > > > + /* > > > + * The uprobe tracer format does not support all the > > > + * addressing modes (notably: in x86 the scaled mode); so, we > > > + * detect ',' characters, if there is just one, there is no > > > + * use converting the sdt arg into a uprobe one. > > > + */ > > > + if (strchr(desc, ',')) { > > > + pr_debug4("SDT argument format not supported\n"); > > > > Please print 'desc' by %s too. > > > > > + goto out; > > > + } > > > + > > > + /* > > > + * If the argument addressing mode is indirect, we must check > > > + * a few things... > > > + */ > > > + tmp = strchr(desc, '('); > > > + if (tmp) { > > > + int j; > > > + > > > + /* > > > + * ...if the addressing mode is indirect with a > > > + * positive offset (ex.: "1608(%ax)"), we need to add > > > + * a '+' prefix so as to be compliant with uprobe > > > + * format. > > > + */ > > > + if (desc[0] != '+' && desc[0] != '-') > > > + prefix = "+"; > > > + > > > + /* > > > + * ...or if the addressing mode is indirect with a symbol > > > + * as offset, the argument will not be supported by > > > + * the uprobe tracer format; so, let's skip this one. > > > + */ > > > + for (j = 0; j < tmp - desc; j++) { > > > + if (desc[j] != '+' && desc[j] != '-' && > > > + !isdigit(desc[j])) > > > + goto out; > > > + } > > > + } > > > + > > > + /* > > > + * The uprobe parser does not support all gas register names; > > > + * so, we have to replace them (ex. for x86_64: %rax -> %ax); > > > + * the loop below performs all the needed renamings if needed. > > > + */ > > > + for (rnames = sdt_reg_renamings; rnames->sdt_name != NULL; rnames++) { > > > + char *new_desc, *sdt_name; > > > + size_t prefix_len, uprobe_len, mid_ofs, desc_len; > > > + > > > + sdt_name = strstr(desc, rnames->sdt_name); > > > + if (sdt_name == NULL) > > > + continue; > > > > It is better to search '%' from the desc and parse it. > > And here, we also find fixed numbers which starts with '$', > > since that is not supported yet. > > > > For example, with your patch, I still see some entries which have fixed num. > > > > $ perf buildid-cache --add /usr/lib64/libglib-2.0.so > > $ grep \$[0-9] ~/.debug/usr/lib64/libglib-2.0.so.0.5000.2/fda1ca4181ba7135d41bf3cfadc813a432f31066/probes | tail -n 2 > > p:sdt_glib/mem__realloc /usr/lib64/libglib-2.0.so.0.5000.2:0x4f670 arg0=%ax:u64 arg1=%bx:u64 arg2=%bp:u32 arg3=$0:s32 > > p:sdt_glib/mem__realloc /usr/lib64/libglib-2.0.so.0.5000.2:0x4f75d arg0=%ax:u64 arg1=%bp:u64 arg2=%bx:u32 arg3=$1:s32 > > > > These arguments should be skipped. > > > > Thank you, > > > > > + > > > + new_desc = zalloc(strlen(desc) + 1 + > > > + strlen(rnames->uprobe_name) - > > > + strlen(rnames->sdt_name)); > > > + if (new_desc == NULL) > > > + goto error; > > > + > > > + prefix_len = sdt_name - desc; > > > + if (prefix_len != 0) > > > + memcpy(new_desc, desc, prefix_len); > > > + > > > + uprobe_len = strlen(rnames->uprobe_name); > > > + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); > > > + > > > + mid_ofs = prefix_len + strlen(rnames->sdt_name); > > > + desc_len = strlen(desc); > > > + if (mid_ofs < desc_len) > > > + memcpy(new_desc + prefix_len + uprobe_len, > > > + desc + mid_ofs, desc_len - mid_ofs); > > > + > > > + free(desc); > > > + desc = new_desc; > > > + } > > > + > > > + if (strbuf_addf(buf, " arg%d=%s%s%s", i, prefix, desc, suffix) < 0) > > > + goto error; > > > + > > > +out: > > > + ret = 0; > > > +error: > > > + free(desc); > > > + return ret; > > > +} > > > + > > > +static char *synthesize_sdt_probe_command(struct sdt_note *note, > > > + const char *pathname, > > > + const char *sdtgrp) > > > +{ > > > + struct strbuf buf; > > > + char *ret = NULL, **args; > > > + int i, args_count; > > > + > > > + if (strbuf_init(&buf, 32) < 0) > > > + return NULL; > > > + > > > + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", > > > + sdtgrp, note->name, pathname, > > > + sdt_note__get_addr(note)) < 0) > > > + goto error; > > > + > > > + if (!note->args) > > > + goto out; > > > + > > > + if (note->args) { > > > + args = argv_split(note->args, &args_count); > > > + > > > + for (i = 0; i < args_count; ++i) { > > > + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) > > > + goto error; > > > + } > > > + } > > > + > > > +out: > > > + ret = strbuf_detach(&buf, NULL); > > > +error: > > > + strbuf_release(&buf); > > > + return ret; > > > +} > > > + > > > int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > > > { > > > struct probe_cache_entry *entry = NULL; > > > @@ -723,11 +883,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > > > entry->pev.group = strdup(sdtgrp); > > > list_add_tail(&entry->node, &pcache->entries); > > > } > > > - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", > > > - sdtgrp, note->name, pathname, > > > - sdt_note__get_addr(note)); > > > - if (ret < 0) > > > + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); > > > + if (!buf) { > > > + ret = -ENOMEM; > > > break; > > > + } > > > + > > > strlist__add(entry->tevlist, buf); > > > free(buf); > > > entry = NULL; > > > -- > > > 2.10.2 > > > > > > > > > -- > > Masami Hiramatsu <mhiramat@kernel.org> -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-07 3:26 ` Masami Hiramatsu 2016-12-09 15:14 ` Arnaldo Carvalho de Melo @ 2016-12-14 0:07 ` Alexis Berlemont 2016-12-14 7:36 ` Ingo Molnar ` (2 more replies) 2016-12-14 0:07 ` [PATCH v5 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2016-12-14 0:07 ` [PATCH v5 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 3 siblings, 3 replies; 77+ messages in thread From: Alexis Berlemont @ 2016-12-14 0:07 UTC (permalink / raw) To: linux-kernel; +Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin Hi Masami, Many thanks for your mail. Here is another patch set which tries to fix the points you mentioned: * Skip the arguments containing a constant ($123); * Review the code in charge of the register renaming (search for '%' and parse it); * Minor changes (print the argument in case of error, skipping, check the sdt arg type index); Many thanks, Alexis. Alexis Berlemont (2): perf sdt: add scanning of sdt probles arguments perf probe: add sdt probes arguments into the uprobe cmd string tools/perf/arch/x86/util/perf_regs.c | 83 +++++++++++++++++ tools/perf/util/perf_regs.c | 6 ++ tools/perf/util/perf_regs.h | 6 ++ tools/perf/util/probe-file.c | 170 ++++++++++++++++++++++++++++++++++- tools/perf/util/symbol-elf.c | 25 +++++- tools/perf/util/symbol.h | 1 + 6 files changed, 285 insertions(+), 6 deletions(-) -- 2.10.2 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-14 0:07 ` [PATCH v5 0/2] " Alexis Berlemont @ 2016-12-14 7:36 ` Ingo Molnar 2017-01-23 11:23 ` Ravi Bangoria 2017-01-24 6:58 ` Ravi Bangoria 2017-02-02 11:11 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Ravi Bangoria 2017-03-21 5:08 ` [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string Masami Hiramatsu 2 siblings, 2 replies; 77+ messages in thread From: Ingo Molnar @ 2016-12-14 7:36 UTC (permalink / raw) To: Alexis Berlemont Cc: linux-kernel, peterz, mingo, acme, alexander.shishkin, Jiri Olsa * Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > Hi Masami, > > Many thanks for your mail. > > Here is another patch set which tries to fix the points you mentioned: > > * Skip the arguments containing a constant ($123); > * Review the code in charge of the register renaming (search for '%' > and parse it); > * Minor changes (print the argument in case of error, skipping, check > the sdt arg type index); > > Many thanks, > > Alexis. > > Alexis Berlemont (2): > perf sdt: add scanning of sdt probles arguments > perf probe: add sdt probes arguments into the uprobe cmd string I'd like to hijack this thread to report an SDT oddity - one of my boxen reports lots of SDT tracepoints in 'perf list': mem:<addr>[/len][:access] [Hardware breakpoint] sdt_libc:lll_lock_wait_private [SDT event] sdt_libc:longjmp [SDT event] sdt_libc:longjmp_target [SDT event] sdt_libc:memory_arena_new [SDT event] sdt_libc:memory_arena_retry [SDT event] sdt_libc:memory_arena_reuse [SDT event] sdt_libc:memory_arena_reuse_free_list [SDT event] sdt_libc:memory_arena_reuse_wait [SDT event] sdt_libc:memory_calloc_retry [SDT event] sdt_libc:memory_heap_free [SDT event] ... But none of them work: Error: No permissions to read /sys/kernel/debug/tracing/events/sdt_libc/longjmp Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing' ... Error: File /sys/kernel/debug/tracing/events/sdt_libc/longjmp not found. Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. What kind of patches are required for SDT probes to work? Thanks, Ingo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-14 7:36 ` Ingo Molnar @ 2017-01-23 11:23 ` Ravi Bangoria 2017-02-22 22:41 ` Alexis Berlemont 2017-01-24 6:58 ` Ravi Bangoria 1 sibling, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-01-23 11:23 UTC (permalink / raw) To: Ingo Molnar, Alexis Berlemont Cc: linux-kernel, peterz, mingo, acme, alexander.shishkin, Jiri Olsa, Ravi Bangoria On Wednesday 14 December 2016 01:06 PM, Ingo Molnar wrote: > * Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > >> Hi Masami, >> >> Many thanks for your mail. >> >> Here is another patch set which tries to fix the points you mentioned: >> >> * Skip the arguments containing a constant ($123); >> * Review the code in charge of the register renaming (search for '%' >> and parse it); >> * Minor changes (print the argument in case of error, skipping, check >> the sdt arg type index); >> >> Many thanks, >> >> Alexis. >> >> Alexis Berlemont (2): >> perf sdt: add scanning of sdt probles arguments >> perf probe: add sdt probes arguments into the uprobe cmd string > I'd like to hijack this thread to report an SDT oddity - one of my boxen reports > lots of SDT tracepoints in 'perf list': > > mem:<addr>[/len][:access] [Hardware breakpoint] > > sdt_libc:lll_lock_wait_private [SDT event] > sdt_libc:longjmp [SDT event] > sdt_libc:longjmp_target [SDT event] > sdt_libc:memory_arena_new [SDT event] > sdt_libc:memory_arena_retry [SDT event] > sdt_libc:memory_arena_reuse [SDT event] > sdt_libc:memory_arena_reuse_free_list [SDT event] > sdt_libc:memory_arena_reuse_wait [SDT event] > sdt_libc:memory_calloc_retry [SDT event] > sdt_libc:memory_heap_free [SDT event] > ... > > But none of them work: > > Error: No permissions to read /sys/kernel/debug/tracing/events/sdt_libc/longjmp > Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing' > > ... > > Error: File /sys/kernel/debug/tracing/events/sdt_libc/longjmp not found. > Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. > > What kind of patches are required for SDT probes to work? Hi Ingo, Works for me on my x86 Fedora 25 box. May be some permission issue? @Alexis, Planning to progress on it :) ? I would like to prepare patch for powerpc. Thanks, Ravi > Thanks, > > Ingo > ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2017-01-23 11:23 ` Ravi Bangoria @ 2017-02-22 22:41 ` Alexis Berlemont 0 siblings, 0 replies; 77+ messages in thread From: Alexis Berlemont @ 2017-02-22 22:41 UTC (permalink / raw) To: Ravi Bangoria Cc: Ingo Molnar, linux-kernel, peterz, mingo, acme, alexander.shishkin, Jiri Olsa Ravi Bangoria wrote: > > > On Wednesday 14 December 2016 01:06 PM, Ingo Molnar wrote: > > * Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > > > >> Hi Masami, > >> > >> Many thanks for your mail. > >> > >> Here is another patch set which tries to fix the points you mentioned: > >> > >> * Skip the arguments containing a constant ($123); > >> * Review the code in charge of the register renaming (search for '%' > >> and parse it); > >> * Minor changes (print the argument in case of error, skipping, check > >> the sdt arg type index); > >> > >> Many thanks, > >> > >> Alexis. > >> > >> Alexis Berlemont (2): > >> perf sdt: add scanning of sdt probles arguments > >> perf probe: add sdt probes arguments into the uprobe cmd string > > I'd like to hijack this thread to report an SDT oddity - one of my boxen reports > > lots of SDT tracepoints in 'perf list': > > > > mem:<addr>[/len][:access] [Hardware breakpoint] > > > > sdt_libc:lll_lock_wait_private [SDT event] > > sdt_libc:longjmp [SDT event] > > sdt_libc:longjmp_target [SDT event] > > sdt_libc:memory_arena_new [SDT event] > > sdt_libc:memory_arena_retry [SDT event] > > sdt_libc:memory_arena_reuse [SDT event] > > sdt_libc:memory_arena_reuse_free_list [SDT event] > > sdt_libc:memory_arena_reuse_wait [SDT event] > > sdt_libc:memory_calloc_retry [SDT event] > > sdt_libc:memory_heap_free [SDT event] > > ... > > > > But none of them work: > > > > Error: No permissions to read /sys/kernel/debug/tracing/events/sdt_libc/longjmp > > Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing' > > > > ... > > > > Error: File /sys/kernel/debug/tracing/events/sdt_libc/longjmp not found. > > Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. > > > > What kind of patches are required for SDT probes to work? > > Hi Ingo, > > Works for me on my x86 Fedora 25 box. May be some permission issue? > > @Alexis, Planning to progress on it :) ? I would like to prepare patch for > powerpc. Hi, Just a quick mail to apologize. After a few weeks without answer, I forgot to regularly poll this thread during my free time. I've just noticed the patches you sent meanwhile... Once more sorry, Alexis. > > Thanks, > Ravi > > > Thanks, > > > > Ingo > > > ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-14 7:36 ` Ingo Molnar 2017-01-23 11:23 ` Ravi Bangoria @ 2017-01-24 6:58 ` Ravi Bangoria 2017-01-24 8:22 ` Ingo Molnar 1 sibling, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-01-24 6:58 UTC (permalink / raw) To: Ingo Molnar Cc: Alexis Berlemont, linux-kernel, peterz, mingo, acme, alexander.shishkin, Jiri Olsa, Ravi Bangoria On Wednesday 14 December 2016 01:06 PM, Ingo Molnar wrote: > * Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > >> Hi Masami, >> >> Many thanks for your mail. >> >> Here is another patch set which tries to fix the points you mentioned: >> >> * Skip the arguments containing a constant ($123); >> * Review the code in charge of the register renaming (search for '%' >> and parse it); >> * Minor changes (print the argument in case of error, skipping, check >> the sdt arg type index); >> >> Many thanks, >> >> Alexis. >> >> Alexis Berlemont (2): >> perf sdt: add scanning of sdt probles arguments >> perf probe: add sdt probes arguments into the uprobe cmd string > I'd like to hijack this thread to report an SDT oddity - one of my boxen reports > lots of SDT tracepoints in 'perf list': > > mem:<addr>[/len][:access] [Hardware breakpoint] > > sdt_libc:lll_lock_wait_private [SDT event] > sdt_libc:longjmp [SDT event] > sdt_libc:longjmp_target [SDT event] > sdt_libc:memory_arena_new [SDT event] > sdt_libc:memory_arena_retry [SDT event] > sdt_libc:memory_arena_reuse [SDT event] > sdt_libc:memory_arena_reuse_free_list [SDT event] > sdt_libc:memory_arena_reuse_wait [SDT event] > sdt_libc:memory_calloc_retry [SDT event] > sdt_libc:memory_heap_free [SDT event] > ... > > But none of them work: > > Error: No permissions to read /sys/kernel/debug/tracing/events/sdt_libc/longjmp > Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing' > > ... > > Error: File /sys/kernel/debug/tracing/events/sdt_libc/longjmp not found. > Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. > > What kind of patches are required for SDT probes to work? Hi Ingo, I suppose you are trying to record SDT events without probing it. In that case, first put a probe on an event and then try to record it. For example, $ ./perf list | grep sdt_ sdt_glib:main__after_prepare [SDT event] sdt_glib:main__before_dispatch [SDT event] ... $ ./perf record -a -e sdt_glib:main__after_prepare event syntax error: 'sdt_glib:main__after_prepare' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sdt_glib/main__after_prepare not found. Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. ... $ ./perf probe sdt_glib:main__after_prepare Added new events: sdt_glib:main__after_prepare (on %main__after_prepare in /usr/lib64/libglib-2.0.so.0.5000.2) sdt_glib:main__after_prepare_1 (on %main__after_prepare in /usr/lib64/libglib-2.0.so.0.5000.2) You can now use it in all perf tools, such as: perf record -e sdt_glib:main__after_prepare_1 -aR sleep 1 $ ./perf record -a -e sdt_glib:main__after_prepare [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.191 MB perf.data ] -Ravi ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2017-01-24 6:58 ` Ravi Bangoria @ 2017-01-24 8:22 ` Ingo Molnar 2017-01-24 8:36 ` Ravi Bangoria 0 siblings, 1 reply; 77+ messages in thread From: Ingo Molnar @ 2017-01-24 8:22 UTC (permalink / raw) To: Ravi Bangoria Cc: Alexis Berlemont, linux-kernel, peterz, mingo, acme, alexander.shishkin, Jiri Olsa * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > On Wednesday 14 December 2016 01:06 PM, Ingo Molnar wrote: > > * Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > > > >> Hi Masami, > >> > >> Many thanks for your mail. > >> > >> Here is another patch set which tries to fix the points you mentioned: > >> > >> * Skip the arguments containing a constant ($123); > >> * Review the code in charge of the register renaming (search for '%' > >> and parse it); > >> * Minor changes (print the argument in case of error, skipping, check > >> the sdt arg type index); > >> > >> Many thanks, > >> > >> Alexis. > >> > >> Alexis Berlemont (2): > >> perf sdt: add scanning of sdt probles arguments > >> perf probe: add sdt probes arguments into the uprobe cmd string > > I'd like to hijack this thread to report an SDT oddity - one of my boxen reports > > lots of SDT tracepoints in 'perf list': > > > > mem:<addr>[/len][:access] [Hardware breakpoint] > > > > sdt_libc:lll_lock_wait_private [SDT event] > > sdt_libc:longjmp [SDT event] > > sdt_libc:longjmp_target [SDT event] > > sdt_libc:memory_arena_new [SDT event] > > sdt_libc:memory_arena_retry [SDT event] > > sdt_libc:memory_arena_reuse [SDT event] > > sdt_libc:memory_arena_reuse_free_list [SDT event] > > sdt_libc:memory_arena_reuse_wait [SDT event] > > sdt_libc:memory_calloc_retry [SDT event] > > sdt_libc:memory_heap_free [SDT event] > > ... > > > > But none of them work: > > > > Error: No permissions to read /sys/kernel/debug/tracing/events/sdt_libc/longjmp > > Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing' > > > > ... > > > > Error: File /sys/kernel/debug/tracing/events/sdt_libc/longjmp not found. > > Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. > > > > What kind of patches are required for SDT probes to work? > > Hi Ingo, > > I suppose you are trying to record SDT events without probing it. > In that case, first put a probe on an event and then try to record > it. For example, Well, I was mainly complaining about the misleading messages and flow of the tooling here. Could you please improve the messages so that if I use it like the way I reported it results in me trying the right approach? Thanks, Ingo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2017-01-24 8:22 ` Ingo Molnar @ 2017-01-24 8:36 ` Ravi Bangoria 0 siblings, 0 replies; 77+ messages in thread From: Ravi Bangoria @ 2017-01-24 8:36 UTC (permalink / raw) To: Ingo Molnar Cc: Alexis Berlemont, linux-kernel, peterz, mingo, acme, alexander.shishkin, Jiri Olsa, Ravi Bangoria, Hemant Kumar On Tuesday 24 January 2017 01:52 PM, Ingo Molnar wrote: > * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > >> >> On Wednesday 14 December 2016 01:06 PM, Ingo Molnar wrote: >>> * Alexis Berlemont <alexis.berlemont@gmail.com> wrote: >>> >>>> Hi Masami, >>>> >>>> Many thanks for your mail. >>>> >>>> Here is another patch set which tries to fix the points you mentioned: >>>> >>>> * Skip the arguments containing a constant ($123); >>>> * Review the code in charge of the register renaming (search for '%' >>>> and parse it); >>>> * Minor changes (print the argument in case of error, skipping, check >>>> the sdt arg type index); >>>> >>>> Many thanks, >>>> >>>> Alexis. >>>> >>>> Alexis Berlemont (2): >>>> perf sdt: add scanning of sdt probles arguments >>>> perf probe: add sdt probes arguments into the uprobe cmd string >>> I'd like to hijack this thread to report an SDT oddity - one of my boxen reports >>> lots of SDT tracepoints in 'perf list': >>> >>> mem:<addr>[/len][:access] [Hardware breakpoint] >>> >>> sdt_libc:lll_lock_wait_private [SDT event] >>> sdt_libc:longjmp [SDT event] >>> sdt_libc:longjmp_target [SDT event] >>> sdt_libc:memory_arena_new [SDT event] >>> sdt_libc:memory_arena_retry [SDT event] >>> sdt_libc:memory_arena_reuse [SDT event] >>> sdt_libc:memory_arena_reuse_free_list [SDT event] >>> sdt_libc:memory_arena_reuse_wait [SDT event] >>> sdt_libc:memory_calloc_retry [SDT event] >>> sdt_libc:memory_heap_free [SDT event] >>> ... >>> >>> But none of them work: >>> >>> Error: No permissions to read /sys/kernel/debug/tracing/events/sdt_libc/longjmp >>> Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing' >>> >>> ... >>> >>> Error: File /sys/kernel/debug/tracing/events/sdt_libc/longjmp not found. >>> Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. >>> >>> What kind of patches are required for SDT probes to work? >> Hi Ingo, >> >> I suppose you are trying to record SDT events without probing it. >> In that case, first put a probe on an event and then try to record >> it. For example, > > Well, I was mainly complaining about the misleading messages and flow of the > tooling here. Could you please improve the messages so that if I use it like the > way I reported it results in me trying the right approach? Right, message is misleading. Will prepare a patch for this. Also it's little odd flow for sdt markers, to put a probe first and then record it while other events can be recorded directly. There was a patch by Hemant about directly recording SDT marker events. I don't see any updates on that: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1138183.html -Ravi > Thanks, > > Ingo > ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH 0/5] perf/sdt: Argument support for x86 and powepc 2016-12-14 0:07 ` [PATCH v5 0/2] " Alexis Berlemont 2016-12-14 7:36 ` Ingo Molnar @ 2017-02-02 11:11 ` Ravi Bangoria 2017-02-02 11:11 ` [PATCH 1/5] perf/sdt: Show proper hint Ravi Bangoria ` (5 more replies) 2017-03-21 5:08 ` [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string Masami Hiramatsu 2 siblings, 6 replies; 77+ messages in thread From: Ravi Bangoria @ 2017-02-02 11:11 UTC (permalink / raw) To: acme, alexis.berlemont, linux-kernel Cc: peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy, Ravi Bangoria The v5 patchset for sdt marker argument support for x86 [1] has couple of issues. For example, it still has x86 specific code in general code. It lacks support for rNN (with size postfix b/w/d), %rsp, %esp, %sil etc. registers and such sdt markers are failing at 'perf probe'. It also fails to convert arguments having no offset but still surrounds register with parenthesis for ex. 8@(%rdi) is converted to +(%di):u64 which is rejected by uprobe_events. It's causing failure at 'perf probe' for all SDT events on all archs except x86. With this patchset, I've solved these issues. (patch 2,3) Also, existing perf shows misleading message when user tries to record sdt event without probing it. I've prepared patch for the same. (patch 1) Apart from that, I've also added logic to support arguments with sdt marker on powerpc. (patch 4) There are cases where uprobe definition of sdt event goes beyond current limit MAX_CMDLEN (256) and in such case perf fails with seg fault. I've solve this issue. (patch 5) Note: This patchset is prepared on top of Alexis' v5 series.[1] [1] http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1292251.html Ravi Bangoria (5): perf/sdt: Show proper hint perf/sdt/x86: Add renaming logic for rNN and other registers perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ perf/sdt/powerpc: Add argument support perf/probe: Change MAX_CMDLEN tools/lib/api/fs/tracing_path.c | 16 +++- tools/perf/arch/powerpc/util/perf_regs.c | 115 ++++++++++++++++++++++++++ tools/perf/arch/x86/util/perf_regs.c | 137 ++++++++++++++++++++++++++++--- tools/perf/util/perf_regs.c | 9 +- tools/perf/util/perf_regs.h | 7 +- tools/perf/util/probe-event.c | 1 - tools/perf/util/probe-file.c | 129 ++++++++--------------------- 7 files changed, 294 insertions(+), 120 deletions(-) -- 2.9.3 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH 1/5] perf/sdt: Show proper hint 2017-02-02 11:11 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Ravi Bangoria @ 2017-02-02 11:11 ` Ravi Bangoria 2017-02-02 13:40 ` Ingo Molnar 2017-02-02 11:11 ` [PATCH 2/5] perf/sdt/x86: Add renaming logic for rNN and other registers Ravi Bangoria ` (4 subsequent siblings) 5 siblings, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-02-02 11:11 UTC (permalink / raw) To: acme, alexis.berlemont, linux-kernel Cc: peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy, Ravi Bangoria All events from 'perf list', except SDT events, can be directly recorded with 'perf record'. But, the flow is little different for SDT events. User has to probe on SDT events before recording them. Perf is showing misleading message when user tries to record SDT event without probing it. Show proper hint there. Before patch: $ perf record -a -e sdt_glib:idle__add event syntax error: 'sdt_glib:idle__add' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add ... Hint: Perhaps this kernel misses some CONFIG_ setting to enable... ... After patch: $ perf record -e sdt_glib:main__after_check event syntax error: 'sdt_glib:idle__add' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add ... Hint: SDT event has to be probed before recording it. Suggested-by: Ingo Molnar <mingo@redhat.com> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> --- tools/lib/api/fs/tracing_path.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c index 251b7c3..a0e85df 100644 --- a/tools/lib/api/fs/tracing_path.c +++ b/tools/lib/api/fs/tracing_path.c @@ -99,10 +99,18 @@ static int strerror_open(int err, char *buf, size_t size, const char *filename) * - jirka */ if (debugfs__configured() || tracefs__configured()) { - snprintf(buf, size, - "Error:\tFile %s/%s not found.\n" - "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", - tracing_events_path, filename); + /* sdt markers */ + if (!strncmp(filename, "sdt_", 4)) { + snprintf(buf, size, + "Error:\tFile %s/%s not found.\n" + "Hint:\tSDT event has to be probed before recording it.\n", + tracing_events_path, filename); + } else { + snprintf(buf, size, + "Error:\tFile %s/%s not found.\n" + "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", + tracing_events_path, filename); + } break; } snprintf(buf, size, "%s", -- 2.9.3 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH 1/5] perf/sdt: Show proper hint 2017-02-02 11:11 ` [PATCH 1/5] perf/sdt: Show proper hint Ravi Bangoria @ 2017-02-02 13:40 ` Ingo Molnar 2017-02-02 16:20 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 77+ messages in thread From: Ingo Molnar @ 2017-02-02 13:40 UTC (permalink / raw) To: Ravi Bangoria Cc: acme, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > After patch: > $ perf record -e sdt_glib:main__after_check > event syntax error: 'sdt_glib:idle__add' > \___ unknown tracepoint > > Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add ... > Hint: SDT event has to be probed before recording it. So what is the command line option to 'probe' an SDT event? Could you give an example that would make the above command work? Thanks, Ingo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH 1/5] perf/sdt: Show proper hint 2017-02-02 13:40 ` Ingo Molnar @ 2017-02-02 16:20 ` Arnaldo Carvalho de Melo 2017-02-03 10:26 ` [PATCH v2] " Ravi Bangoria 0 siblings, 1 reply; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-02-02 16:20 UTC (permalink / raw) To: Ingo Molnar Cc: Ravi Bangoria, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy Em Thu, Feb 02, 2017 at 02:40:48PM +0100, Ingo Molnar escreveu: > * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > After patch: > > $ perf record -e sdt_glib:main__after_check > > event syntax error: 'sdt_glib:idle__add' > > \___ unknown tracepoint > > Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add ... > > Hint: SDT event has to be probed before recording it. > > So what is the command line option to 'probe' an SDT event? Could you give an > example that would make the above command work? I also think 'has to be probed' looks confusing, it should be, I suggest, "put in place using 'perf probe'", what will case it to really be _probed_ is when it is activated via a tool like 'perf record'. So yes, I think the message _and_ the example in this commit log must show what needs to be done, in detail, to overcome the "problem" mentioned in the message above. And after that its up to someone to do the logical next step: if it needs to be put in place, well, do it, automagically. - Arnaldo ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v2] perf/sdt: Show proper hint 2017-02-02 16:20 ` Arnaldo Carvalho de Melo @ 2017-02-03 10:26 ` Ravi Bangoria 2017-02-03 15:18 ` Arnaldo Carvalho de Melo ` (2 more replies) 0 siblings, 3 replies; 77+ messages in thread From: Ravi Bangoria @ 2017-02-03 10:26 UTC (permalink / raw) To: linux-kernel, mingo, acme Cc: alexis.berlemont, peterz, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy, Ravi Bangoria All events from 'perf list', except SDT events, can be directly recorded with 'perf record'. But, the flow is little different for SDT events. Probe point for SDT event needs to be created using 'perf probe' before recording it using 'perf record'. Perf shows misleading hint when user tries to record SDT event without creating a probe point. Show proper hint there. Before patch: $ perf record -a -e sdt_glib:idle__add event syntax error: 'sdt_glib:idle__add' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. ... After patch: $ perf record -a -e sdt_glib:idle__add event syntax error: 'sdt_glib:idle__add' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. Hint: SDT event cannot be directly recorded on. Please use 'perf probe sdt_glib:idle__add' before recording it. ... $ perf probe sdt_glib:idle__add Added new event: sdt_glib:idle__add (on %idle__add in /usr/lib64/libglib-2.0.so.0.5000.2) You can now use it in all perf tools, such as: perf record -e sdt_glib:idle__add -aR sleep 1 $ perf record -a -e sdt_glib:idle__add [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.175 MB perf.data ] Suggested-by: Ingo Molnar <mingo@redhat.com> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> --- Changes in v2: - More precise hint tools/lib/api/fs/tracing_path.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c index 251b7c3..aaafc99 100644 --- a/tools/lib/api/fs/tracing_path.c +++ b/tools/lib/api/fs/tracing_path.c @@ -86,9 +86,13 @@ void put_tracing_file(char *file) free(file); } -static int strerror_open(int err, char *buf, size_t size, const char *filename) +int tracing_path__strerror_open_tp(int err, char *buf, size_t size, + const char *sys, const char *name) { char sbuf[128]; + char filename[PATH_MAX]; + + snprintf(filename, PATH_MAX, "%s/%s", sys, name ?: "*"); switch (err) { case ENOENT: @@ -99,10 +103,18 @@ static int strerror_open(int err, char *buf, size_t size, const char *filename) * - jirka */ if (debugfs__configured() || tracefs__configured()) { - snprintf(buf, size, - "Error:\tFile %s/%s not found.\n" - "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", - tracing_events_path, filename); + /* sdt markers */ + if (!strncmp(filename, "sdt_", 4)) { + snprintf(buf, size, + "Error:\tFile %s/%s not found.\n" + "Hint:\tSDT event cannot be directly recorded on. Please use 'perf probe %s:%s' before recording it.\n", + tracing_events_path, filename, sys, name); + } else { + snprintf(buf, size, + "Error:\tFile %s/%s not found.\n" + "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", + tracing_events_path, filename); + } break; } snprintf(buf, size, "%s", @@ -125,12 +137,3 @@ static int strerror_open(int err, char *buf, size_t size, const char *filename) return 0; } - -int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name) -{ - char path[PATH_MAX]; - - snprintf(path, PATH_MAX, "%s/%s", sys, name ?: "*"); - - return strerror_open(err, buf, size, path); -} -- 2.9.3 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH v2] perf/sdt: Show proper hint 2017-02-03 10:26 ` [PATCH v2] " Ravi Bangoria @ 2017-02-03 15:18 ` Arnaldo Carvalho de Melo 2017-02-07 7:53 ` Ingo Molnar ` (2 more replies) 2017-02-07 1:13 ` [PATCH v2] perf/sdt: Show proper hint Masami Hiramatsu 2017-02-10 7:44 ` [tip:perf/core] perf sdt: Show proper hint when event not yet in place via 'perf probe' tip-bot for Ravi Bangoria 2 siblings, 3 replies; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-02-03 15:18 UTC (permalink / raw) To: Ravi Bangoria Cc: linux-kernel, mingo, alexis.berlemont, peterz, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy Em Fri, Feb 03, 2017 at 03:56:42PM +0530, Ravi Bangoria escreveu: > After patch: > $ perf record -a -e sdt_glib:idle__add > event syntax error: 'sdt_glib:idle__add' > \___ unknown tracepoint > > Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. > Hint: SDT event cannot be directly recorded on. Please use 'perf probe sdt_glib:idle__add' before recording it. > ... > > $ perf probe sdt_glib:idle__add > Added new event: > sdt_glib:idle__add (on %idle__add in /usr/lib64/libglib-2.0.so.0.5000.2) > > You can now use it in all perf tools, such as: > > perf record -e sdt_glib:idle__add -aR sleep 1 > > $ perf record -a -e sdt_glib:idle__add > [ perf record: Woken up 1 times to write data ] > [ perf record: Captured and wrote 0.175 MB perf.data ] Looks much better! Thanks! Unsure if we should state somewhere that this needs to be done only once per boot. Ingo, are you ok now? Ack? - Arnaldo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v2] perf/sdt: Show proper hint 2017-02-03 15:18 ` Arnaldo Carvalho de Melo @ 2017-02-07 7:53 ` Ingo Molnar 2017-02-07 15:50 ` Arnaldo Carvalho de Melo 2017-02-07 8:00 ` Ingo Molnar 2017-02-16 10:16 ` [RFC] perf/sdt: Directly record SDT event with 'perf record' Ravi Bangoria 2 siblings, 1 reply; 77+ messages in thread From: Ingo Molnar @ 2017-02-07 7:53 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Ravi Bangoria, linux-kernel, mingo, alexis.berlemont, peterz, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy * Arnaldo Carvalho de Melo <acme@redhat.com> wrote: > Em Fri, Feb 03, 2017 at 03:56:42PM +0530, Ravi Bangoria escreveu: > > After patch: > > $ perf record -a -e sdt_glib:idle__add > > event syntax error: 'sdt_glib:idle__add' > > \___ unknown tracepoint > > > > Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. > > Hint: SDT event cannot be directly recorded on. Please use 'perf probe sdt_glib:idle__add' before recording it. > > ... > > > > $ perf probe sdt_glib:idle__add > > Added new event: > > sdt_glib:idle__add (on %idle__add in /usr/lib64/libglib-2.0.so.0.5000.2) > > > > You can now use it in all perf tools, such as: > > > > perf record -e sdt_glib:idle__add -aR sleep 1 > > > > $ perf record -a -e sdt_glib:idle__add > > [ perf record: Woken up 1 times to write data ] > > [ perf record: Captured and wrote 0.175 MB perf.data ] > > Looks much better! Thanks! > > Unsure if we should state somewhere that this needs to be done only once > per boot. > > Ingo, are you ok now? Ack? Yeah, looks perfect to me! Acked-by: Ingo Molnar <mingo@kernel.org> Thanks, Ingo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v2] perf/sdt: Show proper hint 2017-02-07 7:53 ` Ingo Molnar @ 2017-02-07 15:50 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-02-07 15:50 UTC (permalink / raw) To: Ingo Molnar Cc: Ravi Bangoria, linux-kernel, mingo, alexis.berlemont, peterz, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy Em Tue, Feb 07, 2017 at 08:53:56AM +0100, Ingo Molnar escreveu: > > * Arnaldo Carvalho de Melo <acme@redhat.com> wrote: > > > Em Fri, Feb 03, 2017 at 03:56:42PM +0530, Ravi Bangoria escreveu: > > > After patch: > > > $ perf record -a -e sdt_glib:idle__add > > > event syntax error: 'sdt_glib:idle__add' > > > \___ unknown tracepoint > > > > > > Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. > > > Hint: SDT event cannot be directly recorded on. Please use 'perf probe sdt_glib:idle__add' before recording it. > > > ... > > > > > > $ perf probe sdt_glib:idle__add > > > Added new event: > > > sdt_glib:idle__add (on %idle__add in /usr/lib64/libglib-2.0.so.0.5000.2) > > > > > > You can now use it in all perf tools, such as: > > > > > > perf record -e sdt_glib:idle__add -aR sleep 1 > > > > > > $ perf record -a -e sdt_glib:idle__add > > > [ perf record: Woken up 1 times to write data ] > > > [ perf record: Captured and wrote 0.175 MB perf.data ] > > > > Looks much better! Thanks! > > > > Unsure if we should state somewhere that this needs to be done only once > > per boot. > > > > Ingo, are you ok now? Ack? > > Yeah, looks perfect to me! > > Acked-by: Ingo Molnar <mingo@kernel.org> Thanks, added that "first" and split the Hint line in two. Automagically setting it up, doing the perf probe and rendering the above comment irrelevant remains as a task to be performed. - Arnaldo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v2] perf/sdt: Show proper hint 2017-02-03 15:18 ` Arnaldo Carvalho de Melo 2017-02-07 7:53 ` Ingo Molnar @ 2017-02-07 8:00 ` Ingo Molnar 2017-02-16 10:16 ` [RFC] perf/sdt: Directly record SDT event with 'perf record' Ravi Bangoria 2 siblings, 0 replies; 77+ messages in thread From: Ingo Molnar @ 2017-02-07 8:00 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Ravi Bangoria, linux-kernel, mingo, alexis.berlemont, peterz, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy * Arnaldo Carvalho de Melo <acme@redhat.com> wrote: > Em Fri, Feb 03, 2017 at 03:56:42PM +0530, Ravi Bangoria escreveu: > > After patch: > > $ perf record -a -e sdt_glib:idle__add > > event syntax error: 'sdt_glib:idle__add' > > \___ unknown tracepoint > > > > Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. > > Hint: SDT event cannot be directly recorded on. Please use 'perf probe sdt_glib:idle__add' before recording it. > > ... > > > > $ perf probe sdt_glib:idle__add > > Added new event: > > sdt_glib:idle__add (on %idle__add in /usr/lib64/libglib-2.0.so.0.5000.2) > > > > You can now use it in all perf tools, such as: > > > > perf record -e sdt_glib:idle__add -aR sleep 1 > > > > $ perf record -a -e sdt_glib:idle__add > > [ perf record: Woken up 1 times to write data ] > > [ perf record: Captured and wrote 0.175 MB perf.data ] > > Looks much better! Thanks! > > Unsure if we should state somewhere that this needs to be done only once > per boot. Forgot to reply to your question - indeed I agree that something like this would be even better: $ perf record -a -e sdt_glib:idle__add event syntax error: 'sdt_glib:idle__add' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. Hint: SDT event cannot be directly recorded on. Please first use 'perf probe sdt_glib:idle__add' before recording it. BTW., and I think this is fundamental: why is this interim step forced upon the user - cannot we just auto-enable it if it's not enabled yet? If for some reason it's important for the user to know that we enabled a probe we could print that we did so: Info: enabling not yet enabled 'perf probe sdt_glib:idle__add' SDT event. ... and that would be even more usable. A tool printing out the perfect thing for the user to type in is a sign that the tool should have done this itself. See for example how Git handles the bisection workflow. Technically the following is required to start a bisection: triton:~/tip> git bisect start triton:~/tip> git bisect bad triton:~/tip> But you can also do: triton:~/tip> git bisect bad You need to start by "git bisect start" Do you want me to do it for you [Y/n]? triton:~/tip> and the user can start the bisection by hitting Enter. No fuss, no unnecessary resistance from tooling - and the user is fully informed all along. Every extra tooling step forced upon users annoys them and shrinks the potential userbase. Thanks, Ingo ^ permalink raw reply [flat|nested] 77+ messages in thread
* [RFC] perf/sdt: Directly record SDT event with 'perf record' 2017-02-03 15:18 ` Arnaldo Carvalho de Melo 2017-02-07 7:53 ` Ingo Molnar 2017-02-07 8:00 ` Ingo Molnar @ 2017-02-16 10:16 ` Ravi Bangoria 2017-02-20 7:08 ` Ingo Molnar 2 siblings, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-02-16 10:16 UTC (permalink / raw) To: mingo, acme, masami.hiramatsu.pt Cc: brendan.d.gregg, peterz, alexander.shishkin, wangnan0, jolsa, ak, treeze.taeung, mathieu.poirier, hekuang, sukadev, ananth, naveen.n.rao, colin.ing, adrian.hunter, linux-kernel, hemant, Ravi Bangoria All events from 'perf list', except SDT events, can be directly recorded with 'perf record'. But, the flow is little different for SDT events. Probe point for SDT event needs to be created using 'perf probe' before recording it using 'perf record'. As suggested by Ingo[1], it's better to make this process simple by creating probe points automatically with 'perf record' for SDT events. This patch disables 'perf probe' on SDT events to simplify usage. It enables recording SDT event only with 'perf record'. This removes all those 'multiple events with same name' issues by not allowing manual probe creation to user. When there are multiple events with same name, 'perf record' will record all of them (in line with other tools supporting SDT (systemtap)). I know 'perf probe' for SDT events has already became interface and people are using it. But, doing this change will make user interface very easy and also it will make tool behaviour consistent. Also, it won't require any changes in uprobe_events structure (suggested by Masami[2]). After patch: $ perf list ... sdt_libpthread:mutex_entry [SDT event] ... $ perf probe -x /usr/lib64/libpthread-2.24.so %sdt_libpthread:mutex_entry SDT events don't need to be put in place using 'perf probe' anymore. You can directly record on SDT events using 'perf record' Error: Command Parse Error. $ perf record -a -e %sdt_libpthread:mutex_entry Warning : Recording on 2 occurences of sdt_libpthread:mutex_entry ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.190 MB perf.data (33 samples) ] $ perf evlist sdt_libpthread:mutex_entry sdt_libpthread:mutex_entry_1 Note: - This is no way a proper patch. Sending this RFC to get thoughts on the idea. - This is Hemant's patch[3] rebased to acme/perf/core, with few changes to disable 'perf probe' on SDT event. [1] https://lkml.org/lkml/2017/2/7/59 [2] https://lkml.org/lkml/2016/4/30/50 [3] https://lkml.org/lkml/2016/5/3/810 Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> --- tools/perf/builtin-record.c | 21 +++++++++ tools/perf/perf.h | 1 + tools/perf/util/parse-events.c | 53 ++++++++++++++++++++++- tools/perf/util/parse-events.h | 1 + tools/perf/util/probe-event.c | 43 ++++++++++++++++++- tools/perf/util/probe-event.h | 4 ++ tools/perf/util/probe-file.c | 97 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/probe-file.h | 8 ++++ 8 files changed, 225 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 2ddf189..37722f0 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -39,6 +39,7 @@ #include "util/trigger.h" #include "util/perf-hooks.h" #include "asm/bug.h" +#include "util/probe-file.h" #include <unistd.h> #include <sched.h> @@ -73,6 +74,7 @@ struct record { bool timestamp_filename; struct switch_output switch_output; unsigned long long samples; + struct list_head sdt_event_list; }; static volatile int auxtrace_record__snapshot_started; @@ -1502,6 +1504,23 @@ static struct record record = { }, }; +void sdt_event_list__add(struct list_head *sdt_event_list) +{ + if (list_empty(sdt_event_list)) + return; + list_splice(sdt_event_list, &record.sdt_event_list); +} + +bool is_cmd_record(void) +{ + return (record.evlist != NULL); +} + +static void sdt_event_list__remove(struct list_head *sdt_event_list) +{ + return remove_sdt_event_list(sdt_event_list); +} + const char record_callchain_help[] = CALLCHAIN_RECORD_HELP "\n\t\t\t\tDefault: fp"; @@ -1670,6 +1689,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) if (rec->evlist == NULL) return -ENOMEM; + INIT_LIST_HEAD(&rec->sdt_event_list); err = perf_config(perf_record_config, rec); if (err) return err; @@ -1836,6 +1856,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) perf_evlist__delete(rec->evlist); symbol__exit(); auxtrace_record__free(rec->itr); + sdt_event_list__remove(&rec->sdt_event_list); return err; } diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 1c27d94..9d8e5fe 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -76,4 +76,5 @@ struct record_opts { struct option; extern const char * const *record_usage; extern struct option *record_options; +bool is_cmd_record(void); #endif diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 07be076..3400a5a 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1726,13 +1726,64 @@ static void parse_events_print_error(struct parse_events_error *err, #undef MAX_WIDTH +static int parse_sdt_event(const char *str, struct list_head **sdt_list) +{ + char *ptr = NULL; + int ret; + struct list_head *sdt_evlist; + + ptr = strdup(str); + if (ptr == NULL) + return -ENOMEM; + + sdt_evlist = zalloc(sizeof(*sdt_evlist)); + if (!sdt_evlist) { + free(ptr); + pr_err("Error in sdt_evlist memory allocation\n"); + return -ENOMEM; + } + INIT_LIST_HEAD(sdt_evlist); + + /* + * If there is an error in this call, no need to free + * up sdt_evlist, its already free'ed up in the previous + * call. Free up 'ptr' though. + */ + ret = add_sdt_event(ptr, sdt_evlist); + + free(ptr); + if (!ret) + *sdt_list = sdt_evlist; + + return ret; +} + int parse_events_option(const struct option *opt, const char *str, int unset __maybe_unused) { struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; struct parse_events_error err = { .idx = 0, }; - int ret = parse_events(evlist, str, &err); + int ret = 0; + struct list_head *sdt_list = NULL; + struct sdt_event_list *event; + + if (*str == '%' && is_cmd_record()) { + ret = parse_sdt_event(str, &sdt_list); + if (!ret) { + list_for_each_entry(event, sdt_list, list) { + ret = parse_events(evlist, event->event_info, + &err); + if (ret < 0) + goto error; + } + /* Add it to the record struct */ + sdt_event_list__add(sdt_list); + } + } else { + ret = parse_events(evlist, str, &err); + } +error: if (ret) parse_events_print_error(&err, str); diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index da246a3..7dbeb7a 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -194,4 +194,5 @@ int is_valid_tracepoint(const char *event_string); int valid_event_mount(const char *eventfs); char *parse_events_formats_error_string(char *additional_terms); +void sdt_event_list__add(struct list_head *sdt_event_list); #endif /* __PERF_PARSE_EVENTS_H */ diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 2c1bca2..5bd5568 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1293,7 +1293,7 @@ int parse_line_range_desc(const char *arg, struct line_range *lr) return err; } -static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev) +int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev) { char *ptr; @@ -1347,7 +1347,8 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) if (arg[0] == '%' || (!strncmp(arg, "sdt_", 4) && !!strchr(arg, ':') && !strchr(arg, '='))) { - pev->sdt = true; + pr_err("SDT events don't need to be put in place using 'perf probe' anymore.\nYou can directly record on SDT events using 'perf record'\n"); + return -EINVAL; if (arg[0] == '%') arg++; } @@ -3173,6 +3174,12 @@ static int find_cached_events_all(struct perf_probe_event *pev, return ret; } +int find_sdt_events_from_cache(struct perf_probe_event *pev, + struct probe_trace_event **tevs) +{ + return find_cached_events_all(pev, tevs); +} + static int find_probe_trace_events_from_cache(struct perf_probe_event *pev, struct probe_trace_event **tevs) { @@ -3483,3 +3490,35 @@ int copy_to_probe_trace_arg(struct probe_trace_arg *tvar, tvar->name = NULL; return 0; } + +/* + * Record session for SDT events has ended. Delete the SDT events + * from uprobe_events file that were created initially. + */ +void remove_sdt_event_list(struct list_head *sdt_events) +{ + struct sdt_event_list *event; + struct strfilter *filter = NULL; + const char *err = NULL; + int ret = 0; + + if (list_empty(sdt_events)) + return; + + list_for_each_entry(event, sdt_events, list) { + if (!filter) { + filter = strfilter__new(event->event_info, &err); + if (!filter) + goto free_list; + } else { + ret = strfilter__or(filter, event->event_info, &err); + } + } + + ret = del_perf_probe_events(filter); + if (ret) + pr_err("Error in deleting the SDT list\n"); + +free_list: + free_sdt_list(sdt_events); +} diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 5d4e940..5ec648e 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -182,4 +182,8 @@ struct map *get_target_map(const char *target, bool user); void arch__post_process_probe_trace_events(struct perf_probe_event *pev, int ntevs); +int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev); + +int find_sdt_events_from_cache(struct perf_probe_event *pev, + struct probe_trace_event **tevs); #endif /*_PROBE_EVENT_H */ diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 436b647..2a6ad02 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -27,8 +27,10 @@ #include "probe-event.h" #include "probe-file.h" #include "session.h" +#include "probe-finder.h" #define MAX_CMDLEN 256 +#define MAX_EVENT_LENGTH 512 static void print_open_warning(int err, bool uprobe) { @@ -933,3 +935,98 @@ bool probe_type_is_available(enum probe_type type) return ret; } + +void free_sdt_list(struct list_head *sdt_events) +{ + struct sdt_event_list *tmp, *ptr; + + if (list_empty(sdt_events)) + return; + list_for_each_entry_safe(tmp, ptr, sdt_events, list) { + list_del(&tmp->list); + free(tmp->event_info); + free(tmp); + } +} + +/* + * Find the SDT event from the cache and if found add it/them + * to the uprobe_events file + */ +int add_sdt_event(char *event, struct list_head *sdt_events) +{ + struct perf_probe_event *pev; + int ret, i; + char *str = event + 1; + struct sdt_event_list *tmp; + + pev = zalloc(sizeof(*pev)); + if (!pev) + return -ENOMEM; + + pev->sdt = true; + pev->uprobes = true; + + /* + * Parse str to find the group name and event name of + * the sdt event. + */ + ret = parse_perf_probe_event_name(&str, pev); + if (ret) { + pr_err("Error in parsing sdt event %s\n", str); + free(pev); + return ret; + } + + probe_conf.max_probes = MAX_PROBES; + probe_conf.force_add = 1; + + /* + * Find the sdt event from the cache, only cached SDT + * events can be directly recorded. + */ + pev->ntevs = find_sdt_events_from_cache(pev, &pev->tevs); + if (pev->ntevs) { + if (pev->ntevs > 1) { + pr_warning("Warning : Recording on %d occurences of %s:%s\n", + pev->ntevs, pev->group, pev->event); + } + ret = apply_perf_probe_events(pev, 1); + if (ret) { + pr_err("Error in adding SDT event : %s\n", event); + goto free_pev; + } + } else { + pr_err(" %s:%s not found in the cache\n", pev->group, + pev->event); + ret = -EINVAL; + goto free_pev; + } + + /* Add the event name to "sdt_events" list */ + for (i = 0; i < pev->ntevs; i++) { + tmp = zalloc(sizeof(*tmp)); + if (!tmp) { + ret = -ENOMEM; + goto free_pev; + } + + INIT_LIST_HEAD(&tmp->list); + tmp->event_info = zalloc(MAX_EVENT_LENGTH * sizeof(char)); + if (!tmp->event_info) { + free_sdt_list(sdt_events); + ret = -ENOMEM; + goto free_pev; + } + snprintf(tmp->event_info, strlen(pev->tevs[i].group) + + strlen(pev->tevs[i].event) + 2, "%s:%s", + pev->tevs[i].group, pev->tevs[i].event); + list_add(&tmp->list, sdt_events); + } + + ret = 0; + +free_pev: + cleanup_perf_probe_events(pev, 1); + return ret; +} diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h index eba44c3..3b39681 100644 --- a/tools/perf/util/probe-file.h +++ b/tools/perf/util/probe-file.h @@ -19,6 +19,11 @@ struct probe_cache { struct list_head entries; }; +struct sdt_event_list { + char *event_info; + struct list_head list; +}; + enum probe_type { PROBE_TYPE_U = 0, PROBE_TYPE_S, @@ -64,6 +69,9 @@ struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache, const char *group, const char *event); int probe_cache__show_all_caches(struct strfilter *filter); bool probe_type_is_available(enum probe_type type); +int add_sdt_event(char *event, struct list_head *sdt_event_list); +void remove_sdt_event_list(struct list_head *sdt_event_list); +void free_sdt_list(struct list_head *sdt_events); #else /* ! HAVE_LIBELF_SUPPORT */ static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused) { -- 2.9.3 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [RFC] perf/sdt: Directly record SDT event with 'perf record' 2017-02-16 10:16 ` [RFC] perf/sdt: Directly record SDT event with 'perf record' Ravi Bangoria @ 2017-02-20 7:08 ` Ingo Molnar 2017-02-20 8:21 ` Ravi Bangoria 0 siblings, 1 reply; 77+ messages in thread From: Ingo Molnar @ 2017-02-20 7:08 UTC (permalink / raw) To: Ravi Bangoria Cc: mingo, acme, masami.hiramatsu.pt, brendan.d.gregg, peterz, alexander.shishkin, wangnan0, jolsa, ak, treeze.taeung, mathieu.poirier, hekuang, sukadev, ananth, naveen.n.rao, colin.ing, adrian.hunter, linux-kernel, hemant * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > All events from 'perf list', except SDT events, can be directly recorded > with 'perf record'. But, the flow is little different for SDT events. > Probe point for SDT event needs to be created using 'perf probe' before > recording it using 'perf record'. > > As suggested by Ingo[1], it's better to make this process simple by > creating probe points automatically with 'perf record' for SDT events. > > This patch disables 'perf probe' on SDT events to simplify usage. It > enables recording SDT event only with 'perf record'. > > This removes all those 'multiple events with same name' issues by not > allowing manual probe creation to user. When there are multiple events > with same name, 'perf record' will record all of them (in line with > other tools supporting SDT (systemtap)). > > I know 'perf probe' for SDT events has already became interface and > people are using it. But, doing this change will make user interface very > easy and also it will make tool behaviour consistent. Also, it won't > require any changes in uprobe_events structure (suggested by Masami[2]). So I like the automatism you implemented for 'perf record', but why not keep the 'perf probe' flow as well, if people got used to it? It's not like computer software is bad at sorting apart and handling the two cases properly, right? Thanks, Ingo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [RFC] perf/sdt: Directly record SDT event with 'perf record' 2017-02-20 7:08 ` Ingo Molnar @ 2017-02-20 8:21 ` Ravi Bangoria 2017-02-20 8:42 ` Ingo Molnar 0 siblings, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-02-20 8:21 UTC (permalink / raw) To: Ingo Molnar Cc: mingo, acme, masami.hiramatsu.pt, brendan.d.gregg, peterz, alexander.shishkin, wangnan0, jolsa, ak, treeze.taeung, mathieu.poirier, hekuang, sukadev, ananth, naveen.n.rao, colin.ing, adrian.hunter, linux-kernel, hemant, Ravi Bangoria On Monday 20 February 2017 12:38 PM, Ingo Molnar wrote: > * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > >> All events from 'perf list', except SDT events, can be directly recorded >> with 'perf record'. But, the flow is little different for SDT events. >> Probe point for SDT event needs to be created using 'perf probe' before >> recording it using 'perf record'. >> >> As suggested by Ingo[1], it's better to make this process simple by >> creating probe points automatically with 'perf record' for SDT events. >> >> This patch disables 'perf probe' on SDT events to simplify usage. It >> enables recording SDT event only with 'perf record'. >> >> This removes all those 'multiple events with same name' issues by not >> allowing manual probe creation to user. When there are multiple events >> with same name, 'perf record' will record all of them (in line with >> other tools supporting SDT (systemtap)). >> >> I know 'perf probe' for SDT events has already became interface and >> people are using it. But, doing this change will make user interface very >> easy and also it will make tool behaviour consistent. Also, it won't >> require any changes in uprobe_events structure (suggested by Masami[2]). > So I like the automatism you implemented for 'perf record', but why not keep the > 'perf probe' flow as well, if people got used to it? > > It's not like computer software is bad at sorting apart and handling the two cases > properly, right? Thanks Ingo for the reply, Yes, initially I thought about allowing both, 'perf probe' and 'perf record' for SDT event. But there are few complications with it, esp. when multiple SDT events with same name exists. For ex, $ readelf -n /usr/lib64/libpthread-2.24.so | grep -A2 Provider Provider: libpthread Name: mutex_entry Location: 0x0000000000009ddb, ... -- Provider: libpthread Name: mutex_entry Location: 0x000000000000bcbb, ... At the time of record, perf has to check first if there is any matching entry exists in uprobe_events with that name. If found, record it, if not, go look into probe cache. If events exists with same name in probe cache, record all of them. Like, If probe point _is not_ created, $ perf record -a -e sdt_libpthread:mutex_entry /** Record both sdt_libpthread:mutex_entry **/ If probe point _is_ created manually, record that particular event, $ perf probe -x /usr/lib64/libpthread-2.24.so sdt_libpthread:mutex_entry Added new events: sdt_libpthread:mutex_entry (on %mutex_entry in /usr/lib64/libpthread-2.24.so) sdt_libpthread:mutex_entry_1 (on %mutex_entry in /usr/lib64/libpthread-2.24.so) $ perf record -a -e sdt_libpthread:mutex_entry /** Record only first sdt_libpthread:mutex_entry **/ Here, same command gives different behaviour for different scenarios. Now consider a scenario when probe point exists for any one event: $ perf probe -d sdt_libpthread:mutex_entry_1 $ perf probe --list sdt_libpthread:mutex_entry (on pthread_mutex_lock+11 in /usr/lib64/libpthread-2.24.so) And user tries to record it by, $ perf record -a -e sdt_libpthread:* What should be the behavior of the tool? Should it record only one 'sdt_libpthread:mutex_entry' which exists in uprobe_events? Or it should record all the SDT events from libpthread? We can choose either of two but both the cases are ambiguous. Not allowing 'perf probe' for SDT event will solve all such issues. Also it will make user interface simple and consistent. Other current tooling (systemtap, for instance) also do not allow probing individual markers when there are multiple markers with the same name. -Ravi ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [RFC] perf/sdt: Directly record SDT event with 'perf record' 2017-02-20 8:21 ` Ravi Bangoria @ 2017-02-20 8:42 ` Ingo Molnar 2017-02-20 11:01 ` Ravi Bangoria 0 siblings, 1 reply; 77+ messages in thread From: Ingo Molnar @ 2017-02-20 8:42 UTC (permalink / raw) To: Ravi Bangoria Cc: mingo, acme, masami.hiramatsu.pt, brendan.d.gregg, peterz, alexander.shishkin, wangnan0, jolsa, ak, treeze.taeung, mathieu.poirier, hekuang, sukadev, ananth, naveen.n.rao, colin.ing, adrian.hunter, linux-kernel, hemant * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > Yes, initially I thought about allowing both, 'perf probe' and > 'perf record' for SDT event. But there are few complications with > it, esp. when multiple SDT events with same name exists. For ex, > > $ readelf -n /usr/lib64/libpthread-2.24.so | grep -A2 Provider > Provider: libpthread > Name: mutex_entry > Location: 0x0000000000009ddb, ... > -- > Provider: libpthread > Name: mutex_entry > Location: 0x000000000000bcbb, ... > > At the time of record, perf has to check first if there is any > matching entry exists in uprobe_events with that name. If found, > record it, if not, go look into probe cache. If events exists with > same name in probe cache, record all of them. Like, > > If probe point _is not_ created, > $ perf record -a -e sdt_libpthread:mutex_entry > /** Record both sdt_libpthread:mutex_entry **/ > > If probe point _is_ created manually, record that particular event, > $ perf probe -x /usr/lib64/libpthread-2.24.so sdt_libpthread:mutex_entry > Added new events: > sdt_libpthread:mutex_entry (on %mutex_entry in /usr/lib64/libpthread-2.24.so) > sdt_libpthread:mutex_entry_1 (on %mutex_entry in /usr/lib64/libpthread-2.24.so) > > $ perf record -a -e sdt_libpthread:mutex_entry > /** Record only first sdt_libpthread:mutex_entry **/ > > Here, same command gives different behaviour for different scenarios. > > Now consider a scenario when probe point exists for any one event: > > $ perf probe -d sdt_libpthread:mutex_entry_1 > $ perf probe --list > sdt_libpthread:mutex_entry (on pthread_mutex_lock+11 in /usr/lib64/libpthread-2.24.so) > > And user tries to record it by, > $ perf record -a -e sdt_libpthread:* > > What should be the behavior of the tool? Should it record only one > 'sdt_libpthread:mutex_entry' which exists in uprobe_events? Or it > should record all the SDT events from libpthread? We can choose either > of two but both the cases are ambiguous. They are not ambiguous really if coded right: just pick one of the outcomes and maybe print a warning to inform the user that something weird is going on because not all markers are enabled? As a user I'd expect 'perf record' to enable all markers and print a warning that the markers were in a partial state. This would result in consistent behaviour. Does it make sense to only enable some of the markers that alias on the same name? If not then maybe disallow that in perf probe - or change perf probe to do the same thing as perf record. I.e. this is IMHO an artificial problem that users should not be exposed to and which can be solved by tooling. In particular if it's possible to enable only a part of the markers then perf record not continuing would be a failure mode: if for example a previous perf record session segfaulted (or ran out of RAM or was killed in the wrong moment or whatever) then it would not be possible to (easily) clean up the mess. > Not allowing 'perf probe' for SDT event will solve all such issues. > Also it will make user interface simple and consistent. Other current > tooling (systemtap, for instance) also do not allow probing individual > markers when there are multiple markers with the same name. In any case if others agree with your change in UI flow too then it's fine by me, but please make it robust, i.e. if perf record sees partially enabled probes it should still continue. Thanks, Ingo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [RFC] perf/sdt: Directly record SDT event with 'perf record' 2017-02-20 8:42 ` Ingo Molnar @ 2017-02-20 11:01 ` Ravi Bangoria 2017-02-20 14:11 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-02-20 11:01 UTC (permalink / raw) To: Ingo Molnar, masami.hiramatsu.pt Cc: mingo, acme, brendan.d.gregg, peterz, alexander.shishkin, wangnan0, jolsa, ak, treeze.taeung, mathieu.poirier, hekuang, sukadev, ananth, naveen.n.rao, colin.ing, adrian.hunter, linux-kernel, hemant, Ravi Bangoria Thanks Ingo, On Monday 20 February 2017 02:12 PM, Ingo Molnar wrote: > * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > >> What should be the behavior of the tool? Should it record only one >> 'sdt_libpthread:mutex_entry' which exists in uprobe_events? Or it >> should record all the SDT events from libpthread? We can choose either >> of two but both the cases are ambiguous. > They are not ambiguous really if coded right: just pick one of the outcomes and > maybe print a warning to inform the user that something weird is going on because > not all markers are enabled? > > As a user I'd expect 'perf record' to enable all markers and print a warning that > the markers were in a partial state. This would result in consistent behaviour. Yes, makes sense. > Does it make sense to only enable some of the markers that alias on the same name? > If not then maybe disallow that in perf probe - or change perf probe to do the > same thing as perf record. 'perf probe' is doing that correctly. It fetches all events with given name from probe-cache and creates entries for them in uprobe_events. The problem is the 2-step process of adding probes and then recording, allowing users to select individual markers to record on. > > I.e. this is IMHO an artificial problem that users should not be exposed to and > which can be solved by tooling. > > In particular if it's possible to enable only a part of the markers then perf > record not continuing would be a failure mode: if for example a previous perf > record session segfaulted (or ran out of RAM or was killed in the wrong moment or > whatever) then it would not be possible to (easily) clean up the mess. Agreed. We need to make this more robust. > >> Not allowing 'perf probe' for SDT event will solve all such issues. >> Also it will make user interface simple and consistent. Other current >> tooling (systemtap, for instance) also do not allow probing individual >> markers when there are multiple markers with the same name. > In any case if others agree with your change in UI flow too then it's fine by me, > but please make it robust, i.e. if perf record sees partially enabled probes it > should still continue. @Masami, can you please provide your thoughts as well. Thanks, Ravi ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [RFC] perf/sdt: Directly record SDT event with 'perf record' 2017-02-20 11:01 ` Ravi Bangoria @ 2017-02-20 14:11 ` Arnaldo Carvalho de Melo 2017-02-23 8:13 ` Ravi Bangoria 0 siblings, 1 reply; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-02-20 14:11 UTC (permalink / raw) To: Ravi Bangoria Cc: Ingo Molnar, masami.hiramatsu.pt, mingo, brendan.d.gregg, peterz, alexander.shishkin, wangnan0, jolsa, ak, treeze.taeung, mathieu.poirier, hekuang, sukadev, ananth, naveen.n.rao, colin.ing, adrian.hunter, linux-kernel, hemant Em Mon, Feb 20, 2017 at 04:31:50PM +0530, Ravi Bangoria escreveu: > Thanks Ingo, > > On Monday 20 February 2017 02:12 PM, Ingo Molnar wrote: > > * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > >> What should be the behavior of the tool? Should it record only one > >> 'sdt_libpthread:mutex_entry' which exists in uprobe_events? Or it > >> should record all the SDT events from libpthread? We can choose either > >> of two but both the cases are ambiguous. > > They are not ambiguous really if coded right: just pick one of the outcomes and > > maybe print a warning to inform the user that something weird is going on because > > not all markers are enabled? > > > > As a user I'd expect 'perf record' to enable all markers and print a warning that > > the markers were in a partial state. This would result in consistent behaviour. > > Yes, makes sense. > > > Does it make sense to only enable some of the markers that alias on the same name? > > If not then maybe disallow that in perf probe - or change perf probe to do the > > same thing as perf record. > > 'perf probe' is doing that correctly. It fetches all events with given name from > probe-cache and creates entries for them in uprobe_events. > > The problem is the 2-step process of adding probes and then recording, > allowing users to select individual markers to record on. So, the more streamlined one works for most people, i.e. just use perf record, no need to perf probe anything. But, for people who "know what they are doing", perf probe can be used first to control exactly which SDT probes one wants in place, and then those will be used. We need to make sure that when processing the file there is information that says which probes were in place and enabled in the record session, tho. Is that possible? > > I.e. this is IMHO an artificial problem that users should not be exposed to and > > which can be solved by tooling. > > > > In particular if it's possible to enable only a part of the markers then perf > > record not continuing would be a failure mode: if for example a previous perf > > record session segfaulted (or ran out of RAM or was killed in the wrong moment or > > whatever) then it would not be possible to (easily) clean up the mess. > Agreed. We need to make this more robust. Right, disambiguating a 'probes left by a session that did auto-probing' from a 'hey, those probes are there intentionally, just use those' is important. > >> Not allowing 'perf probe' for SDT event will solve all such issues. > >> Also it will make user interface simple and consistent. Other current > >> tooling (systemtap, for instance) also do not allow probing individual > >> markers when there are multiple markers with the same name. > > In any case if others agree with your change in UI flow too then it's fine by me, > > but please make it robust, i.e. if perf record sees partially enabled probes it > > should still continue. > @Masami, can you please provide your thoughts as well. Yeah, if technically possible to allow both variants, we should leave it up to users to decide what is best? I.e. most people will do auto-probing, not using 'perf probe' at all, documentation should state the pitfalls in doing so. So, after writing the above, perhaps we should warn the user that pre-existing probes are being used, as this will be the odd case? The normal flow will be just using perf record with SDT probes, that will auto-probe them and remove on exit, or better drop a reference to them, as simultaneous use also needs to be covered? - Arnaldo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [RFC] perf/sdt: Directly record SDT event with 'perf record' 2017-02-20 14:11 ` Arnaldo Carvalho de Melo @ 2017-02-23 8:13 ` Ravi Bangoria 2017-02-23 12:48 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-02-23 8:13 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Ingo Molnar, masami.hiramatsu.pt, mingo, brendan.d.gregg, peterz, alexander.shishkin, wangnan0, jolsa, ak, treeze.taeung, mathieu.poirier, hekuang, sukadev, ananth, naveen.n.rao, colin.ing, adrian.hunter, linux-kernel, hemant, Ravi Bangoria Thanks Arnaldo, I'm working on this but it's taking bit longer time. Will post out a patch within few days. Ravi On Monday 20 February 2017 07:41 PM, Arnaldo Carvalho de Melo wrote: > Em Mon, Feb 20, 2017 at 04:31:50PM +0530, Ravi Bangoria escreveu: >> Thanks Ingo, >> >> On Monday 20 February 2017 02:12 PM, Ingo Molnar wrote: >>> * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: >>> >>>> What should be the behavior of the tool? Should it record only one >>>> 'sdt_libpthread:mutex_entry' which exists in uprobe_events? Or it >>>> should record all the SDT events from libpthread? We can choose either >>>> of two but both the cases are ambiguous. >>> They are not ambiguous really if coded right: just pick one of the outcomes and >>> maybe print a warning to inform the user that something weird is going on because >>> not all markers are enabled? >>> >>> As a user I'd expect 'perf record' to enable all markers and print a warning that >>> the markers were in a partial state. This would result in consistent behaviour. >> Yes, makes sense. >> >>> Does it make sense to only enable some of the markers that alias on the same name? >>> If not then maybe disallow that in perf probe - or change perf probe to do the >>> same thing as perf record. >> 'perf probe' is doing that correctly. It fetches all events with given name from >> probe-cache and creates entries for them in uprobe_events. >> >> The problem is the 2-step process of adding probes and then recording, >> allowing users to select individual markers to record on. > So, the more streamlined one works for most people, i.e. just use perf > record, no need to perf probe anything. But, for people who "know what > they are doing", perf probe can be used first to control exactly which > SDT probes one wants in place, and then those will be used. > > We need to make sure that when processing the file there is information > that says which probes were in place and enabled in the record session, > tho. Is that possible? > >>> I.e. this is IMHO an artificial problem that users should not be exposed to and >>> which can be solved by tooling. >>> >>> In particular if it's possible to enable only a part of the markers then perf >>> record not continuing would be a failure mode: if for example a previous perf >>> record session segfaulted (or ran out of RAM or was killed in the wrong moment or >>> whatever) then it would not be possible to (easily) clean up the mess. >> Agreed. We need to make this more robust. > Right, disambiguating a 'probes left by a session that did auto-probing' > from a 'hey, those probes are there intentionally, just use those' is > important. > >>>> Not allowing 'perf probe' for SDT event will solve all such issues. >>>> Also it will make user interface simple and consistent. Other current >>>> tooling (systemtap, for instance) also do not allow probing individual >>>> markers when there are multiple markers with the same name. >>> In any case if others agree with your change in UI flow too then it's fine by me, >>> but please make it robust, i.e. if perf record sees partially enabled probes it >>> should still continue. >> @Masami, can you please provide your thoughts as well. > Yeah, if technically possible to allow both variants, we should leave > it up to users to decide what is best? > > I.e. most people will do auto-probing, not using 'perf probe' at all, > documentation should state the pitfalls in doing so. > > So, after writing the above, perhaps we should warn the user that > pre-existing probes are being used, as this will be the odd case? > > The normal flow will be just using perf record with SDT probes, that > will auto-probe them and remove on exit, or better drop a reference to > them, as simultaneous use also needs to be covered? > > - Arnaldo > ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [RFC] perf/sdt: Directly record SDT event with 'perf record' 2017-02-23 8:13 ` Ravi Bangoria @ 2017-02-23 12:48 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-02-23 12:48 UTC (permalink / raw) To: Ravi Bangoria Cc: Ingo Molnar, masami.hiramatsu.pt, mingo, brendan.d.gregg, peterz, alexander.shishkin, wangnan0, jolsa, ak, treeze.taeung, mathieu.poirier, hekuang, sukadev, ananth, naveen.n.rao, colin.ing, adrian.hunter, linux-kernel, hemant Em Thu, Feb 23, 2017 at 01:43:38PM +0530, Ravi Bangoria escreveu: > Thanks Arnaldo, > > I'm working on this but it's taking bit longer time. Will post out a patch within > few days. Take your time and thanks for giving consideration to my observations, Regards, - Arnaldo > Ravi > > On Monday 20 February 2017 07:41 PM, Arnaldo Carvalho de Melo wrote: > > Em Mon, Feb 20, 2017 at 04:31:50PM +0530, Ravi Bangoria escreveu: > >> Thanks Ingo, > >> > >> On Monday 20 February 2017 02:12 PM, Ingo Molnar wrote: > >>> * Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > >>> > >>>> What should be the behavior of the tool? Should it record only one > >>>> 'sdt_libpthread:mutex_entry' which exists in uprobe_events? Or it > >>>> should record all the SDT events from libpthread? We can choose either > >>>> of two but both the cases are ambiguous. > >>> They are not ambiguous really if coded right: just pick one of the outcomes and > >>> maybe print a warning to inform the user that something weird is going on because > >>> not all markers are enabled? > >>> > >>> As a user I'd expect 'perf record' to enable all markers and print a warning that > >>> the markers were in a partial state. This would result in consistent behaviour. > >> Yes, makes sense. > >> > >>> Does it make sense to only enable some of the markers that alias on the same name? > >>> If not then maybe disallow that in perf probe - or change perf probe to do the > >>> same thing as perf record. > >> 'perf probe' is doing that correctly. It fetches all events with given name from > >> probe-cache and creates entries for them in uprobe_events. > >> > >> The problem is the 2-step process of adding probes and then recording, > >> allowing users to select individual markers to record on. > > So, the more streamlined one works for most people, i.e. just use perf > > record, no need to perf probe anything. But, for people who "know what > > they are doing", perf probe can be used first to control exactly which > > SDT probes one wants in place, and then those will be used. > > > > We need to make sure that when processing the file there is information > > that says which probes were in place and enabled in the record session, > > tho. Is that possible? > > > >>> I.e. this is IMHO an artificial problem that users should not be exposed to and > >>> which can be solved by tooling. > >>> > >>> In particular if it's possible to enable only a part of the markers then perf > >>> record not continuing would be a failure mode: if for example a previous perf > >>> record session segfaulted (or ran out of RAM or was killed in the wrong moment or > >>> whatever) then it would not be possible to (easily) clean up the mess. > >> Agreed. We need to make this more robust. > > Right, disambiguating a 'probes left by a session that did auto-probing' > > from a 'hey, those probes are there intentionally, just use those' is > > important. > > > >>>> Not allowing 'perf probe' for SDT event will solve all such issues. > >>>> Also it will make user interface simple and consistent. Other current > >>>> tooling (systemtap, for instance) also do not allow probing individual > >>>> markers when there are multiple markers with the same name. > >>> In any case if others agree with your change in UI flow too then it's fine by me, > >>> but please make it robust, i.e. if perf record sees partially enabled probes it > >>> should still continue. > >> @Masami, can you please provide your thoughts as well. > > Yeah, if technically possible to allow both variants, we should leave > > it up to users to decide what is best? > > > > I.e. most people will do auto-probing, not using 'perf probe' at all, > > documentation should state the pitfalls in doing so. > > > > So, after writing the above, perhaps we should warn the user that > > pre-existing probes are being used, as this will be the odd case? > > > > The normal flow will be just using perf record with SDT probes, that > > will auto-probe them and remove on exit, or better drop a reference to > > them, as simultaneous use also needs to be covered? > > > > - Arnaldo > > ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v2] perf/sdt: Show proper hint 2017-02-03 10:26 ` [PATCH v2] " Ravi Bangoria 2017-02-03 15:18 ` Arnaldo Carvalho de Melo @ 2017-02-07 1:13 ` Masami Hiramatsu 2017-02-10 7:44 ` [tip:perf/core] perf sdt: Show proper hint when event not yet in place via 'perf probe' tip-bot for Ravi Bangoria 2 siblings, 0 replies; 77+ messages in thread From: Masami Hiramatsu @ 2017-02-07 1:13 UTC (permalink / raw) To: Ravi Bangoria Cc: linux-kernel, mingo, acme, alexis.berlemont, peterz, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy On Fri, 3 Feb 2017 15:56:42 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > All events from 'perf list', except SDT events, can be directly recorded > with 'perf record'. But, the flow is little different for SDT events. > Probe point for SDT event needs to be created using 'perf probe' before > recording it using 'perf record'. Perf shows misleading hint when user > tries to record SDT event without creating a probe point. Show proper > hint there. > > Before patch: > $ perf record -a -e sdt_glib:idle__add > event syntax error: 'sdt_glib:idle__add' > \___ unknown tracepoint > > Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. > Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. > ... > > After patch: > $ perf record -a -e sdt_glib:idle__add > event syntax error: 'sdt_glib:idle__add' > \___ unknown tracepoint > > Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. > Hint: SDT event cannot be directly recorded on. Please use 'perf probe sdt_glib:idle__add' before recording it. > ... > > $ perf probe sdt_glib:idle__add > Added new event: > sdt_glib:idle__add (on %idle__add in /usr/lib64/libglib-2.0.so.0.5000.2) > > You can now use it in all perf tools, such as: > > perf record -e sdt_glib:idle__add -aR sleep 1 > > $ perf record -a -e sdt_glib:idle__add > [ perf record: Woken up 1 times to write data ] > [ perf record: Captured and wrote 0.175 MB perf.data ] > Looks good to me:) Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Thanks! > Suggested-by: Ingo Molnar <mingo@redhat.com> > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> > --- > Changes in v2: > - More precise hint > > tools/lib/api/fs/tracing_path.c | 31 +++++++++++++++++-------------- > 1 file changed, 17 insertions(+), 14 deletions(-) > > diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c > index 251b7c3..aaafc99 100644 > --- a/tools/lib/api/fs/tracing_path.c > +++ b/tools/lib/api/fs/tracing_path.c > @@ -86,9 +86,13 @@ void put_tracing_file(char *file) > free(file); > } > > -static int strerror_open(int err, char *buf, size_t size, const char *filename) > +int tracing_path__strerror_open_tp(int err, char *buf, size_t size, > + const char *sys, const char *name) > { > char sbuf[128]; > + char filename[PATH_MAX]; > + > + snprintf(filename, PATH_MAX, "%s/%s", sys, name ?: "*"); > > switch (err) { > case ENOENT: > @@ -99,10 +103,18 @@ static int strerror_open(int err, char *buf, size_t size, const char *filename) > * - jirka > */ > if (debugfs__configured() || tracefs__configured()) { > - snprintf(buf, size, > - "Error:\tFile %s/%s not found.\n" > - "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", > - tracing_events_path, filename); > + /* sdt markers */ > + if (!strncmp(filename, "sdt_", 4)) { > + snprintf(buf, size, > + "Error:\tFile %s/%s not found.\n" > + "Hint:\tSDT event cannot be directly recorded on. Please use 'perf probe %s:%s' before recording it.\n", > + tracing_events_path, filename, sys, name); > + } else { > + snprintf(buf, size, > + "Error:\tFile %s/%s not found.\n" > + "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", > + tracing_events_path, filename); > + } > break; > } > snprintf(buf, size, "%s", > @@ -125,12 +137,3 @@ static int strerror_open(int err, char *buf, size_t size, const char *filename) > > return 0; > } > - > -int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name) > -{ > - char path[PATH_MAX]; > - > - snprintf(path, PATH_MAX, "%s/%s", sys, name ?: "*"); > - > - return strerror_open(err, buf, size, path); > -} > -- > 2.9.3 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [tip:perf/core] perf sdt: Show proper hint when event not yet in place via 'perf probe' 2017-02-03 10:26 ` [PATCH v2] " Ravi Bangoria 2017-02-03 15:18 ` Arnaldo Carvalho de Melo 2017-02-07 1:13 ` [PATCH v2] perf/sdt: Show proper hint Masami Hiramatsu @ 2017-02-10 7:44 ` tip-bot for Ravi Bangoria 2 siblings, 0 replies; 77+ messages in thread From: tip-bot for Ravi Bangoria @ 2017-02-10 7:44 UTC (permalink / raw) To: linux-tip-commits Cc: linux-kernel, maddy, ravi.bangoria, mingo, tglx, mhiramat, acme, peterz, alexis.berlemont, mpe, alexander.shishkin, hpa, naveen.n.rao, mingo Commit-ID: 27cf5706a04e53f6844c71be1cbbf1df665f5d19 Gitweb: http://git.kernel.org/tip/27cf5706a04e53f6844c71be1cbbf1df665f5d19 Author: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> AuthorDate: Fri, 3 Feb 2017 15:56:42 +0530 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Wed, 8 Feb 2017 09:28:54 -0300 perf sdt: Show proper hint when event not yet in place via 'perf probe' All events from 'perf list', except SDT events, can be directly recorded with 'perf record'. But, the flow is little different for SDT events. Probe points for SDT event needs to be created using 'perf probe' before recording it using 'perf record'. Perf shows misleading hint when a user tries to record SDT event without first creating a probe point. Show proper hint there. Before patch: $ perf record -a -e sdt_glib:idle__add event syntax error: 'sdt_glib:idle__add' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. ... After patch: $ perf record -a -e sdt_glib:idle__add event syntax error: 'sdt_glib:idle__add' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sdt_glib/idle__add not found. Hint: SDT event cannot be directly recorded on. Please first use 'perf probe sdt_glib:idle__add' before recording it. ... $ perf probe sdt_glib:idle__add Added new event: sdt_glib:idle__add (on %idle__add in /usr/lib64/libglib-2.0.so.0.5000.2) You can now use it in all perf tools, such as: perf record -e sdt_glib:idle__add -aR sleep 1 $ perf record -a -e sdt_glib:idle__add [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.175 MB perf.data ] Suggested-and-Acked-by: Ingo Molnar <mingo@redhat.com> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexis Berlemont <alexis.berlemont@gmail.com> Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20170203102642.17258-1-ravi.bangoria@linux.vnet.ibm.com [ s/Please use/Please first use/ and break the Hint line in two ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/lib/api/fs/tracing_path.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c index 251b7c3..3e606b9 100644 --- a/tools/lib/api/fs/tracing_path.c +++ b/tools/lib/api/fs/tracing_path.c @@ -86,9 +86,13 @@ void put_tracing_file(char *file) free(file); } -static int strerror_open(int err, char *buf, size_t size, const char *filename) +int tracing_path__strerror_open_tp(int err, char *buf, size_t size, + const char *sys, const char *name) { char sbuf[128]; + char filename[PATH_MAX]; + + snprintf(filename, PATH_MAX, "%s/%s", sys, name ?: "*"); switch (err) { case ENOENT: @@ -99,10 +103,19 @@ static int strerror_open(int err, char *buf, size_t size, const char *filename) * - jirka */ if (debugfs__configured() || tracefs__configured()) { - snprintf(buf, size, - "Error:\tFile %s/%s not found.\n" - "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", - tracing_events_path, filename); + /* sdt markers */ + if (!strncmp(filename, "sdt_", 4)) { + snprintf(buf, size, + "Error:\tFile %s/%s not found.\n" + "Hint:\tSDT event cannot be directly recorded on.\n" + "\tPlease first use 'perf probe %s:%s' before recording it.\n", + tracing_events_path, filename, sys, name); + } else { + snprintf(buf, size, + "Error:\tFile %s/%s not found.\n" + "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", + tracing_events_path, filename); + } break; } snprintf(buf, size, "%s", @@ -125,12 +138,3 @@ static int strerror_open(int err, char *buf, size_t size, const char *filename) return 0; } - -int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name) -{ - char path[PATH_MAX]; - - snprintf(path, PATH_MAX, "%s/%s", sys, name ?: "*"); - - return strerror_open(err, buf, size, path); -} ^ permalink raw reply related [flat|nested] 77+ messages in thread
* [PATCH 2/5] perf/sdt/x86: Add renaming logic for rNN and other registers 2017-02-02 11:11 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Ravi Bangoria 2017-02-02 11:11 ` [PATCH 1/5] perf/sdt: Show proper hint Ravi Bangoria @ 2017-02-02 11:11 ` Ravi Bangoria 2017-02-07 3:11 ` Masami Hiramatsu 2017-03-24 18:45 ` [tip:perf/core] perf sdt x86: " tip-bot for Ravi Bangoria 2017-02-02 11:11 ` [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ Ravi Bangoria ` (3 subsequent siblings) 5 siblings, 2 replies; 77+ messages in thread From: Ravi Bangoria @ 2017-02-02 11:11 UTC (permalink / raw) To: acme, alexis.berlemont, linux-kernel Cc: peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy, Ravi Bangoria 'perf probe' is failing for sdt markers whose arguments has rNN (with postfix b/w/d), %rsp, %esp, %sil etc. registers. Add renaming logic for these registers. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> --- tools/perf/arch/x86/util/perf_regs.c | 44 ++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index 09a7f55..d8a8dcf 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -48,10 +48,42 @@ static const struct sdt_name_reg sdt_reg_renamings[] = { SDT_NAME_REG(rdx, dx), SDT_NAME_REG(esi, si), SDT_NAME_REG(rsi, si), + SDT_NAME_REG(sil, si), SDT_NAME_REG(edi, di), SDT_NAME_REG(rdi, di), + SDT_NAME_REG(dil, di), SDT_NAME_REG(ebp, bp), SDT_NAME_REG(rbp, bp), + SDT_NAME_REG(bpl, bp), + SDT_NAME_REG(rsp, sp), + SDT_NAME_REG(esp, sp), + SDT_NAME_REG(spl, sp), + + /* rNN registers */ + SDT_NAME_REG(r8b, r8), + SDT_NAME_REG(r8w, r8), + SDT_NAME_REG(r8d, r8), + SDT_NAME_REG(r9b, r9), + SDT_NAME_REG(r9w, r9), + SDT_NAME_REG(r9d, r9), + SDT_NAME_REG(r10b, r10), + SDT_NAME_REG(r10w, r10), + SDT_NAME_REG(r10d, r10), + SDT_NAME_REG(r11b, r11), + SDT_NAME_REG(r11w, r11), + SDT_NAME_REG(r11d, r11), + SDT_NAME_REG(r12b, r12), + SDT_NAME_REG(r12w, r12), + SDT_NAME_REG(r12d, r12), + SDT_NAME_REG(r13b, r13), + SDT_NAME_REG(r13w, r13), + SDT_NAME_REG(r13d, r13), + SDT_NAME_REG(r14b, r14), + SDT_NAME_REG(r14w, r14), + SDT_NAME_REG(r14d, r14), + SDT_NAME_REG(r15b, r15), + SDT_NAME_REG(r15w, r15), + SDT_NAME_REG(r15d, r15), SDT_NAME_REG_END, }; @@ -88,18 +120,6 @@ int sdt_rename_register(char **pdesc, char *old_name) /* Copy the chars after the register name (if need be) */ offset = prefix_len + sdt_len; - if (offset < old_desc_len) { - /* - * The orginal register name can be suffixed by 'b', - * 'w' or 'd' to indicate its size; so, we need to - * skip this char if we met one. - */ - char sfx = old_desc[offset]; - - if (sfx == 'b' || sfx == 'w' || sfx == 'd') - offset++; - } - if (offset < old_desc_len) memcpy(new_desc + prefix_len + uprobe_len, old_desc + offset, old_desc_len - offset); -- 2.9.3 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH 2/5] perf/sdt/x86: Add renaming logic for rNN and other registers 2017-02-02 11:11 ` [PATCH 2/5] perf/sdt/x86: Add renaming logic for rNN and other registers Ravi Bangoria @ 2017-02-07 3:11 ` Masami Hiramatsu 2017-03-21 14:08 ` Arnaldo Carvalho de Melo 2017-03-24 18:45 ` [tip:perf/core] perf sdt x86: " tip-bot for Ravi Bangoria 1 sibling, 1 reply; 77+ messages in thread From: Masami Hiramatsu @ 2017-02-07 3:11 UTC (permalink / raw) To: Ravi Bangoria Cc: acme, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy On Thu, 2 Feb 2017 16:41:40 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > 'perf probe' is failing for sdt markers whose arguments has rNN > (with postfix b/w/d), %rsp, %esp, %sil etc. registers. Add renaming > logic for these registers. > Looks good to me. Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Thanks! > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> > --- > tools/perf/arch/x86/util/perf_regs.c | 44 ++++++++++++++++++++++++++---------- > 1 file changed, 32 insertions(+), 12 deletions(-) > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > index 09a7f55..d8a8dcf 100644 > --- a/tools/perf/arch/x86/util/perf_regs.c > +++ b/tools/perf/arch/x86/util/perf_regs.c > @@ -48,10 +48,42 @@ static const struct sdt_name_reg sdt_reg_renamings[] = { > SDT_NAME_REG(rdx, dx), > SDT_NAME_REG(esi, si), > SDT_NAME_REG(rsi, si), > + SDT_NAME_REG(sil, si), > SDT_NAME_REG(edi, di), > SDT_NAME_REG(rdi, di), > + SDT_NAME_REG(dil, di), > SDT_NAME_REG(ebp, bp), > SDT_NAME_REG(rbp, bp), > + SDT_NAME_REG(bpl, bp), > + SDT_NAME_REG(rsp, sp), > + SDT_NAME_REG(esp, sp), > + SDT_NAME_REG(spl, sp), > + > + /* rNN registers */ > + SDT_NAME_REG(r8b, r8), > + SDT_NAME_REG(r8w, r8), > + SDT_NAME_REG(r8d, r8), > + SDT_NAME_REG(r9b, r9), > + SDT_NAME_REG(r9w, r9), > + SDT_NAME_REG(r9d, r9), > + SDT_NAME_REG(r10b, r10), > + SDT_NAME_REG(r10w, r10), > + SDT_NAME_REG(r10d, r10), > + SDT_NAME_REG(r11b, r11), > + SDT_NAME_REG(r11w, r11), > + SDT_NAME_REG(r11d, r11), > + SDT_NAME_REG(r12b, r12), > + SDT_NAME_REG(r12w, r12), > + SDT_NAME_REG(r12d, r12), > + SDT_NAME_REG(r13b, r13), > + SDT_NAME_REG(r13w, r13), > + SDT_NAME_REG(r13d, r13), > + SDT_NAME_REG(r14b, r14), > + SDT_NAME_REG(r14w, r14), > + SDT_NAME_REG(r14d, r14), > + SDT_NAME_REG(r15b, r15), > + SDT_NAME_REG(r15w, r15), > + SDT_NAME_REG(r15d, r15), > SDT_NAME_REG_END, > }; > > @@ -88,18 +120,6 @@ int sdt_rename_register(char **pdesc, char *old_name) > > /* Copy the chars after the register name (if need be) */ > offset = prefix_len + sdt_len; > - if (offset < old_desc_len) { > - /* > - * The orginal register name can be suffixed by 'b', > - * 'w' or 'd' to indicate its size; so, we need to > - * skip this char if we met one. > - */ > - char sfx = old_desc[offset]; > - > - if (sfx == 'b' || sfx == 'w' || sfx == 'd') > - offset++; > - } > - > if (offset < old_desc_len) > memcpy(new_desc + prefix_len + uprobe_len, > old_desc + offset, old_desc_len - offset); > -- > 2.9.3 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH 2/5] perf/sdt/x86: Add renaming logic for rNN and other registers 2017-02-07 3:11 ` Masami Hiramatsu @ 2017-03-21 14:08 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-03-21 14:08 UTC (permalink / raw) To: Masami Hiramatsu Cc: Ravi Bangoria, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy Em Tue, Feb 07, 2017 at 12:11:59PM +0900, Masami Hiramatsu escreveu: > On Thu, 2 Feb 2017 16:41:40 +0530 > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > 'perf probe' is failing for sdt markers whose arguments has rNN > > (with postfix b/w/d), %rsp, %esp, %sil etc. registers. Add renaming > > logic for these registers. > > > > Looks good to me. > > Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Thanks, applied right after that v5 series from Alexis. > Thanks! > > > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> > > --- > > tools/perf/arch/x86/util/perf_regs.c | 44 ++++++++++++++++++++++++++---------- > > 1 file changed, 32 insertions(+), 12 deletions(-) > > > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > > index 09a7f55..d8a8dcf 100644 > > --- a/tools/perf/arch/x86/util/perf_regs.c > > +++ b/tools/perf/arch/x86/util/perf_regs.c > > @@ -48,10 +48,42 @@ static const struct sdt_name_reg sdt_reg_renamings[] = { > > SDT_NAME_REG(rdx, dx), > > SDT_NAME_REG(esi, si), > > SDT_NAME_REG(rsi, si), > > + SDT_NAME_REG(sil, si), > > SDT_NAME_REG(edi, di), > > SDT_NAME_REG(rdi, di), > > + SDT_NAME_REG(dil, di), > > SDT_NAME_REG(ebp, bp), > > SDT_NAME_REG(rbp, bp), > > + SDT_NAME_REG(bpl, bp), > > + SDT_NAME_REG(rsp, sp), > > + SDT_NAME_REG(esp, sp), > > + SDT_NAME_REG(spl, sp), > > + > > + /* rNN registers */ > > + SDT_NAME_REG(r8b, r8), > > + SDT_NAME_REG(r8w, r8), > > + SDT_NAME_REG(r8d, r8), > > + SDT_NAME_REG(r9b, r9), > > + SDT_NAME_REG(r9w, r9), > > + SDT_NAME_REG(r9d, r9), > > + SDT_NAME_REG(r10b, r10), > > + SDT_NAME_REG(r10w, r10), > > + SDT_NAME_REG(r10d, r10), > > + SDT_NAME_REG(r11b, r11), > > + SDT_NAME_REG(r11w, r11), > > + SDT_NAME_REG(r11d, r11), > > + SDT_NAME_REG(r12b, r12), > > + SDT_NAME_REG(r12w, r12), > > + SDT_NAME_REG(r12d, r12), > > + SDT_NAME_REG(r13b, r13), > > + SDT_NAME_REG(r13w, r13), > > + SDT_NAME_REG(r13d, r13), > > + SDT_NAME_REG(r14b, r14), > > + SDT_NAME_REG(r14w, r14), > > + SDT_NAME_REG(r14d, r14), > > + SDT_NAME_REG(r15b, r15), > > + SDT_NAME_REG(r15w, r15), > > + SDT_NAME_REG(r15d, r15), > > SDT_NAME_REG_END, > > }; > > > > @@ -88,18 +120,6 @@ int sdt_rename_register(char **pdesc, char *old_name) > > > > /* Copy the chars after the register name (if need be) */ > > offset = prefix_len + sdt_len; > > - if (offset < old_desc_len) { > > - /* > > - * The orginal register name can be suffixed by 'b', > > - * 'w' or 'd' to indicate its size; so, we need to > > - * skip this char if we met one. > > - */ > > - char sfx = old_desc[offset]; > > - > > - if (sfx == 'b' || sfx == 'w' || sfx == 'd') > > - offset++; > > - } > > - > > if (offset < old_desc_len) > > memcpy(new_desc + prefix_len + uprobe_len, > > old_desc + offset, old_desc_len - offset); > > -- > > 2.9.3 > > > > > -- > Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [tip:perf/core] perf sdt x86: Add renaming logic for rNN and other registers 2017-02-02 11:11 ` [PATCH 2/5] perf/sdt/x86: Add renaming logic for rNN and other registers Ravi Bangoria 2017-02-07 3:11 ` Masami Hiramatsu @ 2017-03-24 18:45 ` tip-bot for Ravi Bangoria 1 sibling, 0 replies; 77+ messages in thread From: tip-bot for Ravi Bangoria @ 2017-03-24 18:45 UTC (permalink / raw) To: linux-tip-commits Cc: alexis.berlemont, peterz, mpe, alexander.shishkin, acme, linux-kernel, hpa, mingo, tglx, maddy, naveen.n.rao, ravi.bangoria, mhiramat Commit-ID: 8544d24c3204f94c0ba9788d3113b7a83d5edc0d Gitweb: http://git.kernel.org/tip/8544d24c3204f94c0ba9788d3113b7a83d5edc0d Author: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> AuthorDate: Thu, 2 Feb 2017 16:41:40 +0530 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Tue, 21 Mar 2017 11:07:17 -0300 perf sdt x86: Add renaming logic for rNN and other registers 'perf probe' is failing for sdt markers whose arguments has rNN (with postfix b/w/d), %rsp, %esp, %sil etc. registers. Add renaming logic for these registers. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexis Berlemont <alexis.berlemont@gmail.com> Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20170202111143.14319-3-ravi.bangoria@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/arch/x86/util/perf_regs.c | 44 ++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index 09a7f55..d8a8dcf 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -48,10 +48,42 @@ static const struct sdt_name_reg sdt_reg_renamings[] = { SDT_NAME_REG(rdx, dx), SDT_NAME_REG(esi, si), SDT_NAME_REG(rsi, si), + SDT_NAME_REG(sil, si), SDT_NAME_REG(edi, di), SDT_NAME_REG(rdi, di), + SDT_NAME_REG(dil, di), SDT_NAME_REG(ebp, bp), SDT_NAME_REG(rbp, bp), + SDT_NAME_REG(bpl, bp), + SDT_NAME_REG(rsp, sp), + SDT_NAME_REG(esp, sp), + SDT_NAME_REG(spl, sp), + + /* rNN registers */ + SDT_NAME_REG(r8b, r8), + SDT_NAME_REG(r8w, r8), + SDT_NAME_REG(r8d, r8), + SDT_NAME_REG(r9b, r9), + SDT_NAME_REG(r9w, r9), + SDT_NAME_REG(r9d, r9), + SDT_NAME_REG(r10b, r10), + SDT_NAME_REG(r10w, r10), + SDT_NAME_REG(r10d, r10), + SDT_NAME_REG(r11b, r11), + SDT_NAME_REG(r11w, r11), + SDT_NAME_REG(r11d, r11), + SDT_NAME_REG(r12b, r12), + SDT_NAME_REG(r12w, r12), + SDT_NAME_REG(r12d, r12), + SDT_NAME_REG(r13b, r13), + SDT_NAME_REG(r13w, r13), + SDT_NAME_REG(r13d, r13), + SDT_NAME_REG(r14b, r14), + SDT_NAME_REG(r14w, r14), + SDT_NAME_REG(r14d, r14), + SDT_NAME_REG(r15b, r15), + SDT_NAME_REG(r15w, r15), + SDT_NAME_REG(r15d, r15), SDT_NAME_REG_END, }; @@ -88,18 +120,6 @@ int sdt_rename_register(char **pdesc, char *old_name) /* Copy the chars after the register name (if need be) */ offset = prefix_len + sdt_len; - if (offset < old_desc_len) { - /* - * The orginal register name can be suffixed by 'b', - * 'w' or 'd' to indicate its size; so, we need to - * skip this char if we met one. - */ - char sfx = old_desc[offset]; - - if (sfx == 'b' || sfx == 'w' || sfx == 'd') - offset++; - } - if (offset < old_desc_len) memcpy(new_desc + prefix_len + uprobe_len, old_desc + offset, old_desc_len - offset); ^ permalink raw reply related [flat|nested] 77+ messages in thread
* [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ 2017-02-02 11:11 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Ravi Bangoria 2017-02-02 11:11 ` [PATCH 1/5] perf/sdt: Show proper hint Ravi Bangoria 2017-02-02 11:11 ` [PATCH 2/5] perf/sdt/x86: Add renaming logic for rNN and other registers Ravi Bangoria @ 2017-02-02 11:11 ` Ravi Bangoria 2017-02-07 3:11 ` Masami Hiramatsu 2017-03-21 14:55 ` Masami Hiramatsu 2017-02-02 11:11 ` [PATCH 4/5] perf/sdt/powerpc: Add argument support Ravi Bangoria ` (2 subsequent siblings) 5 siblings, 2 replies; 77+ messages in thread From: Ravi Bangoria @ 2017-02-02 11:11 UTC (permalink / raw) To: acme, alexis.berlemont, linux-kernel Cc: peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy, Ravi Bangoria SDT marker argument is in N@OP format. N is the size of argument and OP is the actual assembly operand. OP is arch dependent component and hence it's parsing logic also should be placed under tools/perf/arch/. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> --- tools/perf/arch/x86/util/perf_regs.c | 93 ++++++++++++++++++++++++- tools/perf/util/perf_regs.c | 9 ++- tools/perf/util/perf_regs.h | 7 +- tools/perf/util/probe-file.c | 127 +++++++++-------------------------- 4 files changed, 134 insertions(+), 102 deletions(-) diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index d8a8dcf..34fcb0d 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -3,6 +3,7 @@ #include "../../perf.h" #include "../../util/util.h" #include "../../util/perf_regs.h" +#include "../../util/debug.h" const struct sample_reg sample_reg_masks[] = { SMPL_REG(AX, PERF_REG_X86_AX), @@ -87,7 +88,16 @@ static const struct sdt_name_reg sdt_reg_renamings[] = { SDT_NAME_REG_END, }; -int sdt_rename_register(char **pdesc, char *old_name) +bool arch_sdt_probe_arg_supp(void) +{ + return true; +} + +/* + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated + * registers before filling the uprobe tracer interface. + */ +static int sdt_rename_register(char **pdesc, char *old_name) { const struct sdt_name_reg *rnames = sdt_reg_renamings; char *new_desc, *old_desc = *pdesc; @@ -129,3 +139,84 @@ int sdt_rename_register(char **pdesc, char *old_name) return 0; } + +/* + * x86 specific implementation + * return value: + * <0 : error + * 0 : success + * >0 : skip + */ +int arch_sdt_probe_parse_op(char **desc, const char **prefix) +{ + char *tmp; + int ret = 0; + + /* + * The uprobe tracer format does not support all the addressing + * modes (notably: in x86 the scaled mode); so, we detect ',' + * characters, if there is just one, there is no use converting + * the sdt arg into a uprobe one. + * + * Also it does not support constants; if we find one in the + * current argument, let's skip the argument. + */ + if (strchr(*desc, ',') || strchr(*desc, '$')) { + pr_debug4("Skipping unsupported SDT argument; %s\n", *desc); + return 1; + } + + /* + * If the argument addressing mode is indirect, we must check + * a few things... + */ + tmp = strchr(*desc, '('); + if (tmp) { + int j; + + /* + * ...if the addressing mode is indirect with a + * positive offset (ex.: "1608(%ax)"), we need to add + * a '+' prefix so as to be compliant with uprobe + * format. + */ + if ((*desc)[0] != '+' && (*desc)[0] != '-') + *prefix = ((*desc)[0] == '(') ? "+0" : "+"; + + /* + * ...or if the addressing mode is indirect with a symbol + * as offset, the argument will not be supported by + * the uprobe tracer format; so, let's skip this one. + */ + for (j = 0; j < tmp - *desc; j++) { + if ((*desc)[j] != '+' && (*desc)[j] != '-' && + !isdigit((*desc)[j])) { + pr_debug4("Skipping unsupported SDT argument; " + "%s\n", *desc); + return 1; + } + } + } + + /* + * The uprobe parser does not support all gas register names; + * so, we have to replace them (ex. for x86_64: %rax -> %ax); + * the loop below looks for the register names (starting with + * a '%' and tries to perform the needed renamings. + */ + tmp = strchr(*desc, '%'); + while (tmp) { + size_t offset = tmp - *desc; + + ret = sdt_rename_register(desc, *desc + offset); + if (ret < 0) + return ret; + + /* + * The *desc pointer might have changed; so, let's not + * try to reuse tmp for next lookup + */ + tmp = strchr(*desc + offset + 1, '%'); + } + return 0; +} diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index a37e593..f2b3d0d 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -6,8 +6,13 @@ const struct sample_reg __weak sample_reg_masks[] = { SMPL_REG_END }; -int __weak sdt_rename_register(char **pdesc __maybe_unused, - char *old_name __maybe_unused) +bool __weak arch_sdt_probe_arg_supp(void) +{ + return false; +} + +int __weak arch_sdt_probe_parse_op(char **op_ptr __maybe_unused, + const char **prefix __maybe_unused) { return 0; } diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 7544a15..86a2961 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -15,11 +15,8 @@ struct sample_reg { extern const struct sample_reg sample_reg_masks[]; -/* - * The table sdt_reg_renamings is used for adjusting gcc/gas-generated - * registers before filling the uprobe tracer interface. - */ -int sdt_rename_register(char **pdesc, char *old_name); +bool arch_sdt_probe_arg_supp(void); +int arch_sdt_probe_parse_op(char **op_ptr, const char **prefix); #ifdef HAVE_PERF_REGS_SUPPORT #include <perf_regs.h> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index d8a169e..38eca3c 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -693,6 +693,25 @@ static const char * const type_to_suffix[] = { "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" }; +/* + * Isolate the string number and convert it into a decimal value; + * this will be an index to get suffix of the uprobe name (defining + * the type) + */ +static int sdt_probe_parse_n(char *n_ptr, const char **suffix) +{ + long type_idx; + + type_idx = strtol(n_ptr, NULL, 10); + if (type_idx < -8 || type_idx > 8) { + pr_debug4("Failed to get a valid sdt type\n"); + return -1; + } + + *suffix = type_to_suffix[type_idx + 8]; + return 0; +} + static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) { char *tmp, *desc = strdup(arg); @@ -704,109 +723,29 @@ static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) return ret; } + /* + * Argument is in N@OP format. N is size of the argument and OP is + * the actual assembly operand. N can be omitted; in that case + * argument is just OP(without @). + */ tmp = strchr(desc, '@'); if (tmp) { - long type_idx; - /* - * Isolate the string number and convert it into a - * binary value; this will be an index to get suffix - * of the uprobe name (defining the type) - */ tmp[0] = '\0'; - type_idx = strtol(desc, NULL, 10); - /* Check that the conversion went OK */ - if (type_idx == LONG_MIN || type_idx == LONG_MAX) { - pr_debug4("Failed to parse sdt type\n"); - goto error; - } - /* Check that the converted value is OK */ - if (type_idx < -8 || type_idx > 8) { - pr_debug4("Failed to get a valid sdt type\n"); - goto error; - } - suffix = type_to_suffix[type_idx + 8]; - /* Get rid of the sdt prefix which is now useless */ tmp++; - memmove(desc, tmp, strlen(tmp) + 1); - } - /* - * The uprobe tracer format does not support all the - * addressing modes (notably: in x86 the scaled mode); so, we - * detect ',' characters, if there is just one, there is no - * use converting the sdt arg into a uprobe one. - */ - if (strchr(desc, ',')) { - pr_debug4("Skipping unsupported SDT argument; %s\n", desc); - goto out; - } - - /* - * If the argument addressing mode is indirect, we must check - * a few things... - */ - tmp = strchr(desc, '('); - if (tmp) { - int j; - - /* - * ...if the addressing mode is indirect with a - * positive offset (ex.: "1608(%ax)"), we need to add - * a '+' prefix so as to be compliant with uprobe - * format. - */ - if (desc[0] != '+' && desc[0] != '-') - prefix = "+"; - - /* - * ...or if the addressing mode is indirect with a symbol - * as offset, the argument will not be supported by - * the uprobe tracer format; so, let's skip this one. - */ - for (j = 0; j < tmp - desc; j++) { - if (desc[j] != '+' && desc[j] != '-' && - !isdigit(desc[j])) { - pr_debug4("Skipping unsupported SDT argument; " - "%s\n", desc); - goto out; - } - } - } - - /* - * The uprobe tracer format does not support constants; if we - * find one in the current argument, let's skip the argument. - */ - if (strchr(desc, '$')) { - pr_debug4("Skipping unsupported SDT argument; %s\n", desc); - goto out; - } - - /* - * The uprobe parser does not support all gas register names; - * so, we have to replace them (ex. for x86_64: %rax -> %ax); - * the loop below looks for the register names (starting with - * a '%' and tries to perform the needed renamings. - */ - tmp = strchr(desc, '%'); - while (tmp) { - size_t offset = tmp - desc; - - ret = sdt_rename_register(&desc, desc + offset); - if (ret < 0) + if (sdt_probe_parse_n(desc, &suffix)) goto error; - - /* - * The desc pointer might have changed; so, let's not - * try to reuse tmp for next lookup - */ - tmp = strchr(desc + offset + 1, '%'); + memmove(desc, tmp, strlen(tmp) + 1); } - if (strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) + ret = arch_sdt_probe_parse_op(&desc, &prefix); + if (ret < 0) + goto error; + + if (ret == 0 && + strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) goto error; -out: ret = 0; error: free(desc); @@ -829,7 +768,7 @@ static char *synthesize_sdt_probe_command(struct sdt_note *note, sdt_note__get_addr(note)) < 0) goto error; - if (!note->args) + if (!note->args || !arch_sdt_probe_arg_supp()) goto out; if (note->args) { -- 2.9.3 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ 2017-02-02 11:11 ` [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ Ravi Bangoria @ 2017-02-07 3:11 ` Masami Hiramatsu 2017-02-07 5:22 ` Ravi Bangoria 2017-03-21 14:55 ` Masami Hiramatsu 1 sibling, 1 reply; 77+ messages in thread From: Masami Hiramatsu @ 2017-02-07 3:11 UTC (permalink / raw) To: Ravi Bangoria Cc: acme, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy On Thu, 2 Feb 2017 16:41:41 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > SDT marker argument is in N@OP format. N is the size of argument and > OP is the actual assembly operand. OP is arch dependent component and > hence it's parsing logic also should be placed under tools/perf/arch/. > Ok, I have one question. Is there any possibility that N is different size of OP? e.g. 8@dil, in this case we will record whole rdi. is that OK? Thanks, > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> > --- > tools/perf/arch/x86/util/perf_regs.c | 93 ++++++++++++++++++++++++- > tools/perf/util/perf_regs.c | 9 ++- > tools/perf/util/perf_regs.h | 7 +- > tools/perf/util/probe-file.c | 127 +++++++++-------------------------- > 4 files changed, 134 insertions(+), 102 deletions(-) > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > index d8a8dcf..34fcb0d 100644 > --- a/tools/perf/arch/x86/util/perf_regs.c > +++ b/tools/perf/arch/x86/util/perf_regs.c > @@ -3,6 +3,7 @@ > #include "../../perf.h" > #include "../../util/util.h" > #include "../../util/perf_regs.h" > +#include "../../util/debug.h" > > const struct sample_reg sample_reg_masks[] = { > SMPL_REG(AX, PERF_REG_X86_AX), > @@ -87,7 +88,16 @@ static const struct sdt_name_reg sdt_reg_renamings[] = { > SDT_NAME_REG_END, > }; > > -int sdt_rename_register(char **pdesc, char *old_name) > +bool arch_sdt_probe_arg_supp(void) > +{ > + return true; > +} > + > +/* > + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > + * registers before filling the uprobe tracer interface. > + */ > +static int sdt_rename_register(char **pdesc, char *old_name) > { > const struct sdt_name_reg *rnames = sdt_reg_renamings; > char *new_desc, *old_desc = *pdesc; > @@ -129,3 +139,84 @@ int sdt_rename_register(char **pdesc, char *old_name) > > return 0; > } > + > +/* > + * x86 specific implementation > + * return value: > + * <0 : error > + * 0 : success > + * >0 : skip > + */ > +int arch_sdt_probe_parse_op(char **desc, const char **prefix) > +{ > + char *tmp; > + int ret = 0; > + > + /* > + * The uprobe tracer format does not support all the addressing > + * modes (notably: in x86 the scaled mode); so, we detect ',' > + * characters, if there is just one, there is no use converting > + * the sdt arg into a uprobe one. > + * > + * Also it does not support constants; if we find one in the > + * current argument, let's skip the argument. > + */ > + if (strchr(*desc, ',') || strchr(*desc, '$')) { > + pr_debug4("Skipping unsupported SDT argument; %s\n", *desc); > + return 1; > + } > + > + /* > + * If the argument addressing mode is indirect, we must check > + * a few things... > + */ > + tmp = strchr(*desc, '('); > + if (tmp) { > + int j; > + > + /* > + * ...if the addressing mode is indirect with a > + * positive offset (ex.: "1608(%ax)"), we need to add > + * a '+' prefix so as to be compliant with uprobe > + * format. > + */ > + if ((*desc)[0] != '+' && (*desc)[0] != '-') > + *prefix = ((*desc)[0] == '(') ? "+0" : "+"; > + > + /* > + * ...or if the addressing mode is indirect with a symbol > + * as offset, the argument will not be supported by > + * the uprobe tracer format; so, let's skip this one. > + */ > + for (j = 0; j < tmp - *desc; j++) { > + if ((*desc)[j] != '+' && (*desc)[j] != '-' && > + !isdigit((*desc)[j])) { > + pr_debug4("Skipping unsupported SDT argument; " > + "%s\n", *desc); > + return 1; > + } > + } > + } > + > + /* > + * The uprobe parser does not support all gas register names; > + * so, we have to replace them (ex. for x86_64: %rax -> %ax); > + * the loop below looks for the register names (starting with > + * a '%' and tries to perform the needed renamings. > + */ > + tmp = strchr(*desc, '%'); > + while (tmp) { > + size_t offset = tmp - *desc; > + > + ret = sdt_rename_register(desc, *desc + offset); > + if (ret < 0) > + return ret; > + > + /* > + * The *desc pointer might have changed; so, let's not > + * try to reuse tmp for next lookup > + */ > + tmp = strchr(*desc + offset + 1, '%'); > + } > + return 0; > +} > diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c > index a37e593..f2b3d0d 100644 > --- a/tools/perf/util/perf_regs.c > +++ b/tools/perf/util/perf_regs.c > @@ -6,8 +6,13 @@ const struct sample_reg __weak sample_reg_masks[] = { > SMPL_REG_END > }; > > -int __weak sdt_rename_register(char **pdesc __maybe_unused, > - char *old_name __maybe_unused) > +bool __weak arch_sdt_probe_arg_supp(void) > +{ > + return false; > +} > + > +int __weak arch_sdt_probe_parse_op(char **op_ptr __maybe_unused, > + const char **prefix __maybe_unused) > { > return 0; > } > diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h > index 7544a15..86a2961 100644 > --- a/tools/perf/util/perf_regs.h > +++ b/tools/perf/util/perf_regs.h > @@ -15,11 +15,8 @@ struct sample_reg { > > extern const struct sample_reg sample_reg_masks[]; > > -/* > - * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > - * registers before filling the uprobe tracer interface. > - */ > -int sdt_rename_register(char **pdesc, char *old_name); > +bool arch_sdt_probe_arg_supp(void); > +int arch_sdt_probe_parse_op(char **op_ptr, const char **prefix); > > #ifdef HAVE_PERF_REGS_SUPPORT > #include <perf_regs.h> > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index d8a169e..38eca3c 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -693,6 +693,25 @@ static const char * const type_to_suffix[] = { > "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" > }; > > +/* > + * Isolate the string number and convert it into a decimal value; > + * this will be an index to get suffix of the uprobe name (defining > + * the type) > + */ > +static int sdt_probe_parse_n(char *n_ptr, const char **suffix) > +{ > + long type_idx; > + > + type_idx = strtol(n_ptr, NULL, 10); > + if (type_idx < -8 || type_idx > 8) { > + pr_debug4("Failed to get a valid sdt type\n"); > + return -1; > + } > + > + *suffix = type_to_suffix[type_idx + 8]; > + return 0; > +} > + > static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > { > char *tmp, *desc = strdup(arg); > @@ -704,109 +723,29 @@ static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > return ret; > } > > + /* > + * Argument is in N@OP format. N is size of the argument and OP is > + * the actual assembly operand. N can be omitted; in that case > + * argument is just OP(without @). > + */ > tmp = strchr(desc, '@'); > if (tmp) { > - long type_idx; > - /* > - * Isolate the string number and convert it into a > - * binary value; this will be an index to get suffix > - * of the uprobe name (defining the type) > - */ > tmp[0] = '\0'; > - type_idx = strtol(desc, NULL, 10); > - /* Check that the conversion went OK */ > - if (type_idx == LONG_MIN || type_idx == LONG_MAX) { > - pr_debug4("Failed to parse sdt type\n"); > - goto error; > - } > - /* Check that the converted value is OK */ > - if (type_idx < -8 || type_idx > 8) { > - pr_debug4("Failed to get a valid sdt type\n"); > - goto error; > - } > - suffix = type_to_suffix[type_idx + 8]; > - /* Get rid of the sdt prefix which is now useless */ > tmp++; > - memmove(desc, tmp, strlen(tmp) + 1); > - } > > - /* > - * The uprobe tracer format does not support all the > - * addressing modes (notably: in x86 the scaled mode); so, we > - * detect ',' characters, if there is just one, there is no > - * use converting the sdt arg into a uprobe one. > - */ > - if (strchr(desc, ',')) { > - pr_debug4("Skipping unsupported SDT argument; %s\n", desc); > - goto out; > - } > - > - /* > - * If the argument addressing mode is indirect, we must check > - * a few things... > - */ > - tmp = strchr(desc, '('); > - if (tmp) { > - int j; > - > - /* > - * ...if the addressing mode is indirect with a > - * positive offset (ex.: "1608(%ax)"), we need to add > - * a '+' prefix so as to be compliant with uprobe > - * format. > - */ > - if (desc[0] != '+' && desc[0] != '-') > - prefix = "+"; > - > - /* > - * ...or if the addressing mode is indirect with a symbol > - * as offset, the argument will not be supported by > - * the uprobe tracer format; so, let's skip this one. > - */ > - for (j = 0; j < tmp - desc; j++) { > - if (desc[j] != '+' && desc[j] != '-' && > - !isdigit(desc[j])) { > - pr_debug4("Skipping unsupported SDT argument; " > - "%s\n", desc); > - goto out; > - } > - } > - } > - > - /* > - * The uprobe tracer format does not support constants; if we > - * find one in the current argument, let's skip the argument. > - */ > - if (strchr(desc, '$')) { > - pr_debug4("Skipping unsupported SDT argument; %s\n", desc); > - goto out; > - } > - > - /* > - * The uprobe parser does not support all gas register names; > - * so, we have to replace them (ex. for x86_64: %rax -> %ax); > - * the loop below looks for the register names (starting with > - * a '%' and tries to perform the needed renamings. > - */ > - tmp = strchr(desc, '%'); > - while (tmp) { > - size_t offset = tmp - desc; > - > - ret = sdt_rename_register(&desc, desc + offset); > - if (ret < 0) > + if (sdt_probe_parse_n(desc, &suffix)) > goto error; > - > - /* > - * The desc pointer might have changed; so, let's not > - * try to reuse tmp for next lookup > - */ > - tmp = strchr(desc + offset + 1, '%'); > + memmove(desc, tmp, strlen(tmp) + 1); > } > > - if (strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) > + ret = arch_sdt_probe_parse_op(&desc, &prefix); > + if (ret < 0) > + goto error; > + > + if (ret == 0 && > + strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) > goto error; > > -out: > ret = 0; > error: > free(desc); > @@ -829,7 +768,7 @@ static char *synthesize_sdt_probe_command(struct sdt_note *note, > sdt_note__get_addr(note)) < 0) > goto error; > > - if (!note->args) > + if (!note->args || !arch_sdt_probe_arg_supp()) > goto out; > > if (note->args) { > -- > 2.9.3 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ 2017-02-07 3:11 ` Masami Hiramatsu @ 2017-02-07 5:22 ` Ravi Bangoria 2017-03-21 14:10 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-02-07 5:22 UTC (permalink / raw) To: Masami Hiramatsu Cc: acme, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy, Ravi Bangoria Thanks Masami for the review. On Tuesday 07 February 2017 08:41 AM, Masami Hiramatsu wrote: > On Thu, 2 Feb 2017 16:41:41 +0530 > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > >> SDT marker argument is in N@OP format. N is the size of argument and >> OP is the actual assembly operand. OP is arch dependent component and >> hence it's parsing logic also should be placed under tools/perf/arch/. >> > Ok, I have one question. Is there any possibility that N is different > size of OP? e.g. 8@dil, in this case we will record whole rdi. > is that OK? By looking at list of markers on my x86 Fedora25 box, yes, it's possible for case when register size used in OP is more than size specified by N. For example, -4@68(%rbx). But I don't see any argument which specifies higher size in N compared to size of register in OP, like you mentioned in your example. Ravi ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ 2017-02-07 5:22 ` Ravi Bangoria @ 2017-03-21 14:10 ` Arnaldo Carvalho de Melo 2017-03-21 23:00 ` Masami Hiramatsu 0 siblings, 1 reply; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-03-21 14:10 UTC (permalink / raw) To: Ravi Bangoria Cc: Masami Hiramatsu, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy Em Tue, Feb 07, 2017 at 10:52:17AM +0530, Ravi Bangoria escreveu: > Thanks Masami for the review. > > On Tuesday 07 February 2017 08:41 AM, Masami Hiramatsu wrote: > > On Thu, 2 Feb 2017 16:41:41 +0530 > > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > >> SDT marker argument is in N@OP format. N is the size of argument and > >> OP is the actual assembly operand. OP is arch dependent component and > >> hence it's parsing logic also should be placed under tools/perf/arch/. > >> > > Ok, I have one question. Is there any possibility that N is different > > size of OP? e.g. 8@dil, in this case we will record whole rdi. > > is that OK? > > By looking at list of markers on my x86 Fedora25 box, yes, it's possible > for case when register size used in OP is more than size specified by N. > For example, -4@68(%rbx). But I don't see any argument which specifies > higher size in N compared to size of register in OP, like you mentioned > in your example. Masami, can I have your Acked-by for 3-5/5 in this series? - Arnaldo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ 2017-03-21 14:10 ` Arnaldo Carvalho de Melo @ 2017-03-21 23:00 ` Masami Hiramatsu 2017-03-22 11:22 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 77+ messages in thread From: Masami Hiramatsu @ 2017-03-21 23:00 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Ravi Bangoria, Masami Hiramatsu, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy On Tue, 21 Mar 2017 11:10:49 -0300 Arnaldo Carvalho de Melo <acme@redhat.com> wrote: > Em Tue, Feb 07, 2017 at 10:52:17AM +0530, Ravi Bangoria escreveu: > > Thanks Masami for the review. > > > > On Tuesday 07 February 2017 08:41 AM, Masami Hiramatsu wrote: > > > On Thu, 2 Feb 2017 16:41:41 +0530 > > > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > > > >> SDT marker argument is in N@OP format. N is the size of argument and > > >> OP is the actual assembly operand. OP is arch dependent component and > > >> hence it's parsing logic also should be placed under tools/perf/arch/. > > >> > > > Ok, I have one question. Is there any possibility that N is different > > > size of OP? e.g. 8@dil, in this case we will record whole rdi. > > > is that OK? > > > > By looking at list of markers on my x86 Fedora25 box, yes, it's possible > > for case when register size used in OP is more than size specified by N. > > For example, -4@68(%rbx). But I don't see any argument which specifies > > higher size in N compared to size of register in OP, like you mentioned > > in your example. > > Masami, can I have your Acked-by for 3-5/5 in this series? Arnaldo, as I reviewed, this patch still have some discussion points. Others are good to me. Thanks! -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ 2017-03-21 23:00 ` Masami Hiramatsu @ 2017-03-22 11:22 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-03-22 11:22 UTC (permalink / raw) To: Masami Hiramatsu Cc: Ravi Bangoria, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy Em Wed, Mar 22, 2017 at 08:00:18AM +0900, Masami Hiramatsu escreveu: > On Tue, 21 Mar 2017 11:10:49 -0300 > Arnaldo Carvalho de Melo <acme@redhat.com> wrote: > > > Em Tue, Feb 07, 2017 at 10:52:17AM +0530, Ravi Bangoria escreveu: > > > Thanks Masami for the review. > > > > > > On Tuesday 07 February 2017 08:41 AM, Masami Hiramatsu wrote: > > > > On Thu, 2 Feb 2017 16:41:41 +0530 > > > > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > > > > > >> SDT marker argument is in N@OP format. N is the size of argument and > > > >> OP is the actual assembly operand. OP is arch dependent component and > > > >> hence it's parsing logic also should be placed under tools/perf/arch/. > > > >> > > > > Ok, I have one question. Is there any possibility that N is different > > > > size of OP? e.g. 8@dil, in this case we will record whole rdi. > > > > is that OK? > > > > > > By looking at list of markers on my x86 Fedora25 box, yes, it's possible > > > for case when register size used in OP is more than size specified by N. > > > For example, -4@68(%rbx). But I don't see any argument which specifies > > > higher size in N compared to size of register in OP, like you mentioned > > > in your example. > > > > Masami, can I have your Acked-by for 3-5/5 in this series? > > Arnaldo, as I reviewed, this patch still have some discussion points. > Others are good to me. That is ok, waiting for the next steps then. Thanks for the update, - Arnaldo ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ 2017-02-02 11:11 ` [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ Ravi Bangoria 2017-02-07 3:11 ` Masami Hiramatsu @ 2017-03-21 14:55 ` Masami Hiramatsu 1 sibling, 0 replies; 77+ messages in thread From: Masami Hiramatsu @ 2017-03-21 14:55 UTC (permalink / raw) To: Ravi Bangoria Cc: acme, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy On Thu, 2 Feb 2017 16:41:41 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > SDT marker argument is in N@OP format. N is the size of argument and > OP is the actual assembly operand. OP is arch dependent component and > hence it's parsing logic also should be placed under tools/perf/arch/. > > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> > --- > tools/perf/arch/x86/util/perf_regs.c | 93 ++++++++++++++++++++++++- > tools/perf/util/perf_regs.c | 9 ++- > tools/perf/util/perf_regs.h | 7 +- > tools/perf/util/probe-file.c | 127 +++++++++-------------------------- > 4 files changed, 134 insertions(+), 102 deletions(-) > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > index d8a8dcf..34fcb0d 100644 > --- a/tools/perf/arch/x86/util/perf_regs.c > +++ b/tools/perf/arch/x86/util/perf_regs.c > @@ -3,6 +3,7 @@ > #include "../../perf.h" > #include "../../util/util.h" > #include "../../util/perf_regs.h" > +#include "../../util/debug.h" > > const struct sample_reg sample_reg_masks[] = { > SMPL_REG(AX, PERF_REG_X86_AX), > @@ -87,7 +88,16 @@ static const struct sdt_name_reg sdt_reg_renamings[] = { > SDT_NAME_REG_END, > }; > > -int sdt_rename_register(char **pdesc, char *old_name) > +bool arch_sdt_probe_arg_supp(void) > +{ > + return true; > +} > + > +/* > + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > + * registers before filling the uprobe tracer interface. > + */ > +static int sdt_rename_register(char **pdesc, char *old_name) > { > const struct sdt_name_reg *rnames = sdt_reg_renamings; > char *new_desc, *old_desc = *pdesc; > @@ -129,3 +139,84 @@ int sdt_rename_register(char **pdesc, char *old_name) > > return 0; > } > + > +/* > + * x86 specific implementation > + * return value: > + * <0 : error > + * 0 : success > + * >0 : skip > + */ > +int arch_sdt_probe_parse_op(char **desc, const char **prefix) Frankly to say, I prefer to see the function interface which has clearly separated in/out arguments. This function, "desc" is used for both of input and output. Could you refactor this to separate args? for example, int arch_sdt_probe_parse_op(const char *desc, struct strbuf *buf) I think prefix also integrated with output buffer. > +{ > + char *tmp; > + int ret = 0; > + > + /* > + * The uprobe tracer format does not support all the addressing > + * modes (notably: in x86 the scaled mode); so, we detect ',' > + * characters, if there is just one, there is no use converting > + * the sdt arg into a uprobe one. > + * > + * Also it does not support constants; if we find one in the > + * current argument, let's skip the argument. > + */ > + if (strchr(*desc, ',') || strchr(*desc, '$')) { > + pr_debug4("Skipping unsupported SDT argument; %s\n", *desc); > + return 1; > + } > + > + /* > + * If the argument addressing mode is indirect, we must check > + * a few things... > + */ > + tmp = strchr(*desc, '('); > + if (tmp) { > + int j; > + > + /* > + * ...if the addressing mode is indirect with a > + * positive offset (ex.: "1608(%ax)"), we need to add > + * a '+' prefix so as to be compliant with uprobe > + * format. > + */ > + if ((*desc)[0] != '+' && (*desc)[0] != '-') > + *prefix = ((*desc)[0] == '(') ? "+0" : "+"; > + > + /* > + * ...or if the addressing mode is indirect with a symbol > + * as offset, the argument will not be supported by > + * the uprobe tracer format; so, let's skip this one. > + */ > + for (j = 0; j < tmp - *desc; j++) { > + if ((*desc)[j] != '+' && (*desc)[j] != '-' && > + !isdigit((*desc)[j])) { > + pr_debug4("Skipping unsupported SDT argument; " > + "%s\n", *desc); > + return 1; > + } > + } > + } > + > + /* > + * The uprobe parser does not support all gas register names; > + * so, we have to replace them (ex. for x86_64: %rax -> %ax); > + * the loop below looks for the register names (starting with > + * a '%' and tries to perform the needed renamings. > + */ > + tmp = strchr(*desc, '%'); > + while (tmp) { > + size_t offset = tmp - *desc; > + > + ret = sdt_rename_register(desc, *desc + offset); > + if (ret < 0) > + return ret; > + > + /* > + * The *desc pointer might have changed; so, let's not > + * try to reuse tmp for next lookup > + */ > + tmp = strchr(*desc + offset + 1, '%'); > + } > + return 0; > +} > diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c > index a37e593..f2b3d0d 100644 > --- a/tools/perf/util/perf_regs.c > +++ b/tools/perf/util/perf_regs.c > @@ -6,8 +6,13 @@ const struct sample_reg __weak sample_reg_masks[] = { > SMPL_REG_END > }; > > -int __weak sdt_rename_register(char **pdesc __maybe_unused, > - char *old_name __maybe_unused) > +bool __weak arch_sdt_probe_arg_supp(void) > +{ > + return false; > +} > + > +int __weak arch_sdt_probe_parse_op(char **op_ptr __maybe_unused, > + const char **prefix __maybe_unused) > { > return 0; > } Hmm, why we we need both of these functions? I think you just need to return 1 from arch_sdt_probe_parse_op(), then all the arguments are skipped. > diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h > index 7544a15..86a2961 100644 > --- a/tools/perf/util/perf_regs.h > +++ b/tools/perf/util/perf_regs.h > @@ -15,11 +15,8 @@ struct sample_reg { > > extern const struct sample_reg sample_reg_masks[]; > > -/* > - * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > - * registers before filling the uprobe tracer interface. > - */ > -int sdt_rename_register(char **pdesc, char *old_name); > +bool arch_sdt_probe_arg_supp(void); > +int arch_sdt_probe_parse_op(char **op_ptr, const char **prefix); > > #ifdef HAVE_PERF_REGS_SUPPORT > #include <perf_regs.h> > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index d8a169e..38eca3c 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -693,6 +693,25 @@ static const char * const type_to_suffix[] = { > "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" > }; > > +/* > + * Isolate the string number and convert it into a decimal value; > + * this will be an index to get suffix of the uprobe name (defining > + * the type) > + */ > +static int sdt_probe_parse_n(char *n_ptr, const char **suffix) please make it more meaningful name, sdt_probe_parse_size() etc. Thank you, > +{ > + long type_idx; > + > + type_idx = strtol(n_ptr, NULL, 10); > + if (type_idx < -8 || type_idx > 8) { > + pr_debug4("Failed to get a valid sdt type\n"); > + return -1; > + } > + > + *suffix = type_to_suffix[type_idx + 8]; > + return 0; > +} > + > static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > { > char *tmp, *desc = strdup(arg); > @@ -704,109 +723,29 @@ static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > return ret; > } > > + /* > + * Argument is in N@OP format. N is size of the argument and OP is > + * the actual assembly operand. N can be omitted; in that case > + * argument is just OP(without @). > + */ > tmp = strchr(desc, '@'); > if (tmp) { > - long type_idx; > - /* > - * Isolate the string number and convert it into a > - * binary value; this will be an index to get suffix > - * of the uprobe name (defining the type) > - */ > tmp[0] = '\0'; > - type_idx = strtol(desc, NULL, 10); > - /* Check that the conversion went OK */ > - if (type_idx == LONG_MIN || type_idx == LONG_MAX) { > - pr_debug4("Failed to parse sdt type\n"); > - goto error; > - } > - /* Check that the converted value is OK */ > - if (type_idx < -8 || type_idx > 8) { > - pr_debug4("Failed to get a valid sdt type\n"); > - goto error; > - } > - suffix = type_to_suffix[type_idx + 8]; > - /* Get rid of the sdt prefix which is now useless */ > tmp++; > - memmove(desc, tmp, strlen(tmp) + 1); > - } > > - /* > - * The uprobe tracer format does not support all the > - * addressing modes (notably: in x86 the scaled mode); so, we > - * detect ',' characters, if there is just one, there is no > - * use converting the sdt arg into a uprobe one. > - */ > - if (strchr(desc, ',')) { > - pr_debug4("Skipping unsupported SDT argument; %s\n", desc); > - goto out; > - } > - > - /* > - * If the argument addressing mode is indirect, we must check > - * a few things... > - */ > - tmp = strchr(desc, '('); > - if (tmp) { > - int j; > - > - /* > - * ...if the addressing mode is indirect with a > - * positive offset (ex.: "1608(%ax)"), we need to add > - * a '+' prefix so as to be compliant with uprobe > - * format. > - */ > - if (desc[0] != '+' && desc[0] != '-') > - prefix = "+"; > - > - /* > - * ...or if the addressing mode is indirect with a symbol > - * as offset, the argument will not be supported by > - * the uprobe tracer format; so, let's skip this one. > - */ > - for (j = 0; j < tmp - desc; j++) { > - if (desc[j] != '+' && desc[j] != '-' && > - !isdigit(desc[j])) { > - pr_debug4("Skipping unsupported SDT argument; " > - "%s\n", desc); > - goto out; > - } > - } > - } > - > - /* > - * The uprobe tracer format does not support constants; if we > - * find one in the current argument, let's skip the argument. > - */ > - if (strchr(desc, '$')) { > - pr_debug4("Skipping unsupported SDT argument; %s\n", desc); > - goto out; > - } > - > - /* > - * The uprobe parser does not support all gas register names; > - * so, we have to replace them (ex. for x86_64: %rax -> %ax); > - * the loop below looks for the register names (starting with > - * a '%' and tries to perform the needed renamings. > - */ > - tmp = strchr(desc, '%'); > - while (tmp) { > - size_t offset = tmp - desc; > - > - ret = sdt_rename_register(&desc, desc + offset); > - if (ret < 0) > + if (sdt_probe_parse_n(desc, &suffix)) > goto error; > - > - /* > - * The desc pointer might have changed; so, let's not > - * try to reuse tmp for next lookup > - */ > - tmp = strchr(desc + offset + 1, '%'); > + memmove(desc, tmp, strlen(tmp) + 1); > } > > - if (strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) > + ret = arch_sdt_probe_parse_op(&desc, &prefix); > + if (ret < 0) > + goto error; > + > + if (ret == 0 && > + strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) > goto error; > > -out: > ret = 0; > error: > free(desc); > @@ -829,7 +768,7 @@ static char *synthesize_sdt_probe_command(struct sdt_note *note, > sdt_note__get_addr(note)) < 0) > goto error; > > - if (!note->args) > + if (!note->args || !arch_sdt_probe_arg_supp()) > goto out; > > if (note->args) { > -- > 2.9.3 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH 4/5] perf/sdt/powerpc: Add argument support 2017-02-02 11:11 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Ravi Bangoria ` (2 preceding siblings ...) 2017-02-02 11:11 ` [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ Ravi Bangoria @ 2017-02-02 11:11 ` Ravi Bangoria 2017-02-02 11:11 ` [PATCH 5/5] perf/probe: Change MAX_CMDLEN Ravi Bangoria 2017-02-07 2:55 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Masami Hiramatsu 5 siblings, 0 replies; 77+ messages in thread From: Ravi Bangoria @ 2017-02-02 11:11 UTC (permalink / raw) To: acme, alexis.berlemont, linux-kernel Cc: peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy, Ravi Bangoria SDT marker argument is in N@OP format. Here OP is arch dependent component. Add powerpc logic to parse OP and convert it to uprobe compatible format. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> --- tools/perf/arch/powerpc/util/perf_regs.c | 115 +++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c index a3c3e1c..bbd6f91 100644 --- a/tools/perf/arch/powerpc/util/perf_regs.c +++ b/tools/perf/arch/powerpc/util/perf_regs.c @@ -1,5 +1,10 @@ +#include <string.h> +#include <regex.h> + #include "../../perf.h" +#include "../../util/util.h" #include "../../util/perf_regs.h" +#include "../../util/debug.h" const struct sample_reg sample_reg_masks[] = { SMPL_REG(r0, PERF_REG_POWERPC_R0), @@ -47,3 +52,113 @@ const struct sample_reg sample_reg_masks[] = { SMPL_REG(dsisr, PERF_REG_POWERPC_DSISR), SMPL_REG_END }; + +bool arch_sdt_probe_arg_supp(void) +{ + return true; +} + +static regex_t regex1, regex2; + +static int init_op_regex(void) +{ + static int initialized; + + if (initialized) + return 0; + + /* REG or %rREG */ + if (regcomp(®ex1, "^(%r)?([1-2]?[0-9]|3[0-1])$", REG_EXTENDED)) + goto error; + + /* -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) */ + if (regcomp(®ex2, "^(\\-)?([0-9]+)\\((%r)?([1-2]?[0-9]|3[0-1])\\)$", + REG_EXTENDED)) + goto free_regex1; + + initialized = 1; + return 0; + +free_regex1: + regfree(®ex1); +error: + pr_debug4("Regex compilation error.\n"); + return -1; +} + +/* + * Parse OP and convert it into uprobe format, which is, +/-NUM(%gprREG). + * Possible variants of OP are: + * Format Example + * ------------------------- + * NUM(REG) 48(18) + * -NUM(REG) -48(18) + * NUM(%rREG) 48(%r18) + * -NUM(%rREG) -48(%r18) + * REG 18 + * %rREG %r18 + * iNUM i0 + * i-NUM i-1 + * + * SDT marker arguments on Powerpc uses %rREG form with -mregnames flag + * and REG form with -mno-regnames. Here REG is general purpose register, + * which is in 0 to 31 range. + * + * return value of the function: + * <0 : error + * 0 : success + * >0 : skip + */ +int arch_sdt_probe_parse_op(char **desc, const char **prefix) +{ + char *tmp = NULL; + size_t new_len; + regmatch_t rm[5]; + + /* Constant argument. Uprobe does not support it */ + if (*desc[0] == 'i') { + pr_debug4("Skipping unsupported SDT argument: %s\n", *desc); + return 1; + } + + if (init_op_regex() < 0) + return -1; + + if (!regexec(®ex1, *desc, 3, rm, 0)) { + /* REG or %rREG --> %gprREG */ + new_len = 5; + new_len += (int)(rm[2].rm_eo - rm[2].rm_so); + + tmp = zalloc(new_len); + if (!tmp) + return -1; + + scnprintf(tmp, new_len, "%%gpr%.*s", + (int)(rm[2].rm_eo - rm[2].rm_so), *desc + rm[2].rm_so); + } else if (!regexec(®ex2, *desc, 5, rm, 0)) { + /* + * -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) --> + * +/-NUM(%gprREG) + */ + *prefix = (rm[1].rm_so == -1) ? "+" : "-"; + + new_len = 7; + new_len += (int)(rm[2].rm_eo - rm[2].rm_so); + new_len += (int)(rm[4].rm_eo - rm[4].rm_so); + + tmp = zalloc(new_len); + if (!tmp) + return -1; + + scnprintf(tmp, new_len, "%.*s(%%gpr%.*s)", + (int)(rm[2].rm_eo - rm[2].rm_so), *desc + rm[2].rm_so, + (int)(rm[4].rm_eo - rm[4].rm_so), *desc + rm[4].rm_so); + } else { + pr_debug4("Skipping unsupported SDT argument: %s\n", *desc); + return 1; + } + + free(*desc); + *desc = tmp; + return 0; +} -- 2.9.3 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* [PATCH 5/5] perf/probe: Change MAX_CMDLEN 2017-02-02 11:11 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Ravi Bangoria ` (3 preceding siblings ...) 2017-02-02 11:11 ` [PATCH 4/5] perf/sdt/powerpc: Add argument support Ravi Bangoria @ 2017-02-02 11:11 ` Ravi Bangoria 2017-02-07 1:40 ` Masami Hiramatsu 2017-02-07 2:55 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Masami Hiramatsu 5 siblings, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-02-02 11:11 UTC (permalink / raw) To: acme, alexis.berlemont, linux-kernel Cc: peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy, Ravi Bangoria There are many SDT markers in powerpc whose uprobe definition goes beyond current MAX_CMDLEN, especially when target filename is long and sdt marker has long list of arguments. For example, definition of sdt marker method__compile__end: 8@17 8@9 8@10 -4@8 8@7 -4@6 8@5 -4@4 1@37(28) from file /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-2.b14.fc22.ppc64/jre/lib/\ ppc64/server/libjvm.so is p:sdt_hotspot/method__compile__end /usr/lib/jvm/java-1.8.0-openjdk-\ 1.8.0.91-2.b14.fc22.ppc64/jre/lib/ppc64/server/libjvm.so:0x4c4e00\ arg1=%gpr17:u64 arg2=%gpr9:u64 arg3=%gpr10:u64 arg4=%gpr8:s32\ arg5=%gpr7:u64 arg6=%gpr6:s32 arg7=%gpr5:u64 arg8=%gpr4:s32\ arg9=+37(%gpr28):u8 Perf probe fails with seg fault for such markers. As uprobe_events file accepts definition beyond 256 characters, increase value of MAX_CMDLEN to 512. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> --- tools/perf/util/probe-event.c | 1 - tools/perf/util/probe-file.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 2c1bca2..5f3256f 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -47,7 +47,6 @@ #include "probe-file.h" #include "session.h" -#define MAX_CMDLEN 256 #define PERFPROBE_GROUP "probe" bool probe_event_dry_run; /* Dry run flag */ diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 38eca3c..1580e26 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -29,7 +29,7 @@ #include "session.h" #include "perf_regs.h" -#define MAX_CMDLEN 256 +#define MAX_CMDLEN 512 static void print_open_warning(int err, bool uprobe) { -- 2.9.3 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH 5/5] perf/probe: Change MAX_CMDLEN 2017-02-02 11:11 ` [PATCH 5/5] perf/probe: Change MAX_CMDLEN Ravi Bangoria @ 2017-02-07 1:40 ` Masami Hiramatsu 2017-02-07 5:45 ` [PATCH v2] " Ravi Bangoria 0 siblings, 1 reply; 77+ messages in thread From: Masami Hiramatsu @ 2017-02-07 1:40 UTC (permalink / raw) To: Ravi Bangoria Cc: acme, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy On Thu, 2 Feb 2017 16:41:43 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > There are many SDT markers in powerpc whose uprobe definition goes > beyond current MAX_CMDLEN, especially when target filename is long > and sdt marker has long list of arguments. For example, definition > of sdt marker > > method__compile__end: 8@17 8@9 8@10 -4@8 8@7 -4@6 8@5 -4@4 1@37(28) > > from file > > /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-2.b14.fc22.ppc64/jre/lib/\ > ppc64/server/libjvm.so > > is > > p:sdt_hotspot/method__compile__end /usr/lib/jvm/java-1.8.0-openjdk-\ > 1.8.0.91-2.b14.fc22.ppc64/jre/lib/ppc64/server/libjvm.so:0x4c4e00\ > arg1=%gpr17:u64 arg2=%gpr9:u64 arg3=%gpr10:u64 arg4=%gpr8:s32\ > arg5=%gpr7:u64 arg6=%gpr6:s32 arg7=%gpr5:u64 arg8=%gpr4:s32\ > arg9=+37(%gpr28):u8 > > Perf probe fails with seg fault for such markers. As uprobe_events file > accepts definition beyond 256 characters, increase value of MAX_CMDLEN > to 512. OK, actually in the kernel side, it accepts up to 4094 (+"\n\0") so it is a good time to expand it to 4094. (I found another buggy message in kernel... will be fixed soon) Thank you, > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> > --- > tools/perf/util/probe-event.c | 1 - > tools/perf/util/probe-file.c | 2 +- > 2 files changed, 1 insertion(+), 2 deletions(-) > > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c > index 2c1bca2..5f3256f 100644 > --- a/tools/perf/util/probe-event.c > +++ b/tools/perf/util/probe-event.c > @@ -47,7 +47,6 @@ > #include "probe-file.h" > #include "session.h" > > -#define MAX_CMDLEN 256 > #define PERFPROBE_GROUP "probe" > > bool probe_event_dry_run; /* Dry run flag */ > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index 38eca3c..1580e26 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -29,7 +29,7 @@ > #include "session.h" > #include "perf_regs.h" > > -#define MAX_CMDLEN 256 > +#define MAX_CMDLEN 512 > > static void print_open_warning(int err, bool uprobe) > { > -- > 2.9.3 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v2] perf/probe: Change MAX_CMDLEN 2017-02-07 1:40 ` Masami Hiramatsu @ 2017-02-07 5:45 ` Ravi Bangoria 2017-03-21 5:19 ` Masami Hiramatsu 2017-03-24 18:43 ` [tip:perf/core] perf probe: " tip-bot for Ravi Bangoria 0 siblings, 2 replies; 77+ messages in thread From: Ravi Bangoria @ 2017-02-07 5:45 UTC (permalink / raw) To: acme, linux-kernel, mhiramat Cc: alexis.berlemont, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy, Ravi Bangoria There are many SDT markers in powerpc whose uprobe definition goes beyond current MAX_CMDLEN, especially when target filename is long and sdt marker has long list of arguments. For example, definition of sdt marker method__compile__end: 8@17 8@9 8@10 -4@8 8@7 -4@6 8@5 -4@4 1@37(28) from file /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-2.b14.fc22.ppc64/jre/lib/\ ppc64/server/libjvm.so is p:sdt_hotspot/method__compile__end /usr/lib/jvm/java-1.8.0-openjdk-\ 1.8.0.91-2.b14.fc22.ppc64/jre/lib/ppc64/server/libjvm.so:0x4c4e00\ arg1=%gpr17:u64 arg2=%gpr9:u64 arg3=%gpr10:u64 arg4=%gpr8:s32\ arg5=%gpr7:u64 arg6=%gpr6:s32 arg7=%gpr5:u64 arg8=%gpr4:s32\ arg9=+37(%gpr28):u8 Perf probe fails with seg fault for such markers. As uprobe_events file accepts definition upto 4094 characters(4096 - 2 (\n\0)), increase value of MAX_CMDLEN to 4094. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> --- Changes in v2: - Set MAX_CMDLEN to 4094 instead of 512 tools/perf/util/probe-event.c | 1 - tools/perf/util/probe-file.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 6a6f44d..e6e3244 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -47,7 +47,6 @@ #include "probe-file.h" #include "session.h" -#define MAX_CMDLEN 256 #define PERFPROBE_GROUP "probe" bool probe_event_dry_run; /* Dry run flag */ diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 38eca3c..fdabe7e 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -29,7 +29,8 @@ #include "session.h" #include "perf_regs.h" -#define MAX_CMDLEN 256 +/* 4096 - 2 ('\n' + '\0') */ +#define MAX_CMDLEN 4094 static void print_open_warning(int err, bool uprobe) { -- 2.9.3 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH v2] perf/probe: Change MAX_CMDLEN 2017-02-07 5:45 ` [PATCH v2] " Ravi Bangoria @ 2017-03-21 5:19 ` Masami Hiramatsu 2017-03-21 13:37 ` Arnaldo Carvalho de Melo 2017-03-24 18:43 ` [tip:perf/core] perf probe: " tip-bot for Ravi Bangoria 1 sibling, 1 reply; 77+ messages in thread From: Masami Hiramatsu @ 2017-03-21 5:19 UTC (permalink / raw) To: Ravi Bangoria Cc: acme, linux-kernel, alexis.berlemont, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy On Tue, 7 Feb 2017 11:15:47 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > There are many SDT markers in powerpc whose uprobe definition goes > beyond current MAX_CMDLEN, especially when target filename is long > and sdt marker has long list of arguments. For example, definition > of sdt marker > > method__compile__end: 8@17 8@9 8@10 -4@8 8@7 -4@6 8@5 -4@4 1@37(28) > > from file > > /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-2.b14.fc22.ppc64/jre/lib/\ > ppc64/server/libjvm.so > > is > > p:sdt_hotspot/method__compile__end /usr/lib/jvm/java-1.8.0-openjdk-\ > 1.8.0.91-2.b14.fc22.ppc64/jre/lib/ppc64/server/libjvm.so:0x4c4e00\ > arg1=%gpr17:u64 arg2=%gpr9:u64 arg3=%gpr10:u64 arg4=%gpr8:s32\ > arg5=%gpr7:u64 arg6=%gpr6:s32 arg7=%gpr5:u64 arg8=%gpr4:s32\ > arg9=+37(%gpr28):u8 > > Perf probe fails with seg fault for such markers. As uprobe_events file > accepts definition upto 4094 characters(4096 - 2 (\n\0)), increase value > of MAX_CMDLEN to 4094. This looks good to me. Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Thanks, > > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> > --- > Changes in v2: > - Set MAX_CMDLEN to 4094 instead of 512 > > tools/perf/util/probe-event.c | 1 - > tools/perf/util/probe-file.c | 3 ++- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c > index 6a6f44d..e6e3244 100644 > --- a/tools/perf/util/probe-event.c > +++ b/tools/perf/util/probe-event.c > @@ -47,7 +47,6 @@ > #include "probe-file.h" > #include "session.h" > > -#define MAX_CMDLEN 256 > #define PERFPROBE_GROUP "probe" > > bool probe_event_dry_run; /* Dry run flag */ > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index 38eca3c..fdabe7e 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -29,7 +29,8 @@ > #include "session.h" > #include "perf_regs.h" > > -#define MAX_CMDLEN 256 > +/* 4096 - 2 ('\n' + '\0') */ > +#define MAX_CMDLEN 4094 > > static void print_open_warning(int err, bool uprobe) > { > -- > 2.9.3 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v2] perf/probe: Change MAX_CMDLEN 2017-03-21 5:19 ` Masami Hiramatsu @ 2017-03-21 13:37 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-03-21 13:37 UTC (permalink / raw) To: Masami Hiramatsu Cc: Ravi Bangoria, linux-kernel, alexis.berlemont, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy Em Tue, Mar 21, 2017 at 02:19:50PM +0900, Masami Hiramatsu escreveu: > On Tue, 7 Feb 2017 11:15:47 +0530 > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > There are many SDT markers in powerpc whose uprobe definition goes > > beyond current MAX_CMDLEN, especially when target filename is long > > and sdt marker has long list of arguments. For example, definition > > of sdt marker > > > > method__compile__end: 8@17 8@9 8@10 -4@8 8@7 -4@6 8@5 -4@4 1@37(28) > > > > from file > > > > /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-2.b14.fc22.ppc64/jre/lib/\ > > ppc64/server/libjvm.so > > > > is > > > > p:sdt_hotspot/method__compile__end /usr/lib/jvm/java-1.8.0-openjdk-\ > > 1.8.0.91-2.b14.fc22.ppc64/jre/lib/ppc64/server/libjvm.so:0x4c4e00\ > > arg1=%gpr17:u64 arg2=%gpr9:u64 arg3=%gpr10:u64 arg4=%gpr8:s32\ > > arg5=%gpr7:u64 arg6=%gpr6:s32 arg7=%gpr5:u64 arg8=%gpr4:s32\ > > arg9=+37(%gpr28):u8 > > > > Perf probe fails with seg fault for such markers. As uprobe_events file > > accepts definition upto 4094 characters(4096 - 2 (\n\0)), increase value > > of MAX_CMDLEN to 4094. > > This looks good to me. > > Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Thanks, applied manually, as the code patched drifted some lines away from the ones here. - Arnaldo > Thanks, > > > > > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> > > --- > > Changes in v2: > > - Set MAX_CMDLEN to 4094 instead of 512 > > > > tools/perf/util/probe-event.c | 1 - > > tools/perf/util/probe-file.c | 3 ++- > > 2 files changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c > > index 6a6f44d..e6e3244 100644 > > --- a/tools/perf/util/probe-event.c > > +++ b/tools/perf/util/probe-event.c > > @@ -47,7 +47,6 @@ > > #include "probe-file.h" > > #include "session.h" > > > > -#define MAX_CMDLEN 256 > > #define PERFPROBE_GROUP "probe" > > > > bool probe_event_dry_run; /* Dry run flag */ > > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > > index 38eca3c..fdabe7e 100644 > > --- a/tools/perf/util/probe-file.c > > +++ b/tools/perf/util/probe-file.c > > @@ -29,7 +29,8 @@ > > #include "session.h" > > #include "perf_regs.h" > > > > -#define MAX_CMDLEN 256 > > +/* 4096 - 2 ('\n' + '\0') */ > > +#define MAX_CMDLEN 4094 > > > > static void print_open_warning(int err, bool uprobe) > > { > > -- > > 2.9.3 > > > > > -- > Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [tip:perf/core] perf probe: Change MAX_CMDLEN 2017-02-07 5:45 ` [PATCH v2] " Ravi Bangoria 2017-03-21 5:19 ` Masami Hiramatsu @ 2017-03-24 18:43 ` tip-bot for Ravi Bangoria 1 sibling, 0 replies; 77+ messages in thread From: tip-bot for Ravi Bangoria @ 2017-03-24 18:43 UTC (permalink / raw) To: linux-tip-commits Cc: naveen.n.rao, hpa, acme, mpe, maddy, mhiramat, alexis.berlemont, ravi.bangoria, peterz, tglx, linux-kernel, mingo, alexander.shishkin Commit-ID: 2e1f8f7895731a8592d483a7364a23855843af17 Gitweb: http://git.kernel.org/tip/2e1f8f7895731a8592d483a7364a23855843af17 Author: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> AuthorDate: Tue, 7 Feb 2017 11:15:47 +0530 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Tue, 21 Mar 2017 10:34:59 -0300 perf probe: Change MAX_CMDLEN There are many SDT markers in powerpc whose uprobe definition goes beyond current MAX_CMDLEN, especially when target filename is long and sdt marker has long list of arguments. For example, definition of sdt marker method__compile__end: 8@17 8@9 8@10 -4@8 8@7 -4@6 8@5 -4@4 1@37(28) from file /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-2.b14.fc22.ppc64/jre/lib/ppc64/server/libjvm.so is p:sdt_hotspot/method__compile__end /usr/lib/jvm/java-1.8.0-openjdk-\ 1.8.0.91-2.b14.fc22.ppc64/jre/lib/ppc64/server/libjvm.so:0x4c4e00\ arg1=%gpr17:u64 arg2=%gpr9:u64 arg3=%gpr10:u64 arg4=%gpr8:s32\ arg5=%gpr7:u64 arg6=%gpr6:s32 arg7=%gpr5:u64 arg8=%gpr4:s32\ arg9=+37(%gpr28):u8 'perf probe' fails with segfault for such markers. As the uprobe_events file accepts definitions up to 4094 characters(4096 - 2 (\n\0)), increase value of MAX_CMDLEN match that. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexis Berlemont <alexis.berlemont@gmail.com> Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20170207054547.3690-1-ravi.bangoria@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/probe-event.c | 1 - tools/perf/util/probe-file.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 6740d68..e4b8894 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -47,7 +47,6 @@ #include "probe-file.h" #include "session.h" -#define MAX_CMDLEN 256 #define PERFPROBE_GROUP "probe" bool probe_event_dry_run; /* Dry run flag */ diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 1542cd0..c3c2871 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -28,7 +28,8 @@ #include "probe-file.h" #include "session.h" -#define MAX_CMDLEN 256 +/* 4096 - 2 ('\n' + '\0') */ +#define MAX_CMDLEN 4094 static void print_open_warning(int err, bool uprobe) { ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH 0/5] perf/sdt: Argument support for x86 and powepc 2017-02-02 11:11 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Ravi Bangoria ` (4 preceding siblings ...) 2017-02-02 11:11 ` [PATCH 5/5] perf/probe: Change MAX_CMDLEN Ravi Bangoria @ 2017-02-07 2:55 ` Masami Hiramatsu 2017-03-06 7:53 ` Ravi Bangoria 5 siblings, 1 reply; 77+ messages in thread From: Masami Hiramatsu @ 2017-02-07 2:55 UTC (permalink / raw) To: Ravi Bangoria Cc: acme, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, mhiramat, maddy On Thu, 2 Feb 2017 16:41:38 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > The v5 patchset for sdt marker argument support for x86 [1] has > couple of issues. For example, it still has x86 specific code > in general code. It lacks support for rNN (with size postfix > b/w/d), %rsp, %esp, %sil etc. registers and such sdt markers > are failing at 'perf probe'. It also fails to convert arguments > having no offset but still surrounds register with parenthesis > for ex. 8@(%rdi) is converted to +(%di):u64 which is rejected > by uprobe_events. It's causing failure at 'perf probe' for all > SDT events on all archs except x86. With this patchset, I've > solved these issues. (patch 2,3) > > Also, existing perf shows misleading message when user tries to > record sdt event without probing it. I've prepared patch for > the same. (patch 1) > > Apart from that, I've also added logic to support arguments with > sdt marker on powerpc. (patch 4) > > There are cases where uprobe definition of sdt event goes beyond > current limit MAX_CMDLEN (256) and in such case perf fails with > seg fault. I've solve this issue. (patch 5) > > Note: This patchset is prepared on top of Alexis' v5 series.[1] > > [1] http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1292251.html Hmm, I must missed it. I'll check it... Thanks! > > Ravi Bangoria (5): > perf/sdt: Show proper hint > perf/sdt/x86: Add renaming logic for rNN and other registers > perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ > perf/sdt/powerpc: Add argument support > perf/probe: Change MAX_CMDLEN > > tools/lib/api/fs/tracing_path.c | 16 +++- > tools/perf/arch/powerpc/util/perf_regs.c | 115 ++++++++++++++++++++++++++ > tools/perf/arch/x86/util/perf_regs.c | 137 ++++++++++++++++++++++++++++--- > tools/perf/util/perf_regs.c | 9 +- > tools/perf/util/perf_regs.h | 7 +- > tools/perf/util/probe-event.c | 1 - > tools/perf/util/probe-file.c | 129 ++++++++--------------------- > 7 files changed, 294 insertions(+), 120 deletions(-) > > -- > 2.9.3 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH 0/5] perf/sdt: Argument support for x86 and powepc 2017-02-07 2:55 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Masami Hiramatsu @ 2017-03-06 7:53 ` Ravi Bangoria 2017-03-06 13:42 ` Masami Hiramatsu 0 siblings, 1 reply; 77+ messages in thread From: Ravi Bangoria @ 2017-03-06 7:53 UTC (permalink / raw) To: Masami Hiramatsu Cc: acme, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy, Ravi Bangoria On Tuesday 07 February 2017 08:25 AM, Masami Hiramatsu wrote: > On Thu, 2 Feb 2017 16:41:38 +0530 > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > >> The v5 patchset for sdt marker argument support for x86 [1] has >> couple of issues. For example, it still has x86 specific code >> in general code. It lacks support for rNN (with size postfix >> b/w/d), %rsp, %esp, %sil etc. registers and such sdt markers >> are failing at 'perf probe'. It also fails to convert arguments >> having no offset but still surrounds register with parenthesis >> for ex. 8@(%rdi) is converted to +(%di):u64 which is rejected >> by uprobe_events. It's causing failure at 'perf probe' for all >> SDT events on all archs except x86. With this patchset, I've >> solved these issues. (patch 2,3) >> >> Also, existing perf shows misleading message when user tries to >> record sdt event without probing it. I've prepared patch for >> the same. (patch 1) >> >> Apart from that, I've also added logic to support arguments with >> sdt marker on powerpc. (patch 4) >> >> There are cases where uprobe definition of sdt event goes beyond >> current limit MAX_CMDLEN (256) and in such case perf fails with >> seg fault. I've solve this issue. (patch 5) >> >> Note: This patchset is prepared on top of Alexis' v5 series.[1] >> >> [1] http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1292251.html > Hmm, I must missed it. I'll check it... > Hi Masami, Can you please review this. Thanks, -Ravi ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH 0/5] perf/sdt: Argument support for x86 and powepc 2017-03-06 7:53 ` Ravi Bangoria @ 2017-03-06 13:42 ` Masami Hiramatsu 0 siblings, 0 replies; 77+ messages in thread From: Masami Hiramatsu @ 2017-03-06 13:42 UTC (permalink / raw) To: Ravi Bangoria Cc: acme, alexis.berlemont, linux-kernel, peterz, mingo, alexander.shishkin, mpe, naveen.n.rao, maddy On Mon, 6 Mar 2017 13:23:30 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > On Tuesday 07 February 2017 08:25 AM, Masami Hiramatsu wrote: > > On Thu, 2 Feb 2017 16:41:38 +0530 > > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > >> The v5 patchset for sdt marker argument support for x86 [1] has > >> couple of issues. For example, it still has x86 specific code > >> in general code. It lacks support for rNN (with size postfix > >> b/w/d), %rsp, %esp, %sil etc. registers and such sdt markers > >> are failing at 'perf probe'. It also fails to convert arguments > >> having no offset but still surrounds register with parenthesis > >> for ex. 8@(%rdi) is converted to +(%di):u64 which is rejected > >> by uprobe_events. It's causing failure at 'perf probe' for all > >> SDT events on all archs except x86. With this patchset, I've > >> solved these issues. (patch 2,3) > >> > >> Also, existing perf shows misleading message when user tries to > >> record sdt event without probing it. I've prepared patch for > >> the same. (patch 1) > >> > >> Apart from that, I've also added logic to support arguments with > >> sdt marker on powerpc. (patch 4) > >> > >> There are cases where uprobe definition of sdt event goes beyond > >> current limit MAX_CMDLEN (256) and in such case perf fails with > >> seg fault. I've solve this issue. (patch 5) > >> > >> Note: This patchset is prepared on top of Alexis' v5 series.[1] > >> > >> [1] http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1292251.html > > Hmm, I must missed it. I'll check it... > > > > Hi Masami, > > Can you please review this. Thanks for kicking me :) -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-14 0:07 ` [PATCH v5 0/2] " Alexis Berlemont 2016-12-14 7:36 ` Ingo Molnar 2017-02-02 11:11 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Ravi Bangoria @ 2017-03-21 5:08 ` Masami Hiramatsu 2 siblings, 0 replies; 77+ messages in thread From: Masami Hiramatsu @ 2017-03-21 5:08 UTC (permalink / raw) To: Alexis Berlemont; +Cc: linux-kernel, peterz, mingo, acme, alexander.shishkin Hello Alexis and Arnaldo, I think this series is now good to go. Could you pick these? Acked-by: Masami Hiramatsu <mhiramat@kernel.org> for this series. Thank you, On Wed, 14 Dec 2016 01:07:30 +0100 Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > Hi Masami, > > Many thanks for your mail. > > Here is another patch set which tries to fix the points you mentioned: > > * Skip the arguments containing a constant ($123); > * Review the code in charge of the register renaming (search for '%' > and parse it); > * Minor changes (print the argument in case of error, skipping, check > the sdt arg type index); > > Many thanks, > > Alexis. > > Alexis Berlemont (2): > perf sdt: add scanning of sdt probles arguments > perf probe: add sdt probes arguments into the uprobe cmd string > > tools/perf/arch/x86/util/perf_regs.c | 83 +++++++++++++++++ > tools/perf/util/perf_regs.c | 6 ++ > tools/perf/util/perf_regs.h | 6 ++ > tools/perf/util/probe-file.c | 170 ++++++++++++++++++++++++++++++++++- > tools/perf/util/symbol-elf.c | 25 +++++- > tools/perf/util/symbol.h | 1 + > 6 files changed, 285 insertions(+), 6 deletions(-) > > -- > 2.10.2 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v5 1/2] perf sdt: add scanning of sdt probles arguments 2016-12-07 3:26 ` Masami Hiramatsu 2016-12-09 15:14 ` Arnaldo Carvalho de Melo 2016-12-14 0:07 ` [PATCH v5 0/2] " Alexis Berlemont @ 2016-12-14 0:07 ` Alexis Berlemont 2017-03-06 13:39 ` Masami Hiramatsu 2017-03-24 18:44 ` [tip:perf/core] perf sdt: Add scanning of sdt probes arguments tip-bot for Alexis Berlemont 2016-12-14 0:07 ` [PATCH v5 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 3 siblings, 2 replies; 77+ messages in thread From: Alexis Berlemont @ 2016-12-14 0:07 UTC (permalink / raw) To: linux-kernel; +Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin During a "perf buildid-cache --add" command, the section ".note.stapsdt" of the "added" binary is scanned in order to list the available SDT markers available in a binary. The parts containing the probes arguments were left unscanned. The whole section is now parsed; the probe arguments are extracted for later use. Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/util/symbol-elf.c | 25 +++++++++++++++++++++++-- tools/perf/util/symbol.h | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 99400b0..7725c3f 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1822,7 +1822,7 @@ void kcore_extract__delete(struct kcore_extract *kce) static int populate_sdt_note(Elf **elf, const char *data, size_t len, struct list_head *sdt_notes) { - const char *provider, *name; + const char *provider, *name, *args; struct sdt_note *tmp = NULL; GElf_Ehdr ehdr; GElf_Addr base_off = 0; @@ -1881,6 +1881,25 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, goto out_free_prov; } + args = memchr(name, '\0', data + len - name); + + /* + * There is no argument if: + * - We reached the end of the note; + * - There is not enough room to hold a potential string; + * - The argument string is empty or just contains ':'. + */ + if (args == NULL || data + len - args < 2 || + args[1] == ':' || args[1] == '\0') + tmp->args = NULL; + else { + tmp->args = strdup(++args); + if (!tmp->args) { + ret = -ENOMEM; + goto out_free_name; + } + } + if (gelf_getclass(*elf) == ELFCLASS32) { memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); tmp->bit32 = true; @@ -1892,7 +1911,7 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, if (!gelf_getehdr(*elf, &ehdr)) { pr_debug("%s : cannot get elf header.\n", __func__); ret = -EBADF; - goto out_free_name; + goto out_free_args; } /* Adjust the prelink effect : @@ -1917,6 +1936,8 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, list_add_tail(&tmp->note_list, sdt_notes); return 0; +out_free_args: + free(tmp->args); out_free_name: free(tmp->name); out_free_prov: diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 6c358b7..9222c7e 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -351,6 +351,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); struct sdt_note { char *name; /* name of the note*/ char *provider; /* provider name */ + char *args; bool bit32; /* whether the location is 32 bits? */ union { /* location, base and semaphore addrs */ Elf64_Addr a64[3]; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH v5 1/2] perf sdt: add scanning of sdt probles arguments 2016-12-14 0:07 ` [PATCH v5 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont @ 2017-03-06 13:39 ` Masami Hiramatsu 2017-03-21 13:52 ` Arnaldo Carvalho de Melo 2017-03-24 18:44 ` [tip:perf/core] perf sdt: Add scanning of sdt probes arguments tip-bot for Alexis Berlemont 1 sibling, 1 reply; 77+ messages in thread From: Masami Hiramatsu @ 2017-03-06 13:39 UTC (permalink / raw) To: Alexis Berlemont; +Cc: linux-kernel, peterz, mingo, acme, alexander.shishkin On Wed, 14 Dec 2016 01:07:31 +0100 Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > During a "perf buildid-cache --add" command, the section > ".note.stapsdt" of the "added" binary is scanned in order to list the > available SDT markers available in a binary. The parts containing the > probes arguments were left unscanned. > > The whole section is now parsed; the probe arguments are extracted for > later use. > Looks good to me. Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Thanks! > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > --- > tools/perf/util/symbol-elf.c | 25 +++++++++++++++++++++++-- > tools/perf/util/symbol.h | 1 + > 2 files changed, 24 insertions(+), 2 deletions(-) > > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c > index 99400b0..7725c3f 100644 > --- a/tools/perf/util/symbol-elf.c > +++ b/tools/perf/util/symbol-elf.c > @@ -1822,7 +1822,7 @@ void kcore_extract__delete(struct kcore_extract *kce) > static int populate_sdt_note(Elf **elf, const char *data, size_t len, > struct list_head *sdt_notes) > { > - const char *provider, *name; > + const char *provider, *name, *args; > struct sdt_note *tmp = NULL; > GElf_Ehdr ehdr; > GElf_Addr base_off = 0; > @@ -1881,6 +1881,25 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > goto out_free_prov; > } > > + args = memchr(name, '\0', data + len - name); > + > + /* > + * There is no argument if: > + * - We reached the end of the note; > + * - There is not enough room to hold a potential string; > + * - The argument string is empty or just contains ':'. > + */ > + if (args == NULL || data + len - args < 2 || > + args[1] == ':' || args[1] == '\0') > + tmp->args = NULL; > + else { > + tmp->args = strdup(++args); > + if (!tmp->args) { > + ret = -ENOMEM; > + goto out_free_name; > + } > + } > + > if (gelf_getclass(*elf) == ELFCLASS32) { > memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); > tmp->bit32 = true; > @@ -1892,7 +1911,7 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > if (!gelf_getehdr(*elf, &ehdr)) { > pr_debug("%s : cannot get elf header.\n", __func__); > ret = -EBADF; > - goto out_free_name; > + goto out_free_args; > } > > /* Adjust the prelink effect : > @@ -1917,6 +1936,8 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > list_add_tail(&tmp->note_list, sdt_notes); > return 0; > > +out_free_args: > + free(tmp->args); > out_free_name: > free(tmp->name); > out_free_prov: > diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h > index 6c358b7..9222c7e 100644 > --- a/tools/perf/util/symbol.h > +++ b/tools/perf/util/symbol.h > @@ -351,6 +351,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); > struct sdt_note { > char *name; /* name of the note*/ > char *provider; /* provider name */ > + char *args; > bool bit32; /* whether the location is 32 bits? */ > union { /* location, base and semaphore addrs */ > Elf64_Addr a64[3]; > -- > 2.10.2 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 1/2] perf sdt: add scanning of sdt probles arguments 2017-03-06 13:39 ` Masami Hiramatsu @ 2017-03-21 13:52 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 77+ messages in thread From: Arnaldo Carvalho de Melo @ 2017-03-21 13:52 UTC (permalink / raw) To: Masami Hiramatsu Cc: Alexis Berlemont, linux-kernel, peterz, mingo, alexander.shishkin Em Mon, Mar 06, 2017 at 02:39:15PM +0100, Masami Hiramatsu escreveu: > On Wed, 14 Dec 2016 01:07:31 +0100 > Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > > > During a "perf buildid-cache --add" command, the section > > ".note.stapsdt" of the "added" binary is scanned in order to list the > > available SDT markers available in a binary. The parts containing the > > probes arguments were left unscanned. > > > > The whole section is now parsed; the probe arguments are extracted for > > later use. > > > > Looks good to me. > > Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Thanks, applied. > Thanks! > > > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > > --- > > tools/perf/util/symbol-elf.c | 25 +++++++++++++++++++++++-- > > tools/perf/util/symbol.h | 1 + > > 2 files changed, 24 insertions(+), 2 deletions(-) > > > > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c > > index 99400b0..7725c3f 100644 > > --- a/tools/perf/util/symbol-elf.c > > +++ b/tools/perf/util/symbol-elf.c > > @@ -1822,7 +1822,7 @@ void kcore_extract__delete(struct kcore_extract *kce) > > static int populate_sdt_note(Elf **elf, const char *data, size_t len, > > struct list_head *sdt_notes) > > { > > - const char *provider, *name; > > + const char *provider, *name, *args; > > struct sdt_note *tmp = NULL; > > GElf_Ehdr ehdr; > > GElf_Addr base_off = 0; > > @@ -1881,6 +1881,25 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > > goto out_free_prov; > > } > > > > + args = memchr(name, '\0', data + len - name); > > + > > + /* > > + * There is no argument if: > > + * - We reached the end of the note; > > + * - There is not enough room to hold a potential string; > > + * - The argument string is empty or just contains ':'. > > + */ > > + if (args == NULL || data + len - args < 2 || > > + args[1] == ':' || args[1] == '\0') > > + tmp->args = NULL; > > + else { > > + tmp->args = strdup(++args); > > + if (!tmp->args) { > > + ret = -ENOMEM; > > + goto out_free_name; > > + } > > + } > > + > > if (gelf_getclass(*elf) == ELFCLASS32) { > > memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); > > tmp->bit32 = true; > > @@ -1892,7 +1911,7 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > > if (!gelf_getehdr(*elf, &ehdr)) { > > pr_debug("%s : cannot get elf header.\n", __func__); > > ret = -EBADF; > > - goto out_free_name; > > + goto out_free_args; > > } > > > > /* Adjust the prelink effect : > > @@ -1917,6 +1936,8 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, > > list_add_tail(&tmp->note_list, sdt_notes); > > return 0; > > > > +out_free_args: > > + free(tmp->args); > > out_free_name: > > free(tmp->name); > > out_free_prov: > > diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h > > index 6c358b7..9222c7e 100644 > > --- a/tools/perf/util/symbol.h > > +++ b/tools/perf/util/symbol.h > > @@ -351,6 +351,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); > > struct sdt_note { > > char *name; /* name of the note*/ > > char *provider; /* provider name */ > > + char *args; > > bool bit32; /* whether the location is 32 bits? */ > > union { /* location, base and semaphore addrs */ > > Elf64_Addr a64[3]; > > -- > > 2.10.2 > > > > > -- > Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [tip:perf/core] perf sdt: Add scanning of sdt probes arguments 2016-12-14 0:07 ` [PATCH v5 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2017-03-06 13:39 ` Masami Hiramatsu @ 2017-03-24 18:44 ` tip-bot for Alexis Berlemont 1 sibling, 0 replies; 77+ messages in thread From: tip-bot for Alexis Berlemont @ 2017-03-24 18:44 UTC (permalink / raw) To: linux-tip-commits Cc: linux-kernel, acme, mhiramat, peterz, ravi.bangoria, alexis.berlemont, hpa, mingo, alexander.shishkin, hemant, tglx Commit-ID: be88184b1c7054719296387c6063748fb48fa645 Gitweb: http://git.kernel.org/tip/be88184b1c7054719296387c6063748fb48fa645 Author: Alexis Berlemont <alexis.berlemont@gmail.com> AuthorDate: Wed, 14 Dec 2016 01:07:31 +0100 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Tue, 21 Mar 2017 10:56:28 -0300 perf sdt: Add scanning of sdt probes arguments During a "perf buildid-cache --add" command, the section ".note.stapsdt" of the "added" binary is scanned in order to list the available SDT markers available in a binary. The parts containing the probes arguments were left unscanned. The whole section is now parsed; the probe arguments are extracted for later use. Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Hemant Kumar <hemant@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/20161214000732.1710-2-alexis.berlemont@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/symbol-elf.c | 25 +++++++++++++++++++++++-- tools/perf/util/symbol.h | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 4e59dde..0e660db 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1828,7 +1828,7 @@ void kcore_extract__delete(struct kcore_extract *kce) static int populate_sdt_note(Elf **elf, const char *data, size_t len, struct list_head *sdt_notes) { - const char *provider, *name; + const char *provider, *name, *args; struct sdt_note *tmp = NULL; GElf_Ehdr ehdr; GElf_Addr base_off = 0; @@ -1887,6 +1887,25 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, goto out_free_prov; } + args = memchr(name, '\0', data + len - name); + + /* + * There is no argument if: + * - We reached the end of the note; + * - There is not enough room to hold a potential string; + * - The argument string is empty or just contains ':'. + */ + if (args == NULL || data + len - args < 2 || + args[1] == ':' || args[1] == '\0') + tmp->args = NULL; + else { + tmp->args = strdup(++args); + if (!tmp->args) { + ret = -ENOMEM; + goto out_free_name; + } + } + if (gelf_getclass(*elf) == ELFCLASS32) { memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); tmp->bit32 = true; @@ -1898,7 +1917,7 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, if (!gelf_getehdr(*elf, &ehdr)) { pr_debug("%s : cannot get elf header.\n", __func__); ret = -EBADF; - goto out_free_name; + goto out_free_args; } /* Adjust the prelink effect : @@ -1923,6 +1942,8 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, list_add_tail(&tmp->note_list, sdt_notes); return 0; +out_free_args: + free(tmp->args); out_free_name: free(tmp->name); out_free_prov: diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 6c358b7..9222c7e 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -351,6 +351,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); struct sdt_note { char *name; /* name of the note*/ char *provider; /* provider name */ + char *args; bool bit32; /* whether the location is 32 bits? */ union { /* location, base and semaphore addrs */ Elf64_Addr a64[3]; ^ permalink raw reply related [flat|nested] 77+ messages in thread
* [PATCH v5 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-07 3:26 ` Masami Hiramatsu ` (2 preceding siblings ...) 2016-12-14 0:07 ` [PATCH v5 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont @ 2016-12-14 0:07 ` Alexis Berlemont 2017-01-24 8:50 ` Ravi Bangoria ` (2 more replies) 3 siblings, 3 replies; 77+ messages in thread From: Alexis Berlemont @ 2016-12-14 0:07 UTC (permalink / raw) To: linux-kernel; +Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin An sdt probe can be associated with arguments but they were not passed to the user probe tracing interface (uprobe_events); this patch adapts the sdt argument descriptors according to the uprobe input format. As the uprobe parser does not support scaled address mode, perf will skip arguments which cannot be adapted to the uprobe format. Here are the results: $ perf buildid-cache -v --add test_sdt $ perf probe -x test_sdt sdt_libfoo:table_frob $ perf probe -x test_sdt sdt_libfoo:table_diddle $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt $ perf script test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/arch/x86/util/perf_regs.c | 83 +++++++++++++++++ tools/perf/util/perf_regs.c | 6 ++ tools/perf/util/perf_regs.h | 6 ++ tools/perf/util/probe-file.c | 170 ++++++++++++++++++++++++++++++++++- 4 files changed, 261 insertions(+), 4 deletions(-) diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index c5db14f..09a7f55 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -1,4 +1,7 @@ +#include <string.h> + #include "../../perf.h" +#include "../../util/util.h" #include "../../util/perf_regs.h" const struct sample_reg sample_reg_masks[] = { @@ -26,3 +29,83 @@ const struct sample_reg sample_reg_masks[] = { #endif SMPL_REG_END }; + +struct sdt_name_reg { + const char *sdt_name; + const char *uprobe_name; +}; +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} + +static const struct sdt_name_reg sdt_reg_renamings[] = { + SDT_NAME_REG(eax, ax), + SDT_NAME_REG(rax, ax), + SDT_NAME_REG(ebx, bx), + SDT_NAME_REG(rbx, bx), + SDT_NAME_REG(ecx, cx), + SDT_NAME_REG(rcx, cx), + SDT_NAME_REG(edx, dx), + SDT_NAME_REG(rdx, dx), + SDT_NAME_REG(esi, si), + SDT_NAME_REG(rsi, si), + SDT_NAME_REG(edi, di), + SDT_NAME_REG(rdi, di), + SDT_NAME_REG(ebp, bp), + SDT_NAME_REG(rbp, bp), + SDT_NAME_REG_END, +}; + +int sdt_rename_register(char **pdesc, char *old_name) +{ + const struct sdt_name_reg *rnames = sdt_reg_renamings; + char *new_desc, *old_desc = *pdesc; + size_t prefix_len, sdt_len, uprobe_len, old_desc_len, offset; + int ret = -1; + + while (ret != 0 && rnames->sdt_name != NULL) { + sdt_len = strlen(rnames->sdt_name); + ret = strncmp(old_name, rnames->sdt_name, sdt_len); + rnames += !!ret; + } + + if (rnames->sdt_name == NULL) + return 0; + + sdt_len = strlen(rnames->sdt_name); + uprobe_len = strlen(rnames->uprobe_name); + old_desc_len = strlen(old_desc) + 1; + + new_desc = zalloc(old_desc_len + uprobe_len - sdt_len); + if (new_desc == NULL) + return -1; + + /* Copy the chars before the register name (at least '%') */ + prefix_len = old_name - old_desc; + memcpy(new_desc, old_desc, prefix_len); + + /* Copy the new register name */ + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); + + /* Copy the chars after the register name (if need be) */ + offset = prefix_len + sdt_len; + if (offset < old_desc_len) { + /* + * The orginal register name can be suffixed by 'b', + * 'w' or 'd' to indicate its size; so, we need to + * skip this char if we met one. + */ + char sfx = old_desc[offset]; + + if (sfx == 'b' || sfx == 'w' || sfx == 'd') + offset++; + } + + if (offset < old_desc_len) + memcpy(new_desc + prefix_len + uprobe_len, + old_desc + offset, old_desc_len - offset); + + free(old_desc); + *pdesc = new_desc; + + return 0; +} diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index c4023f2..a37e593 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -6,6 +6,12 @@ const struct sample_reg __weak sample_reg_masks[] = { SMPL_REG_END }; +int __weak sdt_rename_register(char **pdesc __maybe_unused, + char *old_name __maybe_unused) +{ + return 0; +} + #ifdef HAVE_PERF_REGS_SUPPORT int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) { diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 679d6e4..7544a15 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -15,6 +15,12 @@ struct sample_reg { extern const struct sample_reg sample_reg_masks[]; +/* + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated + * registers before filling the uprobe tracer interface. + */ +int sdt_rename_register(char **pdesc, char *old_name); + #ifdef HAVE_PERF_REGS_SUPPORT #include <perf_regs.h> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 436b647..d8a169e 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -27,6 +27,7 @@ #include "probe-event.h" #include "probe-file.h" #include "session.h" +#include "perf_regs.h" #define MAX_CMDLEN 256 @@ -687,6 +688,166 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) : (unsigned long long)note->addr.a64[0]; } +static const char * const type_to_suffix[] = { + ":s64", "", "", "", ":s32", "", ":s16", ":s8", + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" +}; + +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) +{ + char *tmp, *desc = strdup(arg); + const char *prefix = "", *suffix = ""; + int ret = -1; + + if (desc == NULL) { + pr_debug4("Allocation error\n"); + return ret; + } + + tmp = strchr(desc, '@'); + if (tmp) { + long type_idx; + /* + * Isolate the string number and convert it into a + * binary value; this will be an index to get suffix + * of the uprobe name (defining the type) + */ + tmp[0] = '\0'; + type_idx = strtol(desc, NULL, 10); + /* Check that the conversion went OK */ + if (type_idx == LONG_MIN || type_idx == LONG_MAX) { + pr_debug4("Failed to parse sdt type\n"); + goto error; + } + /* Check that the converted value is OK */ + if (type_idx < -8 || type_idx > 8) { + pr_debug4("Failed to get a valid sdt type\n"); + goto error; + } + suffix = type_to_suffix[type_idx + 8]; + /* Get rid of the sdt prefix which is now useless */ + tmp++; + memmove(desc, tmp, strlen(tmp) + 1); + } + + /* + * The uprobe tracer format does not support all the + * addressing modes (notably: in x86 the scaled mode); so, we + * detect ',' characters, if there is just one, there is no + * use converting the sdt arg into a uprobe one. + */ + if (strchr(desc, ',')) { + pr_debug4("Skipping unsupported SDT argument; %s\n", desc); + goto out; + } + + /* + * If the argument addressing mode is indirect, we must check + * a few things... + */ + tmp = strchr(desc, '('); + if (tmp) { + int j; + + /* + * ...if the addressing mode is indirect with a + * positive offset (ex.: "1608(%ax)"), we need to add + * a '+' prefix so as to be compliant with uprobe + * format. + */ + if (desc[0] != '+' && desc[0] != '-') + prefix = "+"; + + /* + * ...or if the addressing mode is indirect with a symbol + * as offset, the argument will not be supported by + * the uprobe tracer format; so, let's skip this one. + */ + for (j = 0; j < tmp - desc; j++) { + if (desc[j] != '+' && desc[j] != '-' && + !isdigit(desc[j])) { + pr_debug4("Skipping unsupported SDT argument; " + "%s\n", desc); + goto out; + } + } + } + + /* + * The uprobe tracer format does not support constants; if we + * find one in the current argument, let's skip the argument. + */ + if (strchr(desc, '$')) { + pr_debug4("Skipping unsupported SDT argument; %s\n", desc); + goto out; + } + + /* + * The uprobe parser does not support all gas register names; + * so, we have to replace them (ex. for x86_64: %rax -> %ax); + * the loop below looks for the register names (starting with + * a '%' and tries to perform the needed renamings. + */ + tmp = strchr(desc, '%'); + while (tmp) { + size_t offset = tmp - desc; + + ret = sdt_rename_register(&desc, desc + offset); + if (ret < 0) + goto error; + + /* + * The desc pointer might have changed; so, let's not + * try to reuse tmp for next lookup + */ + tmp = strchr(desc + offset + 1, '%'); + } + + if (strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) + goto error; + +out: + ret = 0; +error: + free(desc); + return ret; +} + +static char *synthesize_sdt_probe_command(struct sdt_note *note, + const char *pathname, + const char *sdtgrp) +{ + struct strbuf buf; + char *ret = NULL, **args; + int i, args_count; + + if (strbuf_init(&buf, 32) < 0) + return NULL; + + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", + sdtgrp, note->name, pathname, + sdt_note__get_addr(note)) < 0) + goto error; + + if (!note->args) + goto out; + + if (note->args) { + args = argv_split(note->args, &args_count); + + for (i = 0; i < args_count; ++i) { + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) + goto error; + } + } + +out: + ret = strbuf_detach(&buf, NULL); +error: + strbuf_release(&buf); + return ret; +} + int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) { struct probe_cache_entry *entry = NULL; @@ -723,11 +884,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) entry->pev.group = strdup(sdtgrp); list_add_tail(&entry->node, &pcache->entries); } - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", - sdtgrp, note->name, pathname, - sdt_note__get_addr(note)); - if (ret < 0) + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); + if (!buf) { + ret = -ENOMEM; break; + } + strlist__add(entry->tevlist, buf); free(buf); entry = NULL; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH v5 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-14 0:07 ` [PATCH v5 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont @ 2017-01-24 8:50 ` Ravi Bangoria 2017-03-06 17:23 ` Masami Hiramatsu 2017-03-24 18:44 ` [tip:perf/core] perf probe: Add " tip-bot for Alexis Berlemont 2 siblings, 0 replies; 77+ messages in thread From: Ravi Bangoria @ 2017-01-24 8:50 UTC (permalink / raw) To: Alexis Berlemont Cc: linux-kernel, peterz, mingo, acme, alexander.shishkin, Ravi Bangoria Hi Alexis, On Wednesday 14 December 2016 05:37 AM, Alexis Berlemont wrote: > An sdt probe can be associated with arguments but they were not passed > to the user probe tracing interface (uprobe_events); this patch adapts > the sdt argument descriptors according to the uprobe input format. > > As the uprobe parser does not support scaled address mode, perf will > skip arguments which cannot be adapted to the uprobe format. > > Here are the results: > > $ perf buildid-cache -v --add test_sdt > $ perf probe -x test_sdt sdt_libfoo:table_frob > $ perf probe -x test_sdt sdt_libfoo:table_diddle > $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt > $ perf script > test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 > test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 > test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 > test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 > test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 > test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 > > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > --- > tools/perf/arch/x86/util/perf_regs.c | 83 +++++++++++++++++ > tools/perf/util/perf_regs.c | 6 ++ > tools/perf/util/perf_regs.h | 6 ++ > tools/perf/util/probe-file.c | 170 ++++++++++++++++++++++++++++++++++- > 4 files changed, 261 insertions(+), 4 deletions(-) > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > index c5db14f..09a7f55 100644 > --- a/tools/perf/arch/x86/util/perf_regs.c > +++ b/tools/perf/arch/x86/util/perf_regs.c > @@ -1,4 +1,7 @@ > +#include <string.h> > + > #include "../../perf.h" > +#include "../../util/util.h" > #include "../../util/perf_regs.h" > > const struct sample_reg sample_reg_masks[] = { > @@ -26,3 +29,83 @@ const struct sample_reg sample_reg_masks[] = { > #endif > SMPL_REG_END > }; > + > +struct sdt_name_reg { > + const char *sdt_name; > + const char *uprobe_name; > +}; > +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} > +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} > + > +static const struct sdt_name_reg sdt_reg_renamings[] = { > + SDT_NAME_REG(eax, ax), > + SDT_NAME_REG(rax, ax), > + SDT_NAME_REG(ebx, bx), > + SDT_NAME_REG(rbx, bx), > + SDT_NAME_REG(ecx, cx), > + SDT_NAME_REG(rcx, cx), > + SDT_NAME_REG(edx, dx), > + SDT_NAME_REG(rdx, dx), > + SDT_NAME_REG(esi, si), > + SDT_NAME_REG(rsi, si), > + SDT_NAME_REG(edi, di), > + SDT_NAME_REG(rdi, di), > + SDT_NAME_REG(ebp, bp), > + SDT_NAME_REG(rbp, bp), > + SDT_NAME_REG_END, > +}; I see many markers uses %rsp. Such markers are failing at perf probe. Please add renaming entry for %rsp and %esp. For example: $ readelf -n /usr/lib64/libpython3.5m.so.1.0 ... Name: function__entry Arguments: 8@224(%rsp) 8@232(%rsp) -4@240(%rsp) 8@%rbx $ sudo ./perf probe sdt_python:function__entry Failed to write event: Invalid argument Please upgrade your kernel to at least 3.14 to have access to feature +224(%rsp):u64 Error: Failed to add events. This code does not handle rNN registers with postfix('b', 'w', 'd'). Such markers are failing at perf probe. For example: $ readelf -n /usr/lib64/libperl.so.5.24.0 ... Name: sub__return Arguments: 8@%rax 8@%r8 4@%r9d 8@%rsi $ sudo ./perf probe -v sdt_perl:sub__entry ... Opening /sys/kernel/debug/tracing//uprobe_events write=1 Writing event: p:sdt_perl/sub__entry /usr/lib64/libperl.so.5.24.0:0xbb780 arg1=%ax:u64 arg2=%r8:u64 arg3=%r9d:u32 arg4=%si:u64 Failed to write event: Invalid argument Error: Failed to add events. Reason: Invalid argument (Code: -22) Can we add them like: /* rNN registers */ SDT_NAME_REG(r8b, r8), SDT_NAME_REG(r8w, r8), SDT_NAME_REG(r8d, r8), SDT_NAME_REG(r9b, r9), ... SDT_NAME_REG(r14d, r14), SDT_NAME_REG(r15b, r15), SDT_NAME_REG(r15w, r15), SDT_NAME_REG(r15d, r15), and ... > + > +int sdt_rename_register(char **pdesc, char *old_name) > +{ > + const struct sdt_name_reg *rnames = sdt_reg_renamings; > + char *new_desc, *old_desc = *pdesc; > + size_t prefix_len, sdt_len, uprobe_len, old_desc_len, offset; > + int ret = -1; > + > + while (ret != 0 && rnames->sdt_name != NULL) { > + sdt_len = strlen(rnames->sdt_name); > + ret = strncmp(old_name, rnames->sdt_name, sdt_len); > + rnames += !!ret; > + } > + > + if (rnames->sdt_name == NULL) > + return 0; > + > + sdt_len = strlen(rnames->sdt_name); > + uprobe_len = strlen(rnames->uprobe_name); > + old_desc_len = strlen(old_desc) + 1; > + > + new_desc = zalloc(old_desc_len + uprobe_len - sdt_len); > + if (new_desc == NULL) > + return -1; > + > + /* Copy the chars before the register name (at least '%') */ > + prefix_len = old_name - old_desc; > + memcpy(new_desc, old_desc, prefix_len); > + > + /* Copy the new register name */ > + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); > + > + /* Copy the chars after the register name (if need be) */ > + offset = prefix_len + sdt_len; ... remove below if(){} block. > + if (offset < old_desc_len) { > + /* > + * The orginal register name can be suffixed by 'b', > + * 'w' or 'd' to indicate its size; so, we need to > + * skip this char if we met one. > + */ > + char sfx = old_desc[offset]; > + > + if (sfx == 'b' || sfx == 'w' || sfx == 'd') > + offset++; > + } > + > + if (offset < old_desc_len) > + memcpy(new_desc + prefix_len + uprobe_len, > + old_desc + offset, old_desc_len - offset); > + > + free(old_desc); > + *pdesc = new_desc; > + > + return 0; > +} > diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c > index c4023f2..a37e593 100644 > --- a/tools/perf/util/perf_regs.c > +++ b/tools/perf/util/perf_regs.c > @@ -6,6 +6,12 @@ const struct sample_reg __weak sample_reg_masks[] = { > SMPL_REG_END > }; > > +int __weak sdt_rename_register(char **pdesc __maybe_unused, > + char *old_name __maybe_unused) > +{ > + return 0; > +} > + > #ifdef HAVE_PERF_REGS_SUPPORT > int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) > { > diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h > index 679d6e4..7544a15 100644 > --- a/tools/perf/util/perf_regs.h > +++ b/tools/perf/util/perf_regs.h > @@ -15,6 +15,12 @@ struct sample_reg { > > extern const struct sample_reg sample_reg_masks[]; > > +/* > + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > + * registers before filling the uprobe tracer interface. > + */ > +int sdt_rename_register(char **pdesc, char *old_name); > + > #ifdef HAVE_PERF_REGS_SUPPORT > #include <perf_regs.h> > > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index 436b647..d8a169e 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -27,6 +27,7 @@ > #include "probe-event.h" > #include "probe-file.h" > #include "session.h" > +#include "perf_regs.h" > > #define MAX_CMDLEN 256 > > @@ -687,6 +688,166 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) > : (unsigned long long)note->addr.a64[0]; > } > > +static const char * const type_to_suffix[] = { > + ":s64", "", "", "", ":s32", "", ":s16", ":s8", > + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" > +}; > + > +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > +{ > + char *tmp, *desc = strdup(arg); > + const char *prefix = "", *suffix = ""; > + int ret = -1; > + > + if (desc == NULL) { > + pr_debug4("Allocation error\n"); > + return ret; > + } > + > + tmp = strchr(desc, '@'); > + if (tmp) { > + long type_idx; > + /* > + * Isolate the string number and convert it into a > + * binary value; this will be an index to get suffix > + * of the uprobe name (defining the type) > + */ > + tmp[0] = '\0'; > + type_idx = strtol(desc, NULL, 10); > + /* Check that the conversion went OK */ > + if (type_idx == LONG_MIN || type_idx == LONG_MAX) { > + pr_debug4("Failed to parse sdt type\n"); > + goto error; > + } > + /* Check that the converted value is OK */ > + if (type_idx < -8 || type_idx > 8) { > + pr_debug4("Failed to get a valid sdt type\n"); > + goto error; > + } > + suffix = type_to_suffix[type_idx + 8]; > + /* Get rid of the sdt prefix which is now useless */ > + tmp++; > + memmove(desc, tmp, strlen(tmp) + 1); > + } > + Below code is x86 specific. For example, Powerpc uses "i" for constant arguments not "$". Powerpc does not use symbol as offset etc. SDT marker argument is in N@OP format. Can we divide this function into two components. One parses N and other parses OP. Parsing OP will be arch specific code and should be moved under /tools/perf/arch/. > + /* > + * The uprobe tracer format does not support all the > + * addressing modes (notably: in x86 the scaled mode); so, we > + * detect ',' characters, if there is just one, there is no > + * use converting the sdt arg into a uprobe one. > + */ > + if (strchr(desc, ',')) { > + pr_debug4("Skipping unsupported SDT argument; %s\n", desc); > + goto out; > + } > + > + /* > + * If the argument addressing mode is indirect, we must check > + * a few things... > + */ > + tmp = strchr(desc, '('); > + if (tmp) { > + int j; > + > + /* > + * ...if the addressing mode is indirect with a > + * positive offset (ex.: "1608(%ax)"), we need to add > + * a '+' prefix so as to be compliant with uprobe > + * format. > + */ > + if (desc[0] != '+' && desc[0] != '-') > + prefix = "+"; > + > + /* > + * ...or if the addressing mode is indirect with a symbol > + * as offset, the argument will not be supported by > + * the uprobe tracer format; so, let's skip this one. > + */ > + for (j = 0; j < tmp - desc; j++) { > + if (desc[j] != '+' && desc[j] != '-' && > + !isdigit(desc[j])) { > + pr_debug4("Skipping unsupported SDT argument; " > + "%s\n", desc); > + goto out; > + } > + } > + } > + > + /* > + * The uprobe tracer format does not support constants; if we > + * find one in the current argument, let's skip the argument. > + */ > + if (strchr(desc, '$')) { > + pr_debug4("Skipping unsupported SDT argument; %s\n", desc); > + goto out; > + } > + > + /* > + * The uprobe parser does not support all gas register names; > + * so, we have to replace them (ex. for x86_64: %rax -> %ax); > + * the loop below looks for the register names (starting with > + * a '%' and tries to perform the needed renamings. > + */ > + tmp = strchr(desc, '%'); > + while (tmp) { > + size_t offset = tmp - desc; > + > + ret = sdt_rename_register(&desc, desc + offset); > + if (ret < 0) > + goto error; > + > + /* > + * The desc pointer might have changed; so, let's not > + * try to reuse tmp for next lookup > + */ > + tmp = strchr(desc + offset + 1, '%'); > + } > + > + if (strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) > + goto error; > + > +out: > + ret = 0; > +error: > + free(desc); > + return ret; > +} Thanks, Ravi ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-12-14 0:07 ` [PATCH v5 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2017-01-24 8:50 ` Ravi Bangoria @ 2017-03-06 17:23 ` Masami Hiramatsu 2017-03-24 18:44 ` [tip:perf/core] perf probe: Add " tip-bot for Alexis Berlemont 2 siblings, 0 replies; 77+ messages in thread From: Masami Hiramatsu @ 2017-03-06 17:23 UTC (permalink / raw) To: Alexis Berlemont; +Cc: linux-kernel, peterz, mingo, acme, alexander.shishkin On Wed, 14 Dec 2016 01:07:32 +0100 Alexis Berlemont <alexis.berlemont@gmail.com> wrote: > An sdt probe can be associated with arguments but they were not passed > to the user probe tracing interface (uprobe_events); this patch adapts > the sdt argument descriptors according to the uprobe input format. > > As the uprobe parser does not support scaled address mode, perf will > skip arguments which cannot be adapted to the uprobe format. > > Here are the results: > > $ perf buildid-cache -v --add test_sdt > $ perf probe -x test_sdt sdt_libfoo:table_frob > $ perf probe -x test_sdt sdt_libfoo:table_diddle > $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt > $ perf script > test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 > test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 > test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 > test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 > test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 > test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 > OK, this looks good to me, good job! Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Thanks! > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > --- > tools/perf/arch/x86/util/perf_regs.c | 83 +++++++++++++++++ > tools/perf/util/perf_regs.c | 6 ++ > tools/perf/util/perf_regs.h | 6 ++ > tools/perf/util/probe-file.c | 170 ++++++++++++++++++++++++++++++++++- > 4 files changed, 261 insertions(+), 4 deletions(-) > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > index c5db14f..09a7f55 100644 > --- a/tools/perf/arch/x86/util/perf_regs.c > +++ b/tools/perf/arch/x86/util/perf_regs.c > @@ -1,4 +1,7 @@ > +#include <string.h> > + > #include "../../perf.h" > +#include "../../util/util.h" > #include "../../util/perf_regs.h" > > const struct sample_reg sample_reg_masks[] = { > @@ -26,3 +29,83 @@ const struct sample_reg sample_reg_masks[] = { > #endif > SMPL_REG_END > }; > + > +struct sdt_name_reg { > + const char *sdt_name; > + const char *uprobe_name; > +}; > +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} > +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} > + > +static const struct sdt_name_reg sdt_reg_renamings[] = { > + SDT_NAME_REG(eax, ax), > + SDT_NAME_REG(rax, ax), > + SDT_NAME_REG(ebx, bx), > + SDT_NAME_REG(rbx, bx), > + SDT_NAME_REG(ecx, cx), > + SDT_NAME_REG(rcx, cx), > + SDT_NAME_REG(edx, dx), > + SDT_NAME_REG(rdx, dx), > + SDT_NAME_REG(esi, si), > + SDT_NAME_REG(rsi, si), > + SDT_NAME_REG(edi, di), > + SDT_NAME_REG(rdi, di), > + SDT_NAME_REG(ebp, bp), > + SDT_NAME_REG(rbp, bp), > + SDT_NAME_REG_END, > +}; > + > +int sdt_rename_register(char **pdesc, char *old_name) > +{ > + const struct sdt_name_reg *rnames = sdt_reg_renamings; > + char *new_desc, *old_desc = *pdesc; > + size_t prefix_len, sdt_len, uprobe_len, old_desc_len, offset; > + int ret = -1; > + > + while (ret != 0 && rnames->sdt_name != NULL) { > + sdt_len = strlen(rnames->sdt_name); > + ret = strncmp(old_name, rnames->sdt_name, sdt_len); > + rnames += !!ret; > + } > + > + if (rnames->sdt_name == NULL) > + return 0; > + > + sdt_len = strlen(rnames->sdt_name); > + uprobe_len = strlen(rnames->uprobe_name); > + old_desc_len = strlen(old_desc) + 1; > + > + new_desc = zalloc(old_desc_len + uprobe_len - sdt_len); > + if (new_desc == NULL) > + return -1; > + > + /* Copy the chars before the register name (at least '%') */ > + prefix_len = old_name - old_desc; > + memcpy(new_desc, old_desc, prefix_len); > + > + /* Copy the new register name */ > + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); > + > + /* Copy the chars after the register name (if need be) */ > + offset = prefix_len + sdt_len; > + if (offset < old_desc_len) { > + /* > + * The orginal register name can be suffixed by 'b', > + * 'w' or 'd' to indicate its size; so, we need to > + * skip this char if we met one. > + */ > + char sfx = old_desc[offset]; > + > + if (sfx == 'b' || sfx == 'w' || sfx == 'd') > + offset++; > + } > + > + if (offset < old_desc_len) > + memcpy(new_desc + prefix_len + uprobe_len, > + old_desc + offset, old_desc_len - offset); > + > + free(old_desc); > + *pdesc = new_desc; > + > + return 0; > +} > diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c > index c4023f2..a37e593 100644 > --- a/tools/perf/util/perf_regs.c > +++ b/tools/perf/util/perf_regs.c > @@ -6,6 +6,12 @@ const struct sample_reg __weak sample_reg_masks[] = { > SMPL_REG_END > }; > > +int __weak sdt_rename_register(char **pdesc __maybe_unused, > + char *old_name __maybe_unused) > +{ > + return 0; > +} > + > #ifdef HAVE_PERF_REGS_SUPPORT > int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) > { > diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h > index 679d6e4..7544a15 100644 > --- a/tools/perf/util/perf_regs.h > +++ b/tools/perf/util/perf_regs.h > @@ -15,6 +15,12 @@ struct sample_reg { > > extern const struct sample_reg sample_reg_masks[]; > > +/* > + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > + * registers before filling the uprobe tracer interface. > + */ > +int sdt_rename_register(char **pdesc, char *old_name); > + > #ifdef HAVE_PERF_REGS_SUPPORT > #include <perf_regs.h> > > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index 436b647..d8a169e 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -27,6 +27,7 @@ > #include "probe-event.h" > #include "probe-file.h" > #include "session.h" > +#include "perf_regs.h" > > #define MAX_CMDLEN 256 > > @@ -687,6 +688,166 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) > : (unsigned long long)note->addr.a64[0]; > } > > +static const char * const type_to_suffix[] = { > + ":s64", "", "", "", ":s32", "", ":s16", ":s8", > + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" > +}; > + > +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > +{ > + char *tmp, *desc = strdup(arg); > + const char *prefix = "", *suffix = ""; > + int ret = -1; > + > + if (desc == NULL) { > + pr_debug4("Allocation error\n"); > + return ret; > + } > + > + tmp = strchr(desc, '@'); > + if (tmp) { > + long type_idx; > + /* > + * Isolate the string number and convert it into a > + * binary value; this will be an index to get suffix > + * of the uprobe name (defining the type) > + */ > + tmp[0] = '\0'; > + type_idx = strtol(desc, NULL, 10); > + /* Check that the conversion went OK */ > + if (type_idx == LONG_MIN || type_idx == LONG_MAX) { > + pr_debug4("Failed to parse sdt type\n"); > + goto error; > + } > + /* Check that the converted value is OK */ > + if (type_idx < -8 || type_idx > 8) { > + pr_debug4("Failed to get a valid sdt type\n"); > + goto error; > + } > + suffix = type_to_suffix[type_idx + 8]; > + /* Get rid of the sdt prefix which is now useless */ > + tmp++; > + memmove(desc, tmp, strlen(tmp) + 1); > + } > + > + /* > + * The uprobe tracer format does not support all the > + * addressing modes (notably: in x86 the scaled mode); so, we > + * detect ',' characters, if there is just one, there is no > + * use converting the sdt arg into a uprobe one. > + */ > + if (strchr(desc, ',')) { > + pr_debug4("Skipping unsupported SDT argument; %s\n", desc); > + goto out; > + } > + > + /* > + * If the argument addressing mode is indirect, we must check > + * a few things... > + */ > + tmp = strchr(desc, '('); > + if (tmp) { > + int j; > + > + /* > + * ...if the addressing mode is indirect with a > + * positive offset (ex.: "1608(%ax)"), we need to add > + * a '+' prefix so as to be compliant with uprobe > + * format. > + */ > + if (desc[0] != '+' && desc[0] != '-') > + prefix = "+"; > + > + /* > + * ...or if the addressing mode is indirect with a symbol > + * as offset, the argument will not be supported by > + * the uprobe tracer format; so, let's skip this one. > + */ > + for (j = 0; j < tmp - desc; j++) { > + if (desc[j] != '+' && desc[j] != '-' && > + !isdigit(desc[j])) { > + pr_debug4("Skipping unsupported SDT argument; " > + "%s\n", desc); > + goto out; > + } > + } > + } > + > + /* > + * The uprobe tracer format does not support constants; if we > + * find one in the current argument, let's skip the argument. > + */ > + if (strchr(desc, '$')) { > + pr_debug4("Skipping unsupported SDT argument; %s\n", desc); > + goto out; > + } > + > + /* > + * The uprobe parser does not support all gas register names; > + * so, we have to replace them (ex. for x86_64: %rax -> %ax); > + * the loop below looks for the register names (starting with > + * a '%' and tries to perform the needed renamings. > + */ > + tmp = strchr(desc, '%'); > + while (tmp) { > + size_t offset = tmp - desc; > + > + ret = sdt_rename_register(&desc, desc + offset); > + if (ret < 0) > + goto error; > + > + /* > + * The desc pointer might have changed; so, let's not > + * try to reuse tmp for next lookup > + */ > + tmp = strchr(desc + offset + 1, '%'); > + } > + > + if (strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) > + goto error; > + > +out: > + ret = 0; > +error: > + free(desc); > + return ret; > +} > + > +static char *synthesize_sdt_probe_command(struct sdt_note *note, > + const char *pathname, > + const char *sdtgrp) > +{ > + struct strbuf buf; > + char *ret = NULL, **args; > + int i, args_count; > + > + if (strbuf_init(&buf, 32) < 0) > + return NULL; > + > + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", > + sdtgrp, note->name, pathname, > + sdt_note__get_addr(note)) < 0) > + goto error; > + > + if (!note->args) > + goto out; > + > + if (note->args) { > + args = argv_split(note->args, &args_count); > + > + for (i = 0; i < args_count; ++i) { > + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) > + goto error; > + } > + } > + > +out: > + ret = strbuf_detach(&buf, NULL); > +error: > + strbuf_release(&buf); > + return ret; > +} > + > int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > { > struct probe_cache_entry *entry = NULL; > @@ -723,11 +884,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > entry->pev.group = strdup(sdtgrp); > list_add_tail(&entry->node, &pcache->entries); > } > - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", > - sdtgrp, note->name, pathname, > - sdt_note__get_addr(note)); > - if (ret < 0) > + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); > + if (!buf) { > + ret = -ENOMEM; > break; > + } > + > strlist__add(entry->tevlist, buf); > free(buf); > entry = NULL; > -- > 2.10.2 > -- Masami Hiramatsu <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 77+ messages in thread
* [tip:perf/core] perf probe: Add sdt probes arguments into the uprobe cmd string 2016-12-14 0:07 ` [PATCH v5 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2017-01-24 8:50 ` Ravi Bangoria 2017-03-06 17:23 ` Masami Hiramatsu @ 2017-03-24 18:44 ` tip-bot for Alexis Berlemont 2 siblings, 0 replies; 77+ messages in thread From: tip-bot for Alexis Berlemont @ 2017-03-24 18:44 UTC (permalink / raw) To: linux-tip-commits Cc: alexis.berlemont, linux-kernel, ravi.bangoria, tglx, mingo, hemant, mhiramat, alexander.shishkin, peterz, hpa, acme Commit-ID: 3b1f8311f6963cd11a7d1efbcd2fd900d472ba5c Gitweb: http://git.kernel.org/tip/3b1f8311f6963cd11a7d1efbcd2fd900d472ba5c Author: Alexis Berlemont <alexis.berlemont@gmail.com> AuthorDate: Wed, 14 Dec 2016 01:07:32 +0100 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Tue, 21 Mar 2017 10:59:01 -0300 perf probe: Add sdt probes arguments into the uprobe cmd string An sdt probe can be associated with arguments but they were not passed to the user probe tracing interface (uprobe_events); this patch adapts the sdt argument descriptors according to the uprobe input format. As the uprobe parser does not support scaled address mode, perf will skip arguments which cannot be adapted to the uprobe format. Here are the results: $ perf buildid-cache -v --add test_sdt $ perf probe -x test_sdt sdt_libfoo:table_frob $ perf probe -x test_sdt sdt_libfoo:table_diddle $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt $ perf script test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Hemant Kumar <hemant@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/20161214000732.1710-3-alexis.berlemont@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/arch/x86/util/perf_regs.c | 83 +++++++++++++++++ tools/perf/util/perf_regs.c | 6 ++ tools/perf/util/perf_regs.h | 6 ++ tools/perf/util/probe-file.c | 170 ++++++++++++++++++++++++++++++++++- 4 files changed, 261 insertions(+), 4 deletions(-) diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index c5db14f..09a7f55 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -1,4 +1,7 @@ +#include <string.h> + #include "../../perf.h" +#include "../../util/util.h" #include "../../util/perf_regs.h" const struct sample_reg sample_reg_masks[] = { @@ -26,3 +29,83 @@ const struct sample_reg sample_reg_masks[] = { #endif SMPL_REG_END }; + +struct sdt_name_reg { + const char *sdt_name; + const char *uprobe_name; +}; +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} + +static const struct sdt_name_reg sdt_reg_renamings[] = { + SDT_NAME_REG(eax, ax), + SDT_NAME_REG(rax, ax), + SDT_NAME_REG(ebx, bx), + SDT_NAME_REG(rbx, bx), + SDT_NAME_REG(ecx, cx), + SDT_NAME_REG(rcx, cx), + SDT_NAME_REG(edx, dx), + SDT_NAME_REG(rdx, dx), + SDT_NAME_REG(esi, si), + SDT_NAME_REG(rsi, si), + SDT_NAME_REG(edi, di), + SDT_NAME_REG(rdi, di), + SDT_NAME_REG(ebp, bp), + SDT_NAME_REG(rbp, bp), + SDT_NAME_REG_END, +}; + +int sdt_rename_register(char **pdesc, char *old_name) +{ + const struct sdt_name_reg *rnames = sdt_reg_renamings; + char *new_desc, *old_desc = *pdesc; + size_t prefix_len, sdt_len, uprobe_len, old_desc_len, offset; + int ret = -1; + + while (ret != 0 && rnames->sdt_name != NULL) { + sdt_len = strlen(rnames->sdt_name); + ret = strncmp(old_name, rnames->sdt_name, sdt_len); + rnames += !!ret; + } + + if (rnames->sdt_name == NULL) + return 0; + + sdt_len = strlen(rnames->sdt_name); + uprobe_len = strlen(rnames->uprobe_name); + old_desc_len = strlen(old_desc) + 1; + + new_desc = zalloc(old_desc_len + uprobe_len - sdt_len); + if (new_desc == NULL) + return -1; + + /* Copy the chars before the register name (at least '%') */ + prefix_len = old_name - old_desc; + memcpy(new_desc, old_desc, prefix_len); + + /* Copy the new register name */ + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); + + /* Copy the chars after the register name (if need be) */ + offset = prefix_len + sdt_len; + if (offset < old_desc_len) { + /* + * The orginal register name can be suffixed by 'b', + * 'w' or 'd' to indicate its size; so, we need to + * skip this char if we met one. + */ + char sfx = old_desc[offset]; + + if (sfx == 'b' || sfx == 'w' || sfx == 'd') + offset++; + } + + if (offset < old_desc_len) + memcpy(new_desc + prefix_len + uprobe_len, + old_desc + offset, old_desc_len - offset); + + free(old_desc); + *pdesc = new_desc; + + return 0; +} diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index c4023f2..a37e593 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -6,6 +6,12 @@ const struct sample_reg __weak sample_reg_masks[] = { SMPL_REG_END }; +int __weak sdt_rename_register(char **pdesc __maybe_unused, + char *old_name __maybe_unused) +{ + return 0; +} + #ifdef HAVE_PERF_REGS_SUPPORT int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) { diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 679d6e4..7544a15 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -15,6 +15,12 @@ struct sample_reg { extern const struct sample_reg sample_reg_masks[]; +/* + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated + * registers before filling the uprobe tracer interface. + */ +int sdt_rename_register(char **pdesc, char *old_name); + #ifdef HAVE_PERF_REGS_SUPPORT #include <perf_regs.h> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index c3c2871..d741634 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -27,6 +27,7 @@ #include "probe-event.h" #include "probe-file.h" #include "session.h" +#include "perf_regs.h" /* 4096 - 2 ('\n' + '\0') */ #define MAX_CMDLEN 4094 @@ -688,6 +689,166 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) : (unsigned long long)note->addr.a64[0]; } +static const char * const type_to_suffix[] = { + ":s64", "", "", "", ":s32", "", ":s16", ":s8", + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" +}; + +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) +{ + char *tmp, *desc = strdup(arg); + const char *prefix = "", *suffix = ""; + int ret = -1; + + if (desc == NULL) { + pr_debug4("Allocation error\n"); + return ret; + } + + tmp = strchr(desc, '@'); + if (tmp) { + long type_idx; + /* + * Isolate the string number and convert it into a + * binary value; this will be an index to get suffix + * of the uprobe name (defining the type) + */ + tmp[0] = '\0'; + type_idx = strtol(desc, NULL, 10); + /* Check that the conversion went OK */ + if (type_idx == LONG_MIN || type_idx == LONG_MAX) { + pr_debug4("Failed to parse sdt type\n"); + goto error; + } + /* Check that the converted value is OK */ + if (type_idx < -8 || type_idx > 8) { + pr_debug4("Failed to get a valid sdt type\n"); + goto error; + } + suffix = type_to_suffix[type_idx + 8]; + /* Get rid of the sdt prefix which is now useless */ + tmp++; + memmove(desc, tmp, strlen(tmp) + 1); + } + + /* + * The uprobe tracer format does not support all the + * addressing modes (notably: in x86 the scaled mode); so, we + * detect ',' characters, if there is just one, there is no + * use converting the sdt arg into a uprobe one. + */ + if (strchr(desc, ',')) { + pr_debug4("Skipping unsupported SDT argument; %s\n", desc); + goto out; + } + + /* + * If the argument addressing mode is indirect, we must check + * a few things... + */ + tmp = strchr(desc, '('); + if (tmp) { + int j; + + /* + * ...if the addressing mode is indirect with a + * positive offset (ex.: "1608(%ax)"), we need to add + * a '+' prefix so as to be compliant with uprobe + * format. + */ + if (desc[0] != '+' && desc[0] != '-') + prefix = "+"; + + /* + * ...or if the addressing mode is indirect with a symbol + * as offset, the argument will not be supported by + * the uprobe tracer format; so, let's skip this one. + */ + for (j = 0; j < tmp - desc; j++) { + if (desc[j] != '+' && desc[j] != '-' && + !isdigit(desc[j])) { + pr_debug4("Skipping unsupported SDT argument; " + "%s\n", desc); + goto out; + } + } + } + + /* + * The uprobe tracer format does not support constants; if we + * find one in the current argument, let's skip the argument. + */ + if (strchr(desc, '$')) { + pr_debug4("Skipping unsupported SDT argument; %s\n", desc); + goto out; + } + + /* + * The uprobe parser does not support all gas register names; + * so, we have to replace them (ex. for x86_64: %rax -> %ax); + * the loop below looks for the register names (starting with + * a '%' and tries to perform the needed renamings. + */ + tmp = strchr(desc, '%'); + while (tmp) { + size_t offset = tmp - desc; + + ret = sdt_rename_register(&desc, desc + offset); + if (ret < 0) + goto error; + + /* + * The desc pointer might have changed; so, let's not + * try to reuse tmp for next lookup + */ + tmp = strchr(desc + offset + 1, '%'); + } + + if (strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) + goto error; + +out: + ret = 0; +error: + free(desc); + return ret; +} + +static char *synthesize_sdt_probe_command(struct sdt_note *note, + const char *pathname, + const char *sdtgrp) +{ + struct strbuf buf; + char *ret = NULL, **args; + int i, args_count; + + if (strbuf_init(&buf, 32) < 0) + return NULL; + + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", + sdtgrp, note->name, pathname, + sdt_note__get_addr(note)) < 0) + goto error; + + if (!note->args) + goto out; + + if (note->args) { + args = argv_split(note->args, &args_count); + + for (i = 0; i < args_count; ++i) { + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) + goto error; + } + } + +out: + ret = strbuf_detach(&buf, NULL); +error: + strbuf_release(&buf); + return ret; +} + int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) { struct probe_cache_entry *entry = NULL; @@ -724,11 +885,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) entry->pev.group = strdup(sdtgrp); list_add_tail(&entry->node, &pcache->entries); } - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", - sdtgrp, note->name, pathname, - sdt_note__get_addr(note)); - if (ret < 0) + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); + if (!buf) { + ret = -ENOMEM; break; + } + strlist__add(entry->tevlist, buf); free(buf); entry = NULL; ^ permalink raw reply related [flat|nested] 77+ messages in thread
* [PATCH v2 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-17 9:04 ` Hemant Kumar 2016-11-18 23:56 ` [PATCH v2 0/2] " Alexis Berlemont 2016-11-18 23:56 ` [PATCH v2 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont @ 2016-11-18 23:56 ` Alexis Berlemont 2016-11-21 10:25 ` Hemant Kumar 2 siblings, 1 reply; 77+ messages in thread From: Alexis Berlemont @ 2016-11-18 23:56 UTC (permalink / raw) To: linux-kernel Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin, hemant An sdt probe can be associated with arguments but they were not passed to the user probe tracing interface (uprobe_events); this patch adapts the sdt argument descriptors according to the uprobe input format. As the uprobe parser does not support scaled address mode, perf will skip arguments which cannot be adapted to the uprobe format. Here are the results: $ perf buildid-cache -v --add test_sdt $ perf probe -x test_sdt sdt_libfoo:table_frob $ perf probe -x test_sdt sdt_libfoo:table_diddle $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt $ perf script test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/arch/x86/util/perf_regs.c | 18 +++++ tools/perf/util/perf_regs.c | 4 + tools/perf/util/perf_regs.h | 13 ++++ tools/perf/util/probe-file.c | 141 ++++++++++++++++++++++++++++++++++- 4 files changed, 172 insertions(+), 4 deletions(-) diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index c5db14f..52a1e65 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -26,3 +26,21 @@ const struct sample_reg sample_reg_masks[] = { #endif SMPL_REG_END }; + +const struct sdt_name_reg sdt_reg_renamings[] = { + SDT_NAME_REG(eax, ax), + SDT_NAME_REG(rax, ax), + SDT_NAME_REG(ebx, bx), + SDT_NAME_REG(rbx, bx), + SDT_NAME_REG(ecx, cx), + SDT_NAME_REG(rcx, cx), + SDT_NAME_REG(edx, dx), + SDT_NAME_REG(rdx, dx), + SDT_NAME_REG(esi, si), + SDT_NAME_REG(rsi, si), + SDT_NAME_REG(edi, di), + SDT_NAME_REG(rdi, di), + SDT_NAME_REG(ebp, bp), + SDT_NAME_REG(rbp, bp), + SDT_NAME_REG_END, +}; diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index c4023f2..1c21150 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -6,6 +6,10 @@ const struct sample_reg __weak sample_reg_masks[] = { SMPL_REG_END }; +const struct sdt_name_reg __weak sdt_reg_renamings[] = { + SDT_NAME_REG_END, +}; + #ifdef HAVE_PERF_REGS_SUPPORT int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) { diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 679d6e4..41815ca 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -15,6 +15,19 @@ struct sample_reg { extern const struct sample_reg sample_reg_masks[]; +struct sdt_name_reg { + const char *sdt_name; + const char *uprobe_name; +}; +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} + +/* + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated + * registers before filling the uprobe tracer interface. + */ +extern const struct sdt_name_reg sdt_reg_renamings[]; + #ifdef HAVE_PERF_REGS_SUPPORT #include <perf_regs.h> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 436b647..587763d 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -27,6 +27,7 @@ #include "probe-event.h" #include "probe-file.h" #include "session.h" +#include "perf_regs.h" #define MAX_CMDLEN 256 @@ -687,6 +688,137 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) : (unsigned long long)note->addr.a64[0]; } +static const char * const type_to_suffix[] = { + ":s64", "", "", "", ":s32", "", ":s16", ":s8", + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" +}; + +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) +{ + const struct sdt_name_reg *rnames; + char *tmp, *desc = strdup(arg); + const char *suffix = ""; + int ret = -1; + + if (desc == NULL) { + pr_debug4("Allocation error\n"); + return ret; + } + + /* + * The uprobe tracer format does not support all the + * addressing modes (notably: in x86 the scaled mode); so, we + * detect ',' characters, if there is just one, there is no + * use converting the sdt arg into a uprobe one. + */ + if (strchr(desc, ',')) { + pr_debug4("SDT argument format not supported\n"); + goto out; + } + + tmp = strchr(desc, '@'); + if (tmp) { + long type_idx; + /* + * Isolate the string number and convert it into a + * binary value; this will be an index to get suffix + * of the uprobe name (defining the type) + */ + tmp[0] = '\0'; + type_idx = strtol(desc, NULL, 10); + if (type_idx == LONG_MIN || + type_idx == LONG_MAX) { + pr_debug4("Failed to get sdt type\n"); + goto error; + } + suffix = type_to_suffix[type_idx + 8]; + /* Get rid of the sdt prefix which is now useless */ + tmp++; + memmove(desc, tmp, strlen(tmp) + 1); + } + + /* + * The uprobe parser does not support all gas register names; + * so, we have to replace them (ex. for x86_64: %rax -> %ax); + * the loop below performs all the needed renamings if needed. + */ + + for (rnames = sdt_reg_renamings; rnames->sdt_name != NULL; rnames++) { + char *new_desc, *sdt_name; + size_t prefix_len, uprobe_len, mid_ofs, desc_len; + + sdt_name = strstr(desc, rnames->sdt_name); + if (sdt_name == NULL) + continue; + + new_desc = zalloc(strlen(desc) + 1 + + strlen(rnames->uprobe_name) - + strlen(rnames->sdt_name)); + if (new_desc == NULL) + goto error; + + prefix_len = sdt_name - desc; + if (prefix_len != 0) + memcpy(new_desc, desc, prefix_len); + + uprobe_len = strlen(rnames->uprobe_name); + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); + + mid_ofs = prefix_len + strlen(rnames->sdt_name); + desc_len = strlen(desc); + if (mid_ofs < desc_len) + memcpy(new_desc + prefix_len + uprobe_len, + desc + mid_ofs, desc_len - mid_ofs); + + free(desc); + desc = new_desc; + } + + if (strbuf_addf(buf, " arg%d=%s%s", i, desc, suffix) < 0) + goto error; + +out: + ret = 0; +error: + free(desc); + return ret; +} + +static char *synthesize_sdt_probe_command(struct sdt_note *note, + const char *pathname, + const char *sdtgrp) +{ + struct strbuf buf; + char *ret = NULL, **args; + int i, args_count; + + if (strbuf_init(&buf, 32) < 0) + return NULL; + + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", + sdtgrp, note->name, pathname, + sdt_note__get_addr(note)) < 0) + goto error; + + if (!note->args) + goto out; + + if (note->args) { + args = argv_split(note->args, &args_count); + + for (i = 0; i < args_count; ++i) { + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) + goto error; + } + } + +out: + ret = strbuf_detach(&buf, NULL); +error: + strbuf_release(&buf); + return ret; +} + int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) { struct probe_cache_entry *entry = NULL; @@ -723,11 +855,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) entry->pev.group = strdup(sdtgrp); list_add_tail(&entry->node, &pcache->entries); } - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", - sdtgrp, note->name, pathname, - sdt_note__get_addr(note)); - if (ret < 0) + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); + if (!buf) { + ret = -ENOMEM; break; + } + strlist__add(entry->tevlist, buf); free(buf); entry = NULL; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* Re: [PATCH v2 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-18 23:56 ` [PATCH v2 2/2] perf probe: add " Alexis Berlemont @ 2016-11-21 10:25 ` Hemant Kumar 2016-11-24 23:13 ` [PATCH v3 0/2] " Alexis Berlemont ` (2 more replies) 0 siblings, 3 replies; 77+ messages in thread From: Hemant Kumar @ 2016-11-21 10:25 UTC (permalink / raw) To: Alexis Berlemont, linux-kernel; +Cc: peterz, mingo, acme, alexander.shishkin Hi Alexis, On 11/19/2016 05:26 AM, Alexis Berlemont wrote: > An sdt probe can be associated with arguments but they were not passed > to the user probe tracing interface (uprobe_events); this patch adapts > the sdt argument descriptors according to the uprobe input format. > > As the uprobe parser does not support scaled address mode, perf will > skip arguments which cannot be adapted to the uprobe format. > > Here are the results: > > $ perf buildid-cache -v --add test_sdt > $ perf probe -x test_sdt sdt_libfoo:table_frob Working for some binaries and not working for others. On some digging, I think, this patchset doesn't take care of the offset sign. So, when we try to probe with these patches applied : # ./perf probe -x /lib64/libpthread.so.0 sdt_libpthread:pthread_start Failed to write event: Invalid argument Error: Failed to add events. With -v, the string to be written in uprobe_events is shown as : ... Writing event: p:sdt_libpthread/pthread_start /usr/lib64/libpthread-2.23.so:0x75b8 arg0=%ax:u64 arg1=1600(%ax):u64 arg2=1608(%ax):u64 ... The offsets mentioned in the string, for e.g., arg1=1600(%ax):u64 (to be written into the uprobe_events file don't have any sign. That is the issue here, i.e, we need to have a sign before the offsets. This works fine : # echo "p:sdt_libpthread/pthread_start /usr/lib64/libpthread-2.23.so:0x75b8 arg0=%ax:u64 arg1=+1600(%ax):u64 arg2=+1608(%ax):u64" > /sys/kernel/debug/tracing/uprobe_events For the negative offsets, i.e., '-' sign before the offsets, this works fine because, it takes the sign as is. So, we need to explicitly mention the offset sign. -- Thanks, Hemant Kumar > $ perf probe -x test_sdt sdt_libfoo:table_diddle > $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt > $ perf script > test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 > test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 > test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 > test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 > test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 > test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 > > Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> > --- > tools/perf/arch/x86/util/perf_regs.c | 18 +++++ > tools/perf/util/perf_regs.c | 4 + > tools/perf/util/perf_regs.h | 13 ++++ > tools/perf/util/probe-file.c | 141 ++++++++++++++++++++++++++++++++++- > 4 files changed, 172 insertions(+), 4 deletions(-) > > diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c > index c5db14f..52a1e65 100644 > --- a/tools/perf/arch/x86/util/perf_regs.c > +++ b/tools/perf/arch/x86/util/perf_regs.c > @@ -26,3 +26,21 @@ const struct sample_reg sample_reg_masks[] = { > #endif > SMPL_REG_END > }; > + > +const struct sdt_name_reg sdt_reg_renamings[] = { > + SDT_NAME_REG(eax, ax), > + SDT_NAME_REG(rax, ax), > + SDT_NAME_REG(ebx, bx), > + SDT_NAME_REG(rbx, bx), > + SDT_NAME_REG(ecx, cx), > + SDT_NAME_REG(rcx, cx), > + SDT_NAME_REG(edx, dx), > + SDT_NAME_REG(rdx, dx), > + SDT_NAME_REG(esi, si), > + SDT_NAME_REG(rsi, si), > + SDT_NAME_REG(edi, di), > + SDT_NAME_REG(rdi, di), > + SDT_NAME_REG(ebp, bp), > + SDT_NAME_REG(rbp, bp), > + SDT_NAME_REG_END, > +}; > diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c > index c4023f2..1c21150 100644 > --- a/tools/perf/util/perf_regs.c > +++ b/tools/perf/util/perf_regs.c > @@ -6,6 +6,10 @@ const struct sample_reg __weak sample_reg_masks[] = { > SMPL_REG_END > }; > > +const struct sdt_name_reg __weak sdt_reg_renamings[] = { > + SDT_NAME_REG_END, > +}; > + > #ifdef HAVE_PERF_REGS_SUPPORT > int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) > { > diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h > index 679d6e4..41815ca 100644 > --- a/tools/perf/util/perf_regs.h > +++ b/tools/perf/util/perf_regs.h > @@ -15,6 +15,19 @@ struct sample_reg { > > extern const struct sample_reg sample_reg_masks[]; > > +struct sdt_name_reg { > + const char *sdt_name; > + const char *uprobe_name; > +}; > +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} > +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} > + > +/* > + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated > + * registers before filling the uprobe tracer interface. > + */ > +extern const struct sdt_name_reg sdt_reg_renamings[]; > + > #ifdef HAVE_PERF_REGS_SUPPORT > #include <perf_regs.h> > > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index 436b647..587763d 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -27,6 +27,7 @@ > #include "probe-event.h" > #include "probe-file.h" > #include "session.h" > +#include "perf_regs.h" > > #define MAX_CMDLEN 256 > > @@ -687,6 +688,137 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) > : (unsigned long long)note->addr.a64[0]; > } > > +static const char * const type_to_suffix[] = { > + ":s64", "", "", "", ":s32", "", ":s16", ":s8", > + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" > +}; > + > +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) > +{ > + const struct sdt_name_reg *rnames; > + char *tmp, *desc = strdup(arg); > + const char *suffix = ""; > + int ret = -1; > + > + if (desc == NULL) { > + pr_debug4("Allocation error\n"); > + return ret; > + } > + > + /* > + * The uprobe tracer format does not support all the > + * addressing modes (notably: in x86 the scaled mode); so, we > + * detect ',' characters, if there is just one, there is no > + * use converting the sdt arg into a uprobe one. > + */ > + if (strchr(desc, ',')) { > + pr_debug4("SDT argument format not supported\n"); > + goto out; > + } > + > + tmp = strchr(desc, '@'); > + if (tmp) { > + long type_idx; > + /* > + * Isolate the string number and convert it into a > + * binary value; this will be an index to get suffix > + * of the uprobe name (defining the type) > + */ > + tmp[0] = '\0'; > + type_idx = strtol(desc, NULL, 10); > + if (type_idx == LONG_MIN || > + type_idx == LONG_MAX) { > + pr_debug4("Failed to get sdt type\n"); > + goto error; > + } > + suffix = type_to_suffix[type_idx + 8]; > + /* Get rid of the sdt prefix which is now useless */ > + tmp++; > + memmove(desc, tmp, strlen(tmp) + 1); > + } > + > + /* > + * The uprobe parser does not support all gas register names; > + * so, we have to replace them (ex. for x86_64: %rax -> %ax); > + * the loop below performs all the needed renamings if needed. > + */ > + > + for (rnames = sdt_reg_renamings; rnames->sdt_name != NULL; rnames++) { > + char *new_desc, *sdt_name; > + size_t prefix_len, uprobe_len, mid_ofs, desc_len; > + > + sdt_name = strstr(desc, rnames->sdt_name); > + if (sdt_name == NULL) > + continue; > + > + new_desc = zalloc(strlen(desc) + 1 + > + strlen(rnames->uprobe_name) - > + strlen(rnames->sdt_name)); > + if (new_desc == NULL) > + goto error; > + > + prefix_len = sdt_name - desc; > + if (prefix_len != 0) > + memcpy(new_desc, desc, prefix_len); > + > + uprobe_len = strlen(rnames->uprobe_name); > + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); > + > + mid_ofs = prefix_len + strlen(rnames->sdt_name); > + desc_len = strlen(desc); > + if (mid_ofs < desc_len) > + memcpy(new_desc + prefix_len + uprobe_len, > + desc + mid_ofs, desc_len - mid_ofs); > + > + free(desc); > + desc = new_desc; > + } > + > + if (strbuf_addf(buf, " arg%d=%s%s", i, desc, suffix) < 0) > + goto error; > + > +out: > + ret = 0; > +error: > + free(desc); > + return ret; > +} > + > +static char *synthesize_sdt_probe_command(struct sdt_note *note, > + const char *pathname, > + const char *sdtgrp) > +{ > + struct strbuf buf; > + char *ret = NULL, **args; > + int i, args_count; > + > + if (strbuf_init(&buf, 32) < 0) > + return NULL; > + > + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", > + sdtgrp, note->name, pathname, > + sdt_note__get_addr(note)) < 0) > + goto error; > + > + if (!note->args) > + goto out; > + > + if (note->args) { > + args = argv_split(note->args, &args_count); > + > + for (i = 0; i < args_count; ++i) { > + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) > + goto error; > + } > + } > + > +out: > + ret = strbuf_detach(&buf, NULL); > +error: > + strbuf_release(&buf); > + return ret; > +} > + > int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > { > struct probe_cache_entry *entry = NULL; > @@ -723,11 +855,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) > entry->pev.group = strdup(sdtgrp); > list_add_tail(&entry->node, &pcache->entries); > } > - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", > - sdtgrp, note->name, pathname, > - sdt_note__get_addr(note)); > - if (ret < 0) > + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); > + if (!buf) { > + ret = -ENOMEM; > break; > + } > + > strlist__add(entry->tevlist, buf); > free(buf); > entry = NULL; ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v3 0/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-21 10:25 ` Hemant Kumar @ 2016-11-24 23:13 ` Alexis Berlemont 2016-11-24 23:13 ` [PATCH v3 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2016-11-24 23:13 ` [PATCH v3 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2 siblings, 0 replies; 77+ messages in thread From: Alexis Berlemont @ 2016-11-24 23:13 UTC (permalink / raw) To: linux-kernel Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin, hemant Hi Hemant, Once more thank you for your answer. Sorry for this bug: I tested the patches only on small sample binaries. Now it is tested against the systemtap-enabled libraries libc and libpthread. There were 2 problems: * The one you disclosed: in indirect addressing mode, positive offsets not prefixed with a '+' character; * Another one still in indirect addressing mode: offsets which were not constants but symbols; The following patches solves them both. # cat /sys/kernel/tracing/uprobe_events p:sdt_libpthread/pthread_start /lib/libpthread-2.23.so:0x0000000000007448 arg0=%ax:u64 arg1=+1600(%ax):u64 arg2=+1608(%ax):u64 p:sdt_libpthread/pthread_create /lib/libpthread-2.23.so:0x0000000000007be9 arg0=%ax:u64 arg1=-184(%bp):u64 arg2=-160(%bp):u64 arg3=-168(%bp):u64 p:sdt_libpthread/pthread_join /lib/libpthread-2.23.so:0x000000000000864d arg0=%di:u64 p:sdt_libpthread/pthread_join_ret /lib/libpthread-2.23.so:0x00000000000086fe arg0=%bx:u64 arg1=%ax:s32 arg2=+1584(%bx):u64 p:sdt_libpthread/mutex_init /lib/libpthread-2.23.so:0x000000000000938b arg0=%di:u64 p:sdt_libpthread/mutex_destroy /lib/libpthread-2.23.so:0x0000000000009410 arg0=%di:u64 p:sdt_libpthread/mutex_acquired /lib/libpthread-2.23.so:0x0000000000009685 arg0=%bx:u64 p:sdt_libpthread/mutex_acquired_1 /lib/libpthread-2.23.so:0x0000000000009b31 arg0=%r8:u64 ... # cat /sys/kernel/tracing/uprobe_events p:sdt_libc/setjmp /lib/libc-2.23.so:0x0000000000033181 arg0=%di:u64 arg1=%si:s32 arg2=%ax:u64 p:sdt_libc/longjmp /lib/libc-2.23.so:0x0000000000033263 arg0=%di:u64 arg1=%si:s32 arg2=%dx:u64 p:sdt_libc/longjmp_1 /lib/libc-2.23.so:0x00000000000f7fc3 arg0=%di:u64 arg1=%si:s32 arg2=%dx:u64 p:sdt_libc/longjmp_target /lib/libc-2.23.so:0x000000000003327f arg0=%di:u64 arg1=%ax:s32 arg2=%dx:u64 p:sdt_libc/longjmp_target_1 /lib/libc-2.23.so:0x00000000000f7fdf arg0=%di:u64 arg1=%ax:s32 arg2=%dx:u64 ... Thanks, Alexis. Alexis Berlemont (2): perf sdt: add scanning of sdt probles arguments perf probe: add sdt probes arguments into the uprobe cmd string tools/perf/arch/x86/util/perf_regs.c | 18 ++++ tools/perf/util/perf_regs.c | 4 + tools/perf/util/perf_regs.h | 13 +++ tools/perf/util/probe-file.c | 169 ++++++++++++++++++++++++++++++++++- tools/perf/util/symbol-elf.c | 16 +++- tools/perf/util/symbol.h | 1 + 6 files changed, 216 insertions(+), 5 deletions(-) -- 2.10.2 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v3 1/2] perf sdt: add scanning of sdt probles arguments 2016-11-21 10:25 ` Hemant Kumar 2016-11-24 23:13 ` [PATCH v3 0/2] " Alexis Berlemont @ 2016-11-24 23:13 ` Alexis Berlemont 2016-11-24 23:13 ` [PATCH v3 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2 siblings, 0 replies; 77+ messages in thread From: Alexis Berlemont @ 2016-11-24 23:13 UTC (permalink / raw) To: linux-kernel Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin, hemant During a "perf buildid-cache --add" command, the section ".note.stapsdt" of the "added" binary is scanned in order to list the available SDT markers available in a binary. The parts containing the probes arguments were left unscanned. The whole section is now parsed; the probe arguments are extracted for later use. Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/util/symbol-elf.c | 16 +++++++++++++++- tools/perf/util/symbol.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 99400b0..0fbe0b2 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1822,7 +1822,7 @@ void kcore_extract__delete(struct kcore_extract *kce) static int populate_sdt_note(Elf **elf, const char *data, size_t len, struct list_head *sdt_notes) { - const char *provider, *name; + const char *provider, *name, *args; struct sdt_note *tmp = NULL; GElf_Ehdr ehdr; GElf_Addr base_off = 0; @@ -1881,6 +1881,20 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, goto out_free_prov; } + args = (const char *)memchr(name, '\0', data + len - name); + + /* + * There is no argument if: + * - We reached the end of the note; + * - There is not enough room to hold a potential string; + * - The argument string is empty or just contains ':'. + */ + if (args == NULL || data + len - args < 2 || + args[1] == ':' || args[1] == '\0') + tmp->args = NULL; + else + tmp->args = strdup(++args); + if (gelf_getclass(*elf) == ELFCLASS32) { memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr)); tmp->bit32 = true; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2d0a905..913be07 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -347,6 +347,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); struct sdt_note { char *name; /* name of the note*/ char *provider; /* provider name */ + char *args; bool bit32; /* whether the location is 32 bits? */ union { /* location, base and semaphore addrs */ Elf64_Addr a64[3]; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
* [PATCH v3 2/2] perf probe: add sdt probes arguments into the uprobe cmd string 2016-11-21 10:25 ` Hemant Kumar 2016-11-24 23:13 ` [PATCH v3 0/2] " Alexis Berlemont 2016-11-24 23:13 ` [PATCH v3 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont @ 2016-11-24 23:13 ` Alexis Berlemont 2 siblings, 0 replies; 77+ messages in thread From: Alexis Berlemont @ 2016-11-24 23:13 UTC (permalink / raw) To: linux-kernel Cc: Alexis Berlemont, peterz, mingo, acme, alexander.shishkin, hemant An sdt probe can be associated with arguments but they were not passed to the user probe tracing interface (uprobe_events); this patch adapts the sdt argument descriptors according to the uprobe input format. As the uprobe parser does not support scaled address mode, perf will skip arguments which cannot be adapted to the uprobe format. Here are the results: $ perf buildid-cache -v --add test_sdt $ perf probe -x test_sdt sdt_libfoo:table_frob $ perf probe -x test_sdt sdt_libfoo:table_diddle $ perf record -e sdt_libfoo:table_frob -e sdt_libfoo:table_diddle test_sdt $ perf script test_sdt ... 666.255678: sdt_libfoo:table_frob: (4004d7) arg0=0 arg1=0 test_sdt ... 666.255683: sdt_libfoo:table_diddle: (40051a) arg0=0 arg1=0 test_sdt ... 666.255686: sdt_libfoo:table_frob: (4004d7) arg0=1 arg1=2 test_sdt ... 666.255689: sdt_libfoo:table_diddle: (40051a) arg0=3 arg1=4 test_sdt ... 666.255692: sdt_libfoo:table_frob: (4004d7) arg0=2 arg1=4 test_sdt ... 666.255694: sdt_libfoo:table_diddle: (40051a) arg0=6 arg1=8 Signed-off-by: Alexis Berlemont <alexis.berlemont@gmail.com> --- tools/perf/arch/x86/util/perf_regs.c | 18 ++++ tools/perf/util/perf_regs.c | 4 + tools/perf/util/perf_regs.h | 13 +++ tools/perf/util/probe-file.c | 169 ++++++++++++++++++++++++++++++++++- 4 files changed, 200 insertions(+), 4 deletions(-) diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index c5db14f..52a1e65 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -26,3 +26,21 @@ const struct sample_reg sample_reg_masks[] = { #endif SMPL_REG_END }; + +const struct sdt_name_reg sdt_reg_renamings[] = { + SDT_NAME_REG(eax, ax), + SDT_NAME_REG(rax, ax), + SDT_NAME_REG(ebx, bx), + SDT_NAME_REG(rbx, bx), + SDT_NAME_REG(ecx, cx), + SDT_NAME_REG(rcx, cx), + SDT_NAME_REG(edx, dx), + SDT_NAME_REG(rdx, dx), + SDT_NAME_REG(esi, si), + SDT_NAME_REG(rsi, si), + SDT_NAME_REG(edi, di), + SDT_NAME_REG(rdi, di), + SDT_NAME_REG(ebp, bp), + SDT_NAME_REG(rbp, bp), + SDT_NAME_REG_END, +}; diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index c4023f2..1c21150 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -6,6 +6,10 @@ const struct sample_reg __weak sample_reg_masks[] = { SMPL_REG_END }; +const struct sdt_name_reg __weak sdt_reg_renamings[] = { + SDT_NAME_REG_END, +}; + #ifdef HAVE_PERF_REGS_SUPPORT int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) { diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 679d6e4..41815ca 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -15,6 +15,19 @@ struct sample_reg { extern const struct sample_reg sample_reg_masks[]; +struct sdt_name_reg { + const char *sdt_name; + const char *uprobe_name; +}; +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} + +/* + * The table sdt_reg_renamings is used for adjusting gcc/gas-generated + * registers before filling the uprobe tracer interface. + */ +extern const struct sdt_name_reg sdt_reg_renamings[]; + #ifdef HAVE_PERF_REGS_SUPPORT #include <perf_regs.h> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 436b647..75033c7 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -27,6 +27,7 @@ #include "probe-event.h" #include "probe-file.h" #include "session.h" +#include "perf_regs.h" #define MAX_CMDLEN 256 @@ -687,6 +688,165 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note) : (unsigned long long)note->addr.a64[0]; } +static const char * const type_to_suffix[] = { + ":s64", "", "", "", ":s32", "", ":s16", ":s8", + "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" +}; + +static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) +{ + const struct sdt_name_reg *rnames; + char *tmp, *desc = strdup(arg); + const char *prefix = "", *suffix = ""; + int ret = -1; + + if (desc == NULL) { + pr_debug4("Allocation error\n"); + return ret; + } + + tmp = strchr(desc, '@'); + if (tmp) { + long type_idx; + /* + * Isolate the string number and convert it into a + * binary value; this will be an index to get suffix + * of the uprobe name (defining the type) + */ + tmp[0] = '\0'; + type_idx = strtol(desc, NULL, 10); + if (type_idx == LONG_MIN || + type_idx == LONG_MAX) { + pr_debug4("Failed to get sdt type\n"); + goto error; + } + suffix = type_to_suffix[type_idx + 8]; + /* Get rid of the sdt prefix which is now useless */ + tmp++; + memmove(desc, tmp, strlen(tmp) + 1); + } + + /* + * The uprobe tracer format does not support all the + * addressing modes (notably: in x86 the scaled mode); so, we + * detect ',' characters, if there is just one, there is no + * use converting the sdt arg into a uprobe one. + */ + if (strchr(desc, ',')) { + pr_debug4("SDT argument format not supported\n"); + goto out; + } + + /* + * If the argument addressing mode is indirect, we must check + * a few things... + */ + tmp = strchr(desc, '('); + if (tmp) { + int j; + + /* + * ...if the addressing mode is indirect with a + * positive offset (ex.: "1608(%ax)"), we need to add + * a '+' prefix so as to be compliant with uprobe + * format. + */ + if (desc[0] != '+' && desc[0] != '-') + prefix = "+"; + + /* + * ...or if the addressing mode is indirect with a symbol + * as offset, the argument will not be supported by + * the uprobe tracer format; so, let's skip this one. + */ + for (j = 0; j < tmp - desc; j++) { + if (desc[j] != '+' && desc[j] != '-' && + !isdigit(desc[j])) + goto out; + } + } + + /* + * The uprobe parser does not support all gas register names; + * so, we have to replace them (ex. for x86_64: %rax -> %ax); + * the loop below performs all the needed renamings if needed. + */ + for (rnames = sdt_reg_renamings; rnames->sdt_name != NULL; rnames++) { + char *new_desc, *sdt_name; + size_t prefix_len, uprobe_len, mid_ofs, desc_len; + + sdt_name = strstr(desc, rnames->sdt_name); + if (sdt_name == NULL) + continue; + + new_desc = zalloc(strlen(desc) + 1 + + strlen(rnames->uprobe_name) - + strlen(rnames->sdt_name)); + if (new_desc == NULL) + goto error; + + prefix_len = sdt_name - desc; + if (prefix_len != 0) + memcpy(new_desc, desc, prefix_len); + + uprobe_len = strlen(rnames->uprobe_name); + memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); + + mid_ofs = prefix_len + strlen(rnames->sdt_name); + desc_len = strlen(desc); + if (mid_ofs < desc_len) + memcpy(new_desc + prefix_len + uprobe_len, + desc + mid_ofs, desc_len - mid_ofs); + + free(desc); + desc = new_desc; + } + + if (strbuf_addf(buf, " arg%d=%s%s%s", i, prefix, desc, suffix) < 0) + goto error; + +out: + ret = 0; +error: + free(desc); + return ret; +} + +static char *synthesize_sdt_probe_command(struct sdt_note *note, + const char *pathname, + const char *sdtgrp) +{ + struct strbuf buf; + char *ret = NULL, **args; + int i, args_count; + + if (strbuf_init(&buf, 32) < 0) + return NULL; + + if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx", + sdtgrp, note->name, pathname, + sdt_note__get_addr(note)) < 0) + goto error; + + if (!note->args) + goto out; + + if (note->args) { + args = argv_split(note->args, &args_count); + + for (i = 0; i < args_count; ++i) { + if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) + goto error; + } + } + +out: + ret = strbuf_detach(&buf, NULL); +error: + strbuf_release(&buf); + return ret; +} + int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) { struct probe_cache_entry *entry = NULL; @@ -723,11 +883,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) entry->pev.group = strdup(sdtgrp); list_add_tail(&entry->node, &pcache->entries); } - ret = asprintf(&buf, "p:%s/%s %s:0x%llx", - sdtgrp, note->name, pathname, - sdt_note__get_addr(note)); - if (ret < 0) + buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); + if (!buf) { + ret = -ENOMEM; break; + } + strlist__add(entry->tevlist, buf); free(buf); entry = NULL; -- 2.10.2 ^ permalink raw reply related [flat|nested] 77+ messages in thread
end of thread, other threads:[~2017-03-24 18:52 UTC | newest] Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-11-16 23:55 [PATCH 0/2] perf: add support of SDT probes arguments Alexis Berlemont 2016-11-16 23:56 ` [PATCH 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2016-11-16 23:56 ` [PATCH 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2016-11-17 9:04 ` Hemant Kumar 2016-11-18 23:56 ` [PATCH v2 0/2] " Alexis Berlemont 2016-11-18 23:56 ` [PATCH v2 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2016-11-25 14:40 ` Arnaldo Carvalho de Melo 2016-11-26 0:58 ` [PATCH v4 0/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2016-12-05 23:42 ` Alexis Berlemont 2016-12-06 14:45 ` Arnaldo Carvalho de Melo 2016-11-26 0:58 ` [PATCH v4 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2016-12-07 2:44 ` Masami Hiramatsu 2016-11-26 0:58 ` [PATCH v4 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2016-12-07 3:26 ` Masami Hiramatsu 2016-12-09 15:14 ` Arnaldo Carvalho de Melo 2016-12-10 10:00 ` Masami Hiramatsu 2016-12-14 0:07 ` [PATCH v5 0/2] " Alexis Berlemont 2016-12-14 7:36 ` Ingo Molnar 2017-01-23 11:23 ` Ravi Bangoria 2017-02-22 22:41 ` Alexis Berlemont 2017-01-24 6:58 ` Ravi Bangoria 2017-01-24 8:22 ` Ingo Molnar 2017-01-24 8:36 ` Ravi Bangoria 2017-02-02 11:11 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Ravi Bangoria 2017-02-02 11:11 ` [PATCH 1/5] perf/sdt: Show proper hint Ravi Bangoria 2017-02-02 13:40 ` Ingo Molnar 2017-02-02 16:20 ` Arnaldo Carvalho de Melo 2017-02-03 10:26 ` [PATCH v2] " Ravi Bangoria 2017-02-03 15:18 ` Arnaldo Carvalho de Melo 2017-02-07 7:53 ` Ingo Molnar 2017-02-07 15:50 ` Arnaldo Carvalho de Melo 2017-02-07 8:00 ` Ingo Molnar 2017-02-16 10:16 ` [RFC] perf/sdt: Directly record SDT event with 'perf record' Ravi Bangoria 2017-02-20 7:08 ` Ingo Molnar 2017-02-20 8:21 ` Ravi Bangoria 2017-02-20 8:42 ` Ingo Molnar 2017-02-20 11:01 ` Ravi Bangoria 2017-02-20 14:11 ` Arnaldo Carvalho de Melo 2017-02-23 8:13 ` Ravi Bangoria 2017-02-23 12:48 ` Arnaldo Carvalho de Melo 2017-02-07 1:13 ` [PATCH v2] perf/sdt: Show proper hint Masami Hiramatsu 2017-02-10 7:44 ` [tip:perf/core] perf sdt: Show proper hint when event not yet in place via 'perf probe' tip-bot for Ravi Bangoria 2017-02-02 11:11 ` [PATCH 2/5] perf/sdt/x86: Add renaming logic for rNN and other registers Ravi Bangoria 2017-02-07 3:11 ` Masami Hiramatsu 2017-03-21 14:08 ` Arnaldo Carvalho de Melo 2017-03-24 18:45 ` [tip:perf/core] perf sdt x86: " tip-bot for Ravi Bangoria 2017-02-02 11:11 ` [PATCH 3/5] perf/sdt/x86: Move OP parser to tools/perf/arch/x86/ Ravi Bangoria 2017-02-07 3:11 ` Masami Hiramatsu 2017-02-07 5:22 ` Ravi Bangoria 2017-03-21 14:10 ` Arnaldo Carvalho de Melo 2017-03-21 23:00 ` Masami Hiramatsu 2017-03-22 11:22 ` Arnaldo Carvalho de Melo 2017-03-21 14:55 ` Masami Hiramatsu 2017-02-02 11:11 ` [PATCH 4/5] perf/sdt/powerpc: Add argument support Ravi Bangoria 2017-02-02 11:11 ` [PATCH 5/5] perf/probe: Change MAX_CMDLEN Ravi Bangoria 2017-02-07 1:40 ` Masami Hiramatsu 2017-02-07 5:45 ` [PATCH v2] " Ravi Bangoria 2017-03-21 5:19 ` Masami Hiramatsu 2017-03-21 13:37 ` Arnaldo Carvalho de Melo 2017-03-24 18:43 ` [tip:perf/core] perf probe: " tip-bot for Ravi Bangoria 2017-02-07 2:55 ` [PATCH 0/5] perf/sdt: Argument support for x86 and powepc Masami Hiramatsu 2017-03-06 7:53 ` Ravi Bangoria 2017-03-06 13:42 ` Masami Hiramatsu 2017-03-21 5:08 ` [PATCH v5 0/2] perf probe: add sdt probes arguments into the uprobe cmd string Masami Hiramatsu 2016-12-14 0:07 ` [PATCH v5 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2017-03-06 13:39 ` Masami Hiramatsu 2017-03-21 13:52 ` Arnaldo Carvalho de Melo 2017-03-24 18:44 ` [tip:perf/core] perf sdt: Add scanning of sdt probes arguments tip-bot for Alexis Berlemont 2016-12-14 0:07 ` [PATCH v5 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont 2017-01-24 8:50 ` Ravi Bangoria 2017-03-06 17:23 ` Masami Hiramatsu 2017-03-24 18:44 ` [tip:perf/core] perf probe: Add " tip-bot for Alexis Berlemont 2016-11-18 23:56 ` [PATCH v2 2/2] perf probe: add " Alexis Berlemont 2016-11-21 10:25 ` Hemant Kumar 2016-11-24 23:13 ` [PATCH v3 0/2] " Alexis Berlemont 2016-11-24 23:13 ` [PATCH v3 1/2] perf sdt: add scanning of sdt probles arguments Alexis Berlemont 2016-11-24 23:13 ` [PATCH v3 2/2] perf probe: add sdt probes arguments into the uprobe cmd string Alexis Berlemont
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).