From dd127b3b977b81eab58d1d7ee037195cf0bbeba7 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Thu, 12 Dec 2013 18:05:20 +0100 Subject: [PATCH] s390/cpum_sf: Filter perf events based event->attr.exclude_* settings Introduce the perf_exclude_event() function to filter perf samples according to event->attr.exclude_* settings. During event initialization, reset event exclude settings that are not supported. Signed-off-by: Hendrik Brueckner Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/perf_cpum_sf.c | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index d611facae599..28fa2f235158 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -723,10 +723,19 @@ static int cpumsf_pmu_event_init(struct perf_event *event) return -ENOENT; } + /* Check online status of the CPU to which the event is pinned */ if (event->cpu >= nr_cpumask_bits || (event->cpu >= 0 && !cpu_online(event->cpu))) return -ENODEV; + /* Force reset of idle/hv excludes regardless of what the + * user requested. + */ + if (event->attr.exclude_hv) + event->attr.exclude_hv = 0; + if (event->attr.exclude_idle) + event->attr.exclude_idle = 0; + err = __hw_perf_event_init(event); if (unlikely(err)) if (event->destroy) @@ -824,6 +833,29 @@ static void cpumsf_pmu_disable(struct pmu *pmu) cpuhw->flags &= ~PMU_F_ENABLED; } +/* perf_exclude_event() - Filter event + * @event: The perf event + * @regs: pt_regs structure + * @sde_regs: Sample-data-entry (sde) regs structure + * + * Filter perf events according to their exclude specification. + * + * Return non-zero if the event shall be excluded. + */ +static int perf_exclude_event(struct perf_event *event, struct pt_regs *regs, + struct perf_sf_sde_regs *sde_regs) +{ + if (event->attr.exclude_user && user_mode(regs)) + return 1; + if (event->attr.exclude_kernel && !user_mode(regs)) + return 1; + if (event->attr.exclude_guest && sde_regs->in_guest) + return 1; + if (event->attr.exclude_host && !sde_regs->in_guest) + return 1; + return 0; +} + /* perf_push_sample() - Push samples to perf * @event: The perf event * @sample: Hardware sample data @@ -894,12 +926,14 @@ static int perf_push_sample(struct perf_event *event, sde_regs->in_guest = 1; overflow = 0; + if (perf_exclude_event(event, ®s, sde_regs)) + goto out; if (perf_event_overflow(event, &data, ®s)) { overflow = 1; event->pmu->stop(event, 0); } perf_event_update_userpage(event); - +out: return overflow; } -- 2.39.5