lkml.org 
[lkml]   [2022]   [Mar]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH] perf intel-pt: Synthesize cycle events
On Tue, Mar 29, 2022 at 02:31:14PM +0200, Steinar H. Gunderson wrote:
> int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r)
> {
> if (!sym_l || !sym_r)
> return cmp_null(sym_l, sym_r);
>
> if (sym_l == sym_r)
> return 0;
>
> if (sym_l->inlined || sym_r->inlined) {
> int ret = strcmp(sym_l->name, sym_r->name);
>
> if (ret)
> return ret;
> if ((sym_l->start <= sym_r->end) && (sym_l->end >= sym_r->start))
> return 0;
> }
>
> if (sym_l->start != sym_r->start)
> return (int64_t)(sym_r->start - sym_l->start);

Even fixing <= to <, I do get nonsensical results like an inlined
(and very small) destructor taking 50%+ of CPU time, and having a huge
call chain under it. It largely goes away (I'm not sure if it's perfect)
if I remove the entire if (sym_l->inlined || ... branch, but I guess
it's there for a reason.

Thinking about it, I wonder if this code breaks the entire tree
invariant of comparison being transitive. If left _or_ right is inlined,
it compares them by name, but if not, it compares them by address. So
you can have three symbols A, B (inline) and C, where A < B (on name),
B < C (on name) but C < A (on address; assuming C has a lower start
address than A). That doesn't look good to me.

I'm wondering if the right fix would be something like replacing the
entire if with something like

if (sym_l->inlined && sym_r->inlined &&
strcmp(sym_l->name, sym_r->name) == 0) &&
<keep [start,end) overlap test here>) {
return 0;
}

but I'm not sure.

/* Steinar */

\
 
 \ /
  Last update: 2022-03-29 16:17    [W:0.126 / U:1.276 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site