Message ID | 1473978296-20712-7-git-send-email-sukadev@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu: > From: Andi Kleen <ak@linux.intel.com> > > Add support to print alias descriptions in perf list, which > are taken from the generated event files. > > The sorting code is changed to put the events with descriptions > at the end. The descriptions are printed as possibly multiple word > wrapped lines. So, now I'm trying to reproduce the results below, but I couldn't find a tarball with those .json files for me to use, can you provide me with one? I've put what I have at: git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tmp.perf/json Now testing Jiri's cross compiling patch... Thanks, - Arnaldo > Example output: > > % perf list > ... > arith.fpu_div > [Divide operations executed] > arith.fpu_div_active > [Cycles when divider is busy executing divide operations] > > Signed-off-by: Andi Kleen <ak@linux.intel.com> > Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> > Acked-by: Jiri Olsa <jolsa@redhat.com> > Acked-by: Ingo Molnar <mingo@kernel.org> > --- > > Changelog > - Delete a redundant free() > > Changelog[v14] > - [Jiri Olsa] Fail, rather than continue if strdup() returns NULL; > remove unnecessary __maybe_unused. > --- > tools/perf/util/pmu.c | 83 +++++++++++++++++++++++++++++++++++++++++---------- > tools/perf/util/pmu.h | 1 + > 2 files changed, 68 insertions(+), 16 deletions(-) > > diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c > index c842886..af1a612 100644 > --- a/tools/perf/util/pmu.c > +++ b/tools/perf/util/pmu.c > @@ -222,7 +222,7 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, > } > > static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, > - char *desc __maybe_unused, char *val) > + char *desc, char *val) > { > struct perf_pmu_alias *alias; > int ret; > @@ -255,6 +255,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, > perf_pmu__parse_snapshot(alias, dir, name); > } > > + alias->desc = desc ? strdup(desc) : NULL; > + > list_add_tail(&alias->list, list); > > return 0; > @@ -1044,11 +1046,42 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, > return buf; > } > > -static int cmp_string(const void *a, const void *b) > +struct pair { > + char *name; > + char *desc; > +}; > + > +static int cmp_pair(const void *a, const void *b) > +{ > + const struct pair *as = a; > + const struct pair *bs = b; > + > + /* Put extra events last */ > + if (!!as->desc != !!bs->desc) > + return !!as->desc - !!bs->desc; > + return strcmp(as->name, bs->name); > +} > + > +static void wordwrap(char *s, int start, int max, int corr) > { > - const char * const *as = a; > - const char * const *bs = b; > - return strcmp(*as, *bs); > + int column = start; > + int n; > + > + while (*s) { > + int wlen = strcspn(s, " \t"); > + > + if (column + wlen >= max && column > start) { > + printf("\n%*s", start, ""); > + column = start + corr; > + } > + n = printf("%s%.*s", column > start ? " " : "", wlen, s); > + if (n <= 0) > + break; > + s += wlen; > + column += n; > + while (isspace(*s)) > + s++; > + } > } > > void print_pmu_events(const char *event_glob, bool name_only) > @@ -1058,7 +1091,9 @@ void print_pmu_events(const char *event_glob, bool name_only) > char buf[1024]; > int printed = 0; > int len, j; > - char **aliases; > + struct pair *aliases; > + int numdesc = 0; > + int columns = 78; > > pmu = NULL; > len = 0; > @@ -1068,14 +1103,15 @@ void print_pmu_events(const char *event_glob, bool name_only) > if (pmu->selectable) > len++; > } > - aliases = zalloc(sizeof(char *) * len); > + aliases = zalloc(sizeof(struct pair) * len); > if (!aliases) > goto out_enomem; > pmu = NULL; > j = 0; > while ((pmu = perf_pmu__scan(pmu)) != NULL) { > list_for_each_entry(alias, &pmu->aliases, list) { > - char *name = format_alias(buf, sizeof(buf), pmu, alias); > + char *name = alias->desc ? alias->name : > + format_alias(buf, sizeof(buf), pmu, alias); > bool is_cpu = !strcmp(pmu->name, "cpu"); > > if (event_glob != NULL && > @@ -1084,12 +1120,19 @@ void print_pmu_events(const char *event_glob, bool name_only) > event_glob)))) > continue; > > - if (is_cpu && !name_only) > + if (is_cpu && !name_only && !alias->desc) > name = format_alias_or(buf, sizeof(buf), pmu, alias); > > - aliases[j] = strdup(name); > - if (aliases[j] == NULL) > + aliases[j].name = name; > + if (is_cpu && !name_only && !alias->desc) > + aliases[j].name = format_alias_or(buf, > + sizeof(buf), > + pmu, alias); > + aliases[j].name = strdup(aliases[j].name); > + if (!aliases[j].name) > goto out_enomem; > + > + aliases[j].desc = alias->desc; > j++; > } > if (pmu->selectable && > @@ -1097,25 +1140,33 @@ void print_pmu_events(const char *event_glob, bool name_only) > char *s; > if (asprintf(&s, "%s//", pmu->name) < 0) > goto out_enomem; > - aliases[j] = s; > + aliases[j].name = s; > j++; > } > } > len = j; > - qsort(aliases, len, sizeof(char *), cmp_string); > + qsort(aliases, len, sizeof(struct pair), cmp_pair); > for (j = 0; j < len; j++) { > if (name_only) { > - printf("%s ", aliases[j]); > + printf("%s ", aliases[j].name); > continue; > } > - printf(" %-50s [Kernel PMU event]\n", aliases[j]); > + if (aliases[j].desc) { > + if (numdesc++ == 0) > + printf("\n"); > + printf(" %-50s\n", aliases[j].name); > + printf("%*s", 8, "["); > + wordwrap(aliases[j].desc, 8, columns, 0); > + printf("]\n"); > + } else > + printf(" %-50s [Kernel PMU event]\n", aliases[j].name); > printed++; > } > if (printed && pager_in_use()) > printf("\n"); > out_free: > for (j = 0; j < len; j++) > - zfree(&aliases[j]); > + zfree(&aliases[j].name); > zfree(&aliases); > return; > > diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h > index 5d7e844..11bda57 100644 > --- a/tools/perf/util/pmu.h > +++ b/tools/perf/util/pmu.h > @@ -38,6 +38,7 @@ struct perf_pmu_info { > > struct perf_pmu_alias { > char *name; > + char *desc; > struct list_head terms; /* HEAD struct parse_events_term -> list */ > struct list_head list; /* ELEM */ > char unit[UNIT_MAX_LEN+1]; > -- > 1.8.3.1
Arnaldo Carvalho de Melo [acme@kernel.org] wrote: > Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu: > > From: Andi Kleen <ak@linux.intel.com> > > > > Add support to print alias descriptions in perf list, which > > are taken from the generated event files. > > > > The sorting code is changed to put the events with descriptions > > at the end. The descriptions are printed as possibly multiple word > > wrapped lines. > > So, now I'm trying to reproduce the results below, but I couldn't find a > tarball with those .json files for me to use, can you provide me with > one? The data files are in my github, in the json-code+data-v21 branch starting with 23bb101. They are individual commits rather than a tarball though. > https://github.com/sukadev/linux.git > > Branch Description > ------------------------------------------------------ > json-code-v21 Source Code only > json-code+data-v21 Both code and data(for build/test/pull) > Sukadev
Em Tue, Sep 27, 2016 at 11:11:16AM -0700, Sukadev Bhattiprolu escreveu: > Arnaldo Carvalho de Melo [acme@kernel.org] wrote: > > Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu: > > > From: Andi Kleen <ak@linux.intel.com> > > > Add support to print alias descriptions in perf list, which > > > are taken from the generated event files. > > > > > > The sorting code is changed to put the events with descriptions > > > at the end. The descriptions are printed as possibly multiple word > > > wrapped lines. > > > > So, now I'm trying to reproduce the results below, but I couldn't find a > > tarball with those .json files for me to use, can you provide me with > > one? > > The data files are in my github, in the json-code+data-v21 branch > starting with 23bb101. They are individual commits rather than a > tarball though. Ok, I'll pick one for powerpc and another for x86_64 so that I can test it and Jiri's x-compile support. Refresh my mind, what is the plan on these files? Are we just going to provide pointers to where to get them from vendors, ship it in the kernel, auto-download them as part of the build process? At least examples that allows to build and have a new 'perf test' entry to check them automatically seems to be in order, no? - Arnaldo > > https://github.com/sukadev/linux.git > > > > Branch Description > > ------------------------------------------------------ > > json-code-v21 Source Code only > > json-code+data-v21 Both code and data(for build/test/pull) > > > > Sukadev
Arnaldo Carvalho de Melo [acme@kernel.org] wrote: > Em Tue, Sep 27, 2016 at 11:11:16AM -0700, Sukadev Bhattiprolu escreveu: > > Arnaldo Carvalho de Melo [acme@kernel.org] wrote: > > > Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu: > > > > From: Andi Kleen <ak@linux.intel.com> > > > > Add support to print alias descriptions in perf list, which > > > > are taken from the generated event files. > > > > > > > > The sorting code is changed to put the events with descriptions > > > > at the end. The descriptions are printed as possibly multiple word > > > > wrapped lines. > > > > > > So, now I'm trying to reproduce the results below, but I couldn't find a > > > tarball with those .json files for me to use, can you provide me with > > > one? > > > > The data files are in my github, in the json-code+data-v21 branch > > starting with 23bb101. They are individual commits rather than a > > tarball though. > > Ok, I'll pick one for powerpc and another for x86_64 so that I can test > it and Jiri's x-compile support. Please pull all files if possible, specially on x86, _before_ building the perf binary. If you are going to pull only one, you need to make sure that the file you pull matches the CPU model on the system you are testing.(see below). For Power, you need to test on Power8. > > Refresh my mind, what is the plan on these files? Are we just going to > provide pointers to where to get them from vendors, ship it in the > kernel, auto-download them as part of the build process? They are supposed to be committed into the linux kernel tree as shown in the json-code+data-v21 tree and they will be picked up _during build_ of the perf binary. (We are just not mailing those data files as patches since they are large and there is very little value in reviewing them). When building perf on on say x86, event tables for all the different x86 CPU models will be included in the perf binary. When perf is then executed on an x86 box, it will detect the CPU model of that box and use the set of events corresponding to that model. If the CPU model does not match the models "known" to the perf binary, then the symbolic names will not work on that system, but there should be no other change in behavior. Patch 15/19 tries to explain the process. > > At least examples that allows to build and have a new 'perf test' entry > to check them automatically seems to be in order, no? Well, the hope was that build/usage will be transparent! but we did not test in the cross-compile environment. Will think about a test case. Please let me know if we can update the README in Patch 15/19 in any way. > > - Arnaldo > > > > https://github.com/sukadev/linux.git > > > > > > Branch Description > > > ------------------------------------------------------ > > > json-code-v21 Source Code only > > > json-code+data-v21 Both code and data(for build/test/pull) > > > > > > > Sukadev
Em Wed, Sep 28, 2016 at 11:29:16AM -0700, Sukadev Bhattiprolu escreveu: > Arnaldo Carvalho de Melo [acme@kernel.org] wrote: > > Em Tue, Sep 27, 2016 at 11:11:16AM -0700, Sukadev Bhattiprolu escreveu: > > > Arnaldo Carvalho de Melo [acme@kernel.org] wrote: > > > > Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu: > > > > > From: Andi Kleen <ak@linux.intel.com> > > > > > Add support to print alias descriptions in perf list, which > > > > > are taken from the generated event files. > > > > > > > > > > The sorting code is changed to put the events with descriptions > > > > > at the end. The descriptions are printed as possibly multiple word > > > > > wrapped lines. > > > > > > > > So, now I'm trying to reproduce the results below, but I couldn't find a > > > > tarball with those .json files for me to use, can you provide me with > > > > one? > > > > > > The data files are in my github, in the json-code+data-v21 branch > > > starting with 23bb101. They are individual commits rather than a > > > tarball though. > > > > Ok, I'll pick one for powerpc and another for x86_64 so that I can test > > it and Jiri's x-compile support. > > Please pull all files if possible, specially on x86, _before_ building the > perf binary. If you are going to pull only one, you need to make sure that > the file you pull matches the CPU model on the system you are testing.(see > below). For Power, you need to test on Power8. > > > > > Refresh my mind, what is the plan on these files? Are we just going to > > provide pointers to where to get them from vendors, ship it in the > > kernel, auto-download them as part of the build process? > > They are supposed to be committed into the linux kernel tree as shown > in the json-code+data-v21 tree and they will be picked up _during build_ > of the perf binary. (We are just not mailing those data files as patches > since they are large and there is very little value in reviewing them). > > When building perf on on say x86, event tables for all the different > x86 CPU models will be included in the perf binary. When perf is then > executed on an x86 box, it will detect the CPU model of that box and > use the set of events corresponding to that model. > > If the CPU model does not match the models "known" to the perf binary, > then the symbolic names will not work on that system, but there should > be no other change in behavior. > > Patch 15/19 tries to explain the process. I didn't get to that one yet. > > At least examples that allows to build and have a new 'perf test' entry > > to check them automatically seems to be in order, no? > > Well, the hope was that build/usage will be transparent! but we did not the 'perf test' entry is to test the whole process of going from a json file to a the perf binary and then asking for one such event and checking if the resulting perf_event_attr is what we expect it to be, see, for instance: [root@jouet c]# perf test roundtrip 11: roundtrip evsel->name check : Ok tools/perf/tests/evsel-roundtrip-name.c > test in the cross-compile environment. Will think about a test case. > Please let me know if we can update the README in Patch 15/19 in any > way. I'll let you know when I get to that patch, till then I'll follow the instructions you gave me here. I.e. I go on testing patch by patch, trying to use the documentation that is available up to that point, trying to reproduce the results described in the patch, to fully validate it. - Arnaldo > > > > https://github.com/sukadev/linux.git > > > > > > > > Branch Description > > > > ------------------------------------------------------ > > > > json-code-v21 Source Code only > > > > json-code+data-v21 Both code and data(for build/test/pull) > > > > > > > > > > Sukadev
Em Wed, Sep 28, 2016 at 11:29:16AM -0700, Sukadev Bhattiprolu escreveu: > Arnaldo Carvalho de Melo [acme@kernel.org] wrote: > > Em Tue, Sep 27, 2016 at 11:11:16AM -0700, Sukadev Bhattiprolu escreveu: > > > Arnaldo Carvalho de Melo [acme@kernel.org] wrote: > > > > Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu: > > > > > From: Andi Kleen <ak@linux.intel.com> > > > > > Add support to print alias descriptions in perf list, which > > > > > are taken from the generated event files. > > > > > > > > > > The sorting code is changed to put the events with descriptions > > > > > at the end. The descriptions are printed as possibly multiple word > > > > > wrapped lines. > > > > > > > > So, now I'm trying to reproduce the results below, but I couldn't find a > > > > tarball with those .json files for me to use, can you provide me with > > > > one? > > > > > > The data files are in my github, in the json-code+data-v21 branch > > > starting with 23bb101. They are individual commits rather than a > > > tarball though. > > > > Ok, I'll pick one for powerpc and another for x86_64 so that I can test > > it and Jiri's x-compile support. > > Please pull all files if possible, specially on x86, _before_ building the Nah, will leave this for a second step, i.e. you guys can send a pull req after I finish the initial testing. > perf binary. If you are going to pull only one, you need to make sure that > the file you pull matches the CPU model on the system you are testing.(see Right, right, that was the plan, and I actually did it now, got the mapfile.csv, left only the entry for my test machine: processor : 3 vendor_id : GenuineIntel cpu family : 6 model : 61 model name : Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz Which is 3D, i.e.: [acme@jouet linux]$ cat tools/perf/pmu-events/arch/x86/mapfile.csv Family-model,Version,Filename,EventType GenuineIntel-6-3D,V16,Broadwell,core [acme@jouet linux]$ And copied the files in the directory this maps to: [acme@jouet linux]$ ls -la tools/perf/pmu-events/arch/x86/Broadwell/ total 352 drwxrwxr-x. 2 acme acme 4096 Oct 3 17:23 . drwxrwxr-x. 3 acme acme 4096 Oct 3 17:23 .. -rw-r--r--. 1 acme acme 127294 Oct 3 17:20 Cache.json -rw-r--r--. 1 acme acme 10100 Oct 3 17:21 Floating-point.json -rw-r--r--. 1 acme acme 16319 Oct 3 17:21 Frontend.json -rw-r--r--. 1 acme acme 106375 Oct 3 17:21 Memory.json -rw-r--r--. 1 acme acme 2080 Oct 3 17:22 Other.json -rw-r--r--. 1 acme acme 64972 Oct 3 17:22 Pipeline.json -rw-r--r--. 1 acme acme 15356 Oct 3 17:23 Virtual-Memory.json [acme@jouet linux]$ Then try to build it as usual, i.e. using O=: make O=/tmp/build/perf -C tools/perf install-bin And it fails, not building the $(OUTPUT)pmu-events/pmu-events.c somehow... Ok, I decide to fall back to building it in the same directory as the sources: [acme@jouet linux]$ cd tools/perf [acme@jouet perf]$ make It gets a bit better, but fails as well: [acme@jouet perf]$ make BUILD: Doing 'make -j4' parallel build CC pmu-events/pmu-events.o pmu-events/pmu-events.c:4430:11: error: ‘pme_Filename’ undeclared here (not in a function) .table = pme_Filename ^~~~~~~~~~~~ mv: cannot stat 'pmu-events/.pmu-events.o.tmp': No such file or directory /home/acme/git/linux/tools/build/Makefile.build:88: recipe for target 'pmu-events/pmu-events.o' failed make[2]: *** [pmu-events/pmu-events.o] Error 1 Makefile.perf:467: recipe for target 'pmu-events/pmu-events-in.o' failed make[1]: *** [pmu-events/pmu-events-in.o] Error 2 make[1]: *** Waiting for unfinished jobs.... Makefile:68: recipe for target 'all' failed make: *** [all] Error 2 [acme@jouet perf]$ It finally builds if I ditch the header in https://raw.githubusercontent.com/sukadev/linux/json-code%2Bdata-v21/tools/perf/pmu-events/arch/x86/mapfile.csv [acme@jouet perf]$ cat pmu-events/arch/x86/mapfile.csv Family-model,Version,Filename,EventType GenuineIntel-6-3D,V16,Broadwell,core [acme@jouet perf]$ vim pmu-events/arch/x86/mapfile.csv [acme@jouet perf]$ cat pmu-events/arch/x86/mapfile.csv GenuineIntel-6-3D,V16,Broadwell,core [acme@jouet perf]$ make BUILD: Doing 'make -j4' parallel build GEN pmu-events/pmu-events.c Warning: tools/include/uapi/linux/bpf.h differs from kernel CC pmu-events/pmu-events.o LD pmu-events/pmu-events-in.o AR libperf.a LINK libperf-gtk.so LINK perf [acme@jouet perf]$ And then it seems to work, at least for 'perf list', still need to check if reading events with the generic name so far used + the new one looks sane, will be done after this: [acme@jouet perf]$ perf list | grep arith arith.fpu_div_active fp_arith_inst_retired.128b_packed_double fp_arith_inst_retired.128b_packed_single fp_arith_inst_retired.256b_packed_double fp_arith_inst_retired.256b_packed_single fp_arith_inst_retired.double fp_arith_inst_retired.packed fp_arith_inst_retired.scalar fp_arith_inst_retired.scalar_double fp_arith_inst_retired.scalar_single fp_arith_inst_retired.single [acme@jouet perf]$ Now trying to fix the O= part to continue processing... - Arnaldo > below). For Power, you need to test on Power8. > > > > Refresh my mind, what is the plan on these files? Are we just going to > > provide pointers to where to get them from vendors, ship it in the > > kernel, auto-download them as part of the build process? > > They are supposed to be committed into the linux kernel tree as shown > in the json-code+data-v21 tree and they will be picked up _during build_ > of the perf binary. (We are just not mailing those data files as patches > since they are large and there is very little value in reviewing them). > > When building perf on on say x86, event tables for all the different > x86 CPU models will be included in the perf binary. When perf is then > executed on an x86 box, it will detect the CPU model of that box and > use the set of events corresponding to that model. > > If the CPU model does not match the models "known" to the perf binary, > then the symbolic names will not work on that system, but there should > be no other change in behavior. > > Patch 15/19 tries to explain the process. > > > > > At least examples that allows to build and have a new 'perf test' entry > > to check them automatically seems to be in order, no? > > Well, the hope was that build/usage will be transparent! but we did not > test in the cross-compile environment. Will think about a test case. > Please let me know if we can update the README in Patch 15/19 in any > way. > > > > > - Arnaldo > > > > > > https://github.com/sukadev/linux.git > > > > > > > > Branch Description > > > > ------------------------------------------------------ > > > > json-code-v21 Source Code only > > > > json-code+data-v21 Both code and data(for build/test/pull) > > > > > > > > > > Sukadev
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index c842886..af1a612 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -222,7 +222,7 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, } static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, - char *desc __maybe_unused, char *val) + char *desc, char *val) { struct perf_pmu_alias *alias; int ret; @@ -255,6 +255,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, perf_pmu__parse_snapshot(alias, dir, name); } + alias->desc = desc ? strdup(desc) : NULL; + list_add_tail(&alias->list, list); return 0; @@ -1044,11 +1046,42 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put extra events last */ + if (!!as->desc != !!bs->desc) + return !!as->desc - !!bs->desc; + return strcmp(as->name, bs->name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, " \t"); + + if (column + wlen >= max && column > start) { + printf("\n%*s", start, ""); + column = start + corr; + } + n = printf("%s%.*s", column > start ? " " : "", wlen, s); + if (n <= 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } } void print_pmu_events(const char *event_glob, bool name_only) @@ -1058,7 +1091,9 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = 78; pmu = NULL; len = 0; @@ -1068,14 +1103,15 @@ void print_pmu_events(const char *event_glob, bool name_only) if (pmu->selectable) len++; } - aliases = zalloc(sizeof(char *) * len); + aliases = zalloc(sizeof(struct pair) * len); if (!aliases) goto out_enomem; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) { list_for_each_entry(alias, &pmu->aliases, list) { - char *name = format_alias(buf, sizeof(buf), pmu, alias); + char *name = alias->desc ? alias->name : + format_alias(buf, sizeof(buf), pmu, alias); bool is_cpu = !strcmp(pmu->name, "cpu"); if (event_glob != NULL && @@ -1084,12 +1120,19 @@ void print_pmu_events(const char *event_glob, bool name_only) event_glob)))) continue; - if (is_cpu && !name_only) + if (is_cpu && !name_only && !alias->desc) name = format_alias_or(buf, sizeof(buf), pmu, alias); - aliases[j] = strdup(name); - if (aliases[j] == NULL) + aliases[j].name = name; + if (is_cpu && !name_only && !alias->desc) + aliases[j].name = format_alias_or(buf, + sizeof(buf), + pmu, alias); + aliases[j].name = strdup(aliases[j].name); + if (!aliases[j].name) goto out_enomem; + + aliases[j].desc = alias->desc; j++; } if (pmu->selectable && @@ -1097,25 +1140,33 @@ void print_pmu_events(const char *event_glob, bool name_only) char *s; if (asprintf(&s, "%s//", pmu->name) < 0) goto out_enomem; - aliases[j] = s; + aliases[j].name = s; j++; } } len = j; - qsort(aliases, len, sizeof(char *), cmp_string); + qsort(aliases, len, sizeof(struct pair), cmp_pair); for (j = 0; j < len; j++) { if (name_only) { - printf("%s ", aliases[j]); + printf("%s ", aliases[j].name); continue; } - printf(" %-50s [Kernel PMU event]\n", aliases[j]); + if (aliases[j].desc) { + if (numdesc++ == 0) + printf("\n"); + printf(" %-50s\n", aliases[j].name); + printf("%*s", 8, "["); + wordwrap(aliases[j].desc, 8, columns, 0); + printf("]\n"); + } else + printf(" %-50s [Kernel PMU event]\n", aliases[j].name); printed++; } if (printed && pager_in_use()) printf("\n"); out_free: for (j = 0; j < len; j++) - zfree(&aliases[j]); + zfree(&aliases[j].name); zfree(&aliases); return; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 5d7e844..11bda57 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -38,6 +38,7 @@ struct perf_pmu_info { struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; /* HEAD struct parse_events_term -> list */ struct list_head list; /* ELEM */ char unit[UNIT_MAX_LEN+1];