ARCv2: perf: implement exclusion of event counting in user or kernel mode
authorAlexey Brodkin <abrodkin@synopsys.com>
Mon, 24 Aug 2015 10:53:36 +0000 (13:53 +0300)
committerVineet Gupta <vgupta@synopsys.com>
Thu, 27 Aug 2015 09:28:14 +0000 (14:58 +0530)
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/include/asm/perf_event.h
arch/arc/kernel/perf_event.c

index 3522d095b61573fc202a08eb201d3a34716c7554..5824ab46cb71ebdb32c1097e638aadbe02068e10 100644 (file)
@@ -34,6 +34,9 @@
 #define ARC_REG_PCT_INT_CTRL   0x25E
 #define ARC_REG_PCT_INT_ACT    0x25F
 
+#define ARC_REG_PCT_CONFIG_USER        (1 << 18)       /* count in user mode */
+#define ARC_REG_PCT_CONFIG_KERN        (1 << 19)       /* count in kernel mode */
+
 #define ARC_REG_PCT_CONTROL_CC (1 << 16)       /* clear counts */
 #define ARC_REG_PCT_CONTROL_SN (1 << 17)       /* snapshot */
 
index 208c9546e8f0252bba427b51f0a2745a69042238..5b94cebe053527730e8a7650cff37e2221f28095 100644 (file)
@@ -147,13 +147,25 @@ static int arc_pmu_event_init(struct perf_event *event)
                local64_set(&hwc->period_left, hwc->sample_period);
        }
 
+       hwc->config = 0;
+
+       if (is_isa_arcv2()) {
+               /* "exclude user" means "count only kernel" */
+               if (event->attr.exclude_user)
+                       hwc->config |= ARC_REG_PCT_CONFIG_KERN;
+
+               /* "exclude kernel" means "count only user" */
+               if (event->attr.exclude_kernel)
+                       hwc->config |= ARC_REG_PCT_CONFIG_USER;
+       }
+
        switch (event->attr.type) {
        case PERF_TYPE_HARDWARE:
                if (event->attr.config >= PERF_COUNT_HW_MAX)
                        return -ENOENT;
                if (arc_pmu->ev_hw_idx[event->attr.config] < 0)
                        return -ENOENT;
-               hwc->config = arc_pmu->ev_hw_idx[event->attr.config];
+               hwc->config |= arc_pmu->ev_hw_idx[event->attr.config];
                pr_debug("init event %d with h/w %d \'%s\'\n",
                         (int) event->attr.config, (int) hwc->config,
                         arc_pmu_ev_hw_map[event->attr.config]);
@@ -163,7 +175,7 @@ static int arc_pmu_event_init(struct perf_event *event)
                ret = arc_pmu_cache_event(event->attr.config);
                if (ret < 0)
                        return ret;
-               hwc->config = arc_pmu->ev_hw_idx[ret];
+               hwc->config |= arc_pmu->ev_hw_idx[ret];
                return 0;
        default:
                return -ENOENT;