Messages in this thread Patch in this message | | | From | David Carrillo-Cisneros <> | Subject | [PATCH v2 17/32] perf/core,perf/x86/intel/cqm: add pmu::event_terminate | Date | Wed, 11 May 2016 16:02:17 -0700 |
| |
Allow a PMU to clean an event before the event's torn down in perf_events begins.
Utilized in CQM to dettach the cgroup from monr before perf removes it from event.
Reviewed-by: Stephane Eranian <eranian@google.com> Signed-off-by: David Carrillo-Cisneros <davidcc@google.com> --- arch/x86/events/intel/cqm.c | 18 +++++++++++++++--- include/linux/perf_event.h | 6 ++++++ kernel/events/core.c | 4 ++++ 3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c index fb62bac..a5bec07 100644 --- a/arch/x86/events/intel/cqm.c +++ b/arch/x86/events/intel/cqm.c @@ -2376,7 +2376,7 @@ static inline bool cqm_group_leader(struct perf_event *event) return !list_empty(&event->hw.cqm_event_groups_entry); } -static void intel_cqm_event_destroy(struct perf_event *event) +static void intel_cqm_event_terminate(struct perf_event *event) { struct perf_event *group_other = NULL; struct monr *monr; @@ -2423,6 +2423,19 @@ static void intel_cqm_event_destroy(struct perf_event *event) if (monr__is_root(monr)) goto exit; +#ifdef CONFIG_CGROUP_PERF + /* Handle cgroup event. */ + if (event->cgrp) { + monr->mon_event_group = NULL; + if ((event->cgrp->css.flags & CSS_ONLINE) && + !cgrp_to_cqm_info(event->cgrp)->cont_monitoring) + __css_stop_monitoring(&monr__get_mon_cgrp(monr)->css); + + goto exit; + } + WARN_ON_ONCE(!monr_is_event_type(monr)); +#endif + /* Transition all pmonrs to (U)state. */ monr_hrchy_acquire_locks(flags, i); @@ -2463,8 +2476,6 @@ static int intel_cqm_event_init(struct perf_event *event) INIT_LIST_HEAD(&event->hw.cqm_event_groups_entry); INIT_LIST_HEAD(&event->hw.cqm_event_group_entry); - event->destroy = intel_cqm_event_destroy; - mutex_lock(&cqm_mutex); @@ -2580,6 +2591,7 @@ static struct pmu intel_cqm_pmu = { .attr_groups = intel_cqm_attr_groups, .task_ctx_nr = perf_sw_context, .event_init = intel_cqm_event_init, + .event_terminate = intel_cqm_event_terminate, .add = intel_cqm_event_add, .del = intel_cqm_event_stop, .start = intel_cqm_event_start, diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 60dbd5d..73c5a22 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -278,6 +278,12 @@ struct pmu { int (*event_init) (struct perf_event *event); /* + * Terminate the event for this PMU. Optional complement for a + * successful event_init. Called before the event fields are tear down. + */ + void (*event_terminate) (struct perf_event *event); + + /* * Notification that the event was mapped or unmapped. Called * in the context of the mapping task. */ diff --git a/kernel/events/core.c b/kernel/events/core.c index b249251..c242e80 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3833,6 +3833,8 @@ static void _free_event(struct perf_event *event) ring_buffer_attach(event, NULL); mutex_unlock(&event->mmap_mutex); } + if (event->pmu->event_terminate) + event->pmu->event_terminate(event); if (is_cgroup_event(event)) perf_detach_cgroup(event); @@ -8851,6 +8853,8 @@ err_per_task: exclusive_event_destroy(event); err_pmu: + if (event->pmu->event_terminate) + event->pmu->event_terminate(event); if (event->destroy) event->destroy(event); module_put(pmu->module); -- 2.8.0.rc3.226.g39d4020
| |