diff options
author | Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 2013-12-12 12:05:20 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-12-16 08:37:59 -0500 |
commit | dd127b3b977b81eab58d1d7ee037195cf0bbeba7 (patch) | |
tree | 034aae43391c8a50cad79d42ca91086d535df14d | |
parent | 443e802bab16916f9a51a34f2213f4dee6e8762c (diff) |
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 <brueckner@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/kernel/perf_cpum_sf.c | 36 |
1 files changed, 35 insertions, 1 deletions
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) | |||
723 | return -ENOENT; | 723 | return -ENOENT; |
724 | } | 724 | } |
725 | 725 | ||
726 | /* Check online status of the CPU to which the event is pinned */ | ||
726 | if (event->cpu >= nr_cpumask_bits || | 727 | if (event->cpu >= nr_cpumask_bits || |
727 | (event->cpu >= 0 && !cpu_online(event->cpu))) | 728 | (event->cpu >= 0 && !cpu_online(event->cpu))) |
728 | return -ENODEV; | 729 | return -ENODEV; |
729 | 730 | ||
731 | /* Force reset of idle/hv excludes regardless of what the | ||
732 | * user requested. | ||
733 | */ | ||
734 | if (event->attr.exclude_hv) | ||
735 | event->attr.exclude_hv = 0; | ||
736 | if (event->attr.exclude_idle) | ||
737 | event->attr.exclude_idle = 0; | ||
738 | |||
730 | err = __hw_perf_event_init(event); | 739 | err = __hw_perf_event_init(event); |
731 | if (unlikely(err)) | 740 | if (unlikely(err)) |
732 | if (event->destroy) | 741 | if (event->destroy) |
@@ -824,6 +833,29 @@ static void cpumsf_pmu_disable(struct pmu *pmu) | |||
824 | cpuhw->flags &= ~PMU_F_ENABLED; | 833 | cpuhw->flags &= ~PMU_F_ENABLED; |
825 | } | 834 | } |
826 | 835 | ||
836 | /* perf_exclude_event() - Filter event | ||
837 | * @event: The perf event | ||
838 | * @regs: pt_regs structure | ||
839 | * @sde_regs: Sample-data-entry (sde) regs structure | ||
840 | * | ||
841 | * Filter perf events according to their exclude specification. | ||
842 | * | ||
843 | * Return non-zero if the event shall be excluded. | ||
844 | */ | ||
845 | static int perf_exclude_event(struct perf_event *event, struct pt_regs *regs, | ||
846 | struct perf_sf_sde_regs *sde_regs) | ||
847 | { | ||
848 | if (event->attr.exclude_user && user_mode(regs)) | ||
849 | return 1; | ||
850 | if (event->attr.exclude_kernel && !user_mode(regs)) | ||
851 | return 1; | ||
852 | if (event->attr.exclude_guest && sde_regs->in_guest) | ||
853 | return 1; | ||
854 | if (event->attr.exclude_host && !sde_regs->in_guest) | ||
855 | return 1; | ||
856 | return 0; | ||
857 | } | ||
858 | |||
827 | /* perf_push_sample() - Push samples to perf | 859 | /* perf_push_sample() - Push samples to perf |
828 | * @event: The perf event | 860 | * @event: The perf event |
829 | * @sample: Hardware sample data | 861 | * @sample: Hardware sample data |
@@ -894,12 +926,14 @@ static int perf_push_sample(struct perf_event *event, | |||
894 | sde_regs->in_guest = 1; | 926 | sde_regs->in_guest = 1; |
895 | 927 | ||
896 | overflow = 0; | 928 | overflow = 0; |
929 | if (perf_exclude_event(event, ®s, sde_regs)) | ||
930 | goto out; | ||
897 | if (perf_event_overflow(event, &data, ®s)) { | 931 | if (perf_event_overflow(event, &data, ®s)) { |
898 | overflow = 1; | 932 | overflow = 1; |
899 | event->pmu->stop(event, 0); | 933 | event->pmu->stop(event, 0); |
900 | } | 934 | } |
901 | perf_event_update_userpage(event); | 935 | perf_event_update_userpage(event); |
902 | 936 | out: | |
903 | return overflow; | 937 | return overflow; |
904 | } | 938 | } |
905 | 939 | ||