lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 14 Feb 2024 21:26:42 -0800
From: Namhyung Kim <namhyung@...nel.org>
To: Ian Rogers <irogers@...gle.com>
Cc: Arnaldo Carvalho de Melo <acme@...nel.org>, Jiri Olsa <jolsa@...nel.org>, 
	Adrian Hunter <adrian.hunter@...el.com>, Peter Zijlstra <peterz@...radead.org>, 
	Ingo Molnar <mingo@...nel.org>, LKML <linux-kernel@...r.kernel.org>, 
	linux-perf-users@...r.kernel.org
Subject: Re: [PATCH 3/4] perf hist: Do not use event index in hpp__fmt()

On Wed, Feb 14, 2024 at 4:08 PM Ian Rogers <irogers@...gle.com> wrote:
>
> On Mon, Feb 12, 2024 at 11:52 PM Namhyung Kim <namhyung@...nel.org> wrote:
> >
> > The __hpp__fmt() is to print period values in a hist entry.  It handles
> > event groups using linked pair entries.  Until now, it used event index
> > to print values of group members.  But we want to make it more robust
> > and support groups even if some members in the group were removed.
>
> I'm unclear how it breaks currently. The evsel idx is set the evlist
> nr_entries on creation and not updated by a remove. A remove may
> change a groups leader, should the remove also make the next entry's
> index idx that of the previous group leader?

The evsel__group_idx() returns evsel->idx - leader->idx.
If it has a group event {A, B, C} then the index would be 0, 1, 2.
If it removes B, the group would be {A, C} with index 0 and 2.
The nr_members is 2 now so it cannot use index 2 for C.

Note that we cannot change the index of C because some information
like annotation histogram relies on the index.

>
> > Let's use an index table from evsel to value array so that we can skip
> > dummy events in the output later.
> >
> > Signed-off-by: Namhyung Kim <namhyung@...nel.org>
> > ---
> >  tools/perf/ui/hist.c | 34 ++++++++++++++++++++++++++++------
> >  1 file changed, 28 insertions(+), 6 deletions(-)
> >
> > diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
> > index 5f4c110d840f..9c4c738edde1 100644
> > --- a/tools/perf/ui/hist.c
> > +++ b/tools/perf/ui/hist.c
> > @@ -48,15 +48,30 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
> >         if (evsel__is_group_event(evsel)) {
> >                 int idx;
> >                 struct hist_entry *pair;
> > -               int nr_members = evsel->core.nr_members;
> > +               int nr_members = evsel->core.nr_members - 1;
>
> A comment on the -1 would be useful.

The 'nr_members' includes the leader which is already printed.
In this code, we want to print member events only, hence -1.
I'll add it to the comment.

Thanks,
Namhyung

>
> Thanks,
> Ian
>
>
> >                 union {
> >                         u64 period;
> >                         double percent;
> >                 } *val;
> > +               struct evsel *member;
> > +               struct evsel **idx_table;
> >
> >                 val = calloc(nr_members, sizeof(*val));
> >                 if (val == NULL)
> > -                       return 0;
> > +                       goto out;
> > +
> > +               idx_table = calloc(nr_members, sizeof(*idx_table));
> > +               if (idx_table == NULL)
> > +                       goto out;
> > +
> > +               /*
> > +                * Build an index table for each evsel to the val array.
> > +                * It cannot use evsel->core.idx because removed events might
> > +                * create a hole so the index is not consecutive anymore.
> > +                */
> > +               idx = 0;
> > +               for_each_group_member(member, evsel)
> > +                       idx_table[idx++] = member;
> >
> >                 /* collect values in the group members */
> >                 list_for_each_entry(pair, &he->pairs.head, pairs.node) {
> > @@ -66,8 +81,15 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
> >                         if (!total)
> >                                 continue;
> >
> > -                       evsel = hists_to_evsel(pair->hists);
> > -                       idx = evsel__group_idx(evsel);
> > +                       member = hists_to_evsel(pair->hists);
> > +                       for (idx = 0; idx < nr_members; idx++) {
> > +                               if (idx_table[idx] == member)
> > +                                       break;
> > +                       }
> > +
> > +                       /* this should not happen */
> > +                       if (idx == nr_members)
> > +                               continue;
> >
> >                         if (fmt_percent)
> >                                 val[idx].percent = 100.0 * period / total;
> > @@ -75,8 +97,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
> >                                 val[idx].period = period;
> >                 }
> >
> > -               /* idx starts from 1 to skip the leader event */
> > -               for (idx = 1; idx < nr_members; idx++) {
> > +               for (idx = 0; idx < nr_members; idx++) {
> >                         if (fmt_percent) {
> >                                 ret += hpp__call_print_fn(hpp, print_fn,
> >                                                           fmt, len, val[idx].percent);
> > @@ -89,6 +110,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
> >                 free(val);
> >         }
> >
> > +out:
> >         /*
> >          * Restore original buf and size as it's where caller expects
> >          * the result will be saved.
> > --
> > 2.43.0.687.g38aa6559b0-goog
> >

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ