From: Jiri Olsa <olsajiri@gmail.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Jiri Olsa <olsajiri@gmail.com>,
Andrii Nakryiko <andrii@kernel.org>,
linux-trace-kernel@vger.kernel.org, peterz@infradead.org,
mingo@kernel.org, oleg@redhat.com, rostedt@goodmis.org,
mhiramat@kernel.org, bpf@vger.kernel.org,
linux-kernel@vger.kernel.org, liaochang1@huawei.com,
kernel-team@meta.com
Subject: Re: [PATCH perf/core 4/4] uprobes: reuse return_instances between multiple uretprobes within task
Date: Sat, 7 Dec 2024 01:36:57 +0100 [thread overview]
Message-ID: <Z1OYqdCZXXbNGEE8@krava> (raw)
In-Reply-To: <CAEf4BzaESrHfAXZrN0VbjQvxLJ0ij0ujKpsp2T6iQtbisYPa=A@mail.gmail.com>
On Fri, Dec 06, 2024 at 10:00:16AM -0800, Andrii Nakryiko wrote:
> On Fri, Dec 6, 2024 at 6:07 AM Jiri Olsa <olsajiri@gmail.com> wrote:
> >
> > On Thu, Dec 05, 2024 at 04:24:17PM -0800, Andrii Nakryiko wrote:
> >
> > SNIP
> >
> > > +static void free_ret_instance(struct uprobe_task *utask,
> > > + struct return_instance *ri, bool cleanup_hprobe)
> > > +{
> > > + unsigned seq;
> > > +
> > > if (cleanup_hprobe) {
> > > enum hprobe_state hstate;
> > >
> > > @@ -1897,8 +1923,22 @@ static void free_ret_instance(struct return_instance *ri, bool cleanup_hprobe)
> > > hprobe_finalize(&ri->hprobe, hstate);
> > > }
> > >
> > > - kfree(ri->extra_consumers);
> > > - kfree_rcu(ri, rcu);
> > > + /*
> > > + * At this point return_instance is unlinked from utask's
> > > + * return_instances list and this has become visible to ri_timer().
> > > + * If seqcount now indicates that ri_timer's return instance
> > > + * processing loop isn't active, we can return ri into the pool of
> > > + * to-be-reused return instances for future uretprobes. If ri_timer()
> > > + * happens to be running right now, though, we fallback to safety and
> > > + * just perform RCU-delated freeing of ri.
> > > + */
> > > + if (raw_seqcount_try_begin(&utask->ri_seqcount, seq)) {
> > > + /* immediate reuse of ri without RCU GP is OK */
> > > + ri_pool_push(utask, ri);
> >
> > should the push be limitted somehow? I wonder you could make uprobes/consumers
> > setup that would allocate/push many of ri instances that would not be freed
> > until the process exits?
>
> So I'm just relying on the existing MAX_URETPROBE_DEPTH limit that is
> enforced by prepare_uretprobe anyways. But yes, we can have up to 64
> instances in ri_pool.
>
> I did consider cleaning this up from ri_timer() (that would be a nice
> properly, because ri_timer fires after 100ms of inactivity), and my
> initial version did use lockless llist for that, but there is a bit of
> a problem: llist doesn't support popping single iter from the list
> (you can only atomically take *all* of the items) in lockless way. So
> my implementation had to swap the entire list, take one element out of
> it, and then put N - 1 items back. Which, when there are deep chains
> of uretprobes, would be quite an unnecessary CPU overhead. And I
> clearly didn't want to add locking anywhere in this hot path, of
> course.
>
> So I figured that at the absolute worst case we'll just keep
> MAX_URETPROBE_DEPTH items in ri_pool until the task dies. That's not
> that much memory for a small subset of tasks on the system.
>
> One more idea I explored and rejected was to limit the size of ri_pool
> to something smaller than MAX_URETPROBE_DEPTH, say just 16. But then
> there is a corner case of high-frequency long chain of uretprobes up
> to 64 depth, then returning through all of them, and then going into
> the same set of functions again, up to 64. So depth oscillates between
> 0 and full 64. In this case this ri_pool will be causing allocation
> for the majority of those invocations, completely defeating the
> purpose.
>
> So, in the end, it felt like 64 cached instances (worst case, if we
> actually ever reached such a deep chain) would be acceptable.
> Especially that commonly I wouldn't expect more than 3-4, actually.
>
> WDYT?
ah ok, there's MAX_URETPROBE_DEPTH limit for task, 64 should be fine
thanks,
jirka
>
> >
> > jirka
> >
> > > + } else {
> > > + /* we might be racing with ri_timer(), so play it safe */
> > > + ri_free(ri);
> > > + }
> > > }
> > >
> > > /*
>
> [...]
next prev parent reply other threads:[~2024-12-07 0:37 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-06 0:24 [PATCH perf/core 0/4] Improve performance and scalability of uretprobes Andrii Nakryiko
2024-12-06 0:24 ` [PATCH perf/core 1/4] uprobes: simplify session consumer tracking Andrii Nakryiko
2024-12-06 9:38 ` [tip: perf/core] uprobes: Simplify " tip-bot2 for Andrii Nakryiko
2024-12-06 14:07 ` [PATCH perf/core 1/4] uprobes: simplify " Jiri Olsa
2024-12-06 17:50 ` Andrii Nakryiko
2024-12-09 10:32 ` [tip: perf/core] uprobes: Simplify " tip-bot2 for Andrii Nakryiko
2024-12-09 14:55 ` tip-bot2 for Andrii Nakryiko
2024-12-06 0:24 ` [PATCH perf/core 2/4] uprobes: decouple return_instance list traversal and freeing Andrii Nakryiko
2024-12-06 9:38 ` [tip: perf/core] uprobes: Decouple " tip-bot2 for Andrii Nakryiko
2024-12-09 10:32 ` tip-bot2 for Andrii Nakryiko
2024-12-09 14:55 ` tip-bot2 for Andrii Nakryiko
2024-12-06 0:24 ` [PATCH perf/core 3/4] uprobes: ensure return_instance is detached from the list before freeing Andrii Nakryiko
2024-12-06 9:38 ` [tip: perf/core] uprobes: Ensure " tip-bot2 for Andrii Nakryiko
2024-12-09 10:32 ` tip-bot2 for Andrii Nakryiko
2024-12-09 14:55 ` tip-bot2 for Andrii Nakryiko
2024-12-06 0:24 ` [PATCH perf/core 4/4] uprobes: reuse return_instances between multiple uretprobes within task Andrii Nakryiko
2024-12-06 9:38 ` [tip: perf/core] uprobes: Reuse " tip-bot2 for Andrii Nakryiko
2024-12-06 14:07 ` [PATCH perf/core 4/4] uprobes: reuse " Jiri Olsa
2024-12-06 18:00 ` Andrii Nakryiko
2024-12-07 0:36 ` Jiri Olsa [this message]
2024-12-06 14:09 ` Jiri Olsa
2024-12-09 10:32 ` [tip: perf/core] uprobes: Reuse " tip-bot2 for Andrii Nakryiko
2024-12-09 14:55 ` tip-bot2 for Andrii Nakryiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z1OYqdCZXXbNGEE8@krava \
--to=olsajiri@gmail.com \
--cc=andrii.nakryiko@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=kernel-team@meta.com \
--cc=liaochang1@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.