[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250211154617.GI29593@noisy.programming.kicks-ass.net>
Date: Tue, 11 Feb 2025 16:46:17 +0100
From: Peter Zijlstra <peterz@...radead.org>
To: Ravi Bangoria <ravi.bangoria@....com>
Cc: "mingo@...nel.org" <mingo@...nel.org>,
"lucas.demarchi@...el.com" <lucas.demarchi@...el.com>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"willy@...radead.org" <willy@...radead.org>,
"acme@...nel.org" <acme@...nel.org>,
"namhyung@...nel.org" <namhyung@...nel.org>,
"mark.rutland@....com" <mark.rutland@....com>,
"alexander.shishkin@...ux.intel.com" <alexander.shishkin@...ux.intel.com>,
"jolsa@...nel.org" <jolsa@...nel.org>,
"irogers@...gle.com" <irogers@...gle.com>,
"adrian.hunter@...el.com" <adrian.hunter@...el.com>,
"kan.liang@...ux.intel.com" <kan.liang@...ux.intel.com>
Subject: Re: [PATCH v2 24/24] perf: Make perf_pmu_unregister() useable
On Mon, Feb 10, 2025 at 12:09:18PM +0530, Ravi Bangoria wrote:
> Hi Peter,
>
> > @@ -1737,7 +1742,7 @@ static inline bool needs_branch_stack(st
> >
> > static inline bool has_aux(struct perf_event *event)
> > {
> > - return event->pmu->setup_aux;
> > + return event->pmu && event->pmu->setup_aux;
> > }
>
> this ...
Bah, I'll try and trace that.
> > @@ -6412,7 +6444,7 @@ static void perf_mmap_open(struct vm_are
> > if (vma->vm_pgoff)
> > atomic_inc(&event->rb->aux_mmap_count);
> >
> > - if (event->pmu->event_mapped)
> > + if (event->pmu && event->pmu->event_mapped)
> > event->pmu->event_mapped(event, vma->vm_mm);
> > }
> >
> > @@ -6435,7 +6467,8 @@ static void perf_mmap_close(struct vm_ar
> > unsigned long size = perf_data_size(rb);
> > bool detach_rest = false;
> >
> > - if (event->pmu->event_unmapped)
> > + /* FIXIES vs perf_pmu_unregister() */
> > + if (event->pmu && event->pmu->event_unmapped)
> > event->pmu->event_unmapped(event, vma->vm_mm);
>
> these two ...
>
> > @@ -6837,7 +6880,7 @@ static int perf_mmap(struct file *file,
> > if (!ret)
> > ret = map_range(rb, vma);
> >
> > - if (!ret && event->pmu->event_mapped)
> > + if (!ret && event->pmu && event->pmu->event_mapped)
> > event->pmu->event_mapped(event, vma->vm_mm);
>
> ... and this one.
These are relatively simple to fix, something like so. This relies on
the fact that if there's mapped functions the whole unregister thing
won't happen.
---
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6432,9 +6432,22 @@ void ring_buffer_put(struct perf_buffer
call_rcu(&rb->rcu_head, rb_free_rcu);
}
+typedef void (*mapped_f)(struct perf_event *event, struct mm_struct *mm);
+
+#define get_mapped(event, func) \
+({ struct pmu *pmu; \
+ mapped_f f = NULL; \
+ guard(rcu)(); \
+ pmu = READ_ONCE(event->pmu); \
+ if (pmu) \
+ f = pmu->func; \
+ f; \
+})
+
static void perf_mmap_open(struct vm_area_struct *vma)
{
struct perf_event *event = vma->vm_file->private_data;
+ mapped_f mapped = get_mapped(event, event_mapped);
atomic_inc(&event->mmap_count);
atomic_inc(&event->rb->mmap_count);
@@ -6442,8 +6455,8 @@ static void perf_mmap_open(struct vm_are
if (vma->vm_pgoff)
atomic_inc(&event->rb->aux_mmap_count);
- if (event->pmu && event->pmu->event_mapped)
- event->pmu->event_mapped(event, vma->vm_mm);
+ if (mapped)
+ mapped(event, vma->vm_mm);
}
static void perf_pmu_output_stop(struct perf_event *event);
@@ -6459,6 +6472,7 @@ static void perf_pmu_output_stop(struct
static void perf_mmap_close(struct vm_area_struct *vma)
{
struct perf_event *event = vma->vm_file->private_data;
+ mapped_f unmapped = get_mapped(event, event_unmapped);
struct perf_buffer *rb = ring_buffer_get(event);
struct user_struct *mmap_user = rb->mmap_user;
int mmap_locked = rb->mmap_locked;
@@ -6466,8 +6480,8 @@ static void perf_mmap_close(struct vm_ar
bool detach_rest = false;
/* FIXIES vs perf_pmu_unregister() */
- if (event->pmu && event->pmu->event_unmapped)
- event->pmu->event_unmapped(event, vma->vm_mm);
+ if (unmapped)
+ unmapped(event, vma->vm_mm);
/*
* The AUX buffer is strictly a sub-buffer, serialize using aux_mutex
@@ -6660,6 +6674,7 @@ static int perf_mmap(struct file *file,
unsigned long nr_pages;
long user_extra = 0, extra = 0;
int ret, flags = 0;
+ mapped_f mapped;
/*
* Don't allow mmap() of inherited per-task counters. This would
@@ -6878,8 +6893,9 @@ static int perf_mmap(struct file *file,
if (!ret)
ret = map_range(rb, vma);
- if (!ret && event->pmu && event->pmu->event_mapped)
- event->pmu->event_mapped(event, vma->vm_mm);
+ mapped = get_mapped(event, event_mapped);
+ if (mapped)
+ mapped(event, vma->vm_mm);
return ret;
}
Powered by blists - more mailing lists