lkml.org 
[lkml]   [2021]   [Jan]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
SubjectRe: Process-wide watchpoints
On Thu, Nov 12, 2020 at 11:43 AM Dmitry Vyukov <dvyukov@google.com> wrote:
> > > for sampling race detection),
> > > number of threads in the process can be up to, say, ~~10K and the
> > > watchpoint is intended to be set for a very brief period of time
> > > (~~few ms).
> >
> > Performance is a consideration here, doing lots of IPIs in such a short
> > window, on potentially large machines is a DoS risk.
> >
> > > This can be done today with both perf_event_open and ptrace.
> > > However, the problem is that both APIs work on a single thread level
> > > (? perf_event_open can be inherited by children, but not for existing
> > > siblings). So doing this would require iterating over, say, 10K
> >
> > One way would be to create the event before the process starts spawning
> > threads and keeping it disabled. Then every thread will inherit it, but
> > it'll be inactive.
> >
> > > I see at least one potential problem: what do we do if some sibling
> > > thread already has all 4 watchpoints consumed?
> >
> > That would be immediately avoided by this, since it will have the
> > watchpoint reserved per inheriting the event.
> >
> > Then you can do ioctl(PERF_EVENT_IOC_{MODIFY_ATTRIBUTES,ENABLE,DISABLE})
> > to update the watch location and enable/disable it. This _will_ indeed
> > result in a shitload of IPIs if the threads are active, but it should
> > work.
>
> Aha! That's the possibility I missed.
> We will try to prototype this and get back with more questions if/when
> we have them.
> Thanks!

Hi Peter,

I've tested this approach and it works, but only in half.
PERF_EVENT_IOC_{ENABLE,DISABLE} work as advertised.
However, PERF_EVENT_IOC_MODIFY_ATTRIBUTES does not work for inherited
child events.
Does something like this make any sense to you? Are you willing to
accept such change?

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 55d18791a72d..f6974807a32c 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3174,7 +3174,7 @@ int perf_event_refresh(struct perf_event *event,
int refresh)
}
EXPORT_SYMBOL_GPL(perf_event_refresh);

-static int perf_event_modify_breakpoint(struct perf_event *bp,
+static int _perf_event_modify_breakpoint(struct perf_event *bp,
struct perf_event_attr *attr)
{
int err;
@@ -3189,6 +3189,28 @@ static int perf_event_modify_breakpoint(struct
perf_event *bp,
return err;
}

+static int perf_event_modify_breakpoint(struct perf_event *bp,
+ struct perf_event_attr *attr)
+{
+ struct perf_event *child;
+ int err;
+
+ WARN_ON_ONCE(bp->ctx->parent_ctx);
+
+ mutex_lock(&bp->child_mutex);
+ err = _perf_event_modify_breakpoint(bp, attr);
+ if (err)
+ goto unlock;
+ list_for_each_entry(child, &bp->child_list, child_list) {
+ err = _perf_event_modify_breakpoint(child, attr);
+ if (err)
+ goto unlock;
+ }
+unlock:
+ mutex_unlock(&bp->child_mutex);
+ return err;
+}
+
static int perf_event_modify_attr(struct perf_event *event,
struct perf_event_attr *attr)
\
 
 \ /
  Last update: 2021-01-31 12:38    [W:0.121 / U:0.548 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site