]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
perf/x86/cqm: Fix CQM handling of grouping events into a cache_group
authorVikas Shivappa <vikas.shivappa@linux.intel.com>
Thu, 10 Mar 2016 23:32:07 +0000 (15:32 -0800)
committerIngo Molnar <mingo@kernel.org>
Mon, 21 Mar 2016 08:08:18 +0000 (09:08 +0100)
Currently CQM (cache quality of service monitoring) is grouping all
events belonging to same PID to use one RMID. However its not counting
all of these different events. Hence we end up with a count of zero
for all events other than the group leader.

The patch tries to address the issue by keeping a flag in the
perf_event.hw which has other CQM related fields. The field is updated
at event creation and during grouping.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
[peterz: Changed hw_perf_event::is_group_event to an int]
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: fenghua.yu@intel.com
Cc: h.peter.anvin@intel.com
Cc: ravi.v.shankar@intel.com
Cc: vikas.shivappa@intel.com
Link: http://lkml.kernel.org/r/1457652732-4499-2-git-send-email-vikas.shivappa@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/events/intel/cqm.c
include/linux/perf_event.h

index 93cb412a55792fbc68f2460da7295c77098e4532..b0226f1912a21ed92d70bf6b438150cce16e80c2 100644 (file)
@@ -281,9 +281,13 @@ static bool __match_event(struct perf_event *a, struct perf_event *b)
 
        /*
         * Events that target same task are placed into the same cache group.
+        * Mark it as a multi event group, so that we update ->count
+        * for every event rather than just the group leader later.
         */
-       if (a->hw.target == b->hw.target)
+       if (a->hw.target == b->hw.target) {
+               b->hw.is_group_event = true;
                return true;
+       }
 
        /*
         * Are we an inherited event?
@@ -849,6 +853,7 @@ static void intel_cqm_setup_event(struct perf_event *event,
        bool conflict = false;
        u32 rmid;
 
+       event->hw.is_group_event = false;
        list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) {
                rmid = iter->hw.cqm_rmid;
 
@@ -940,7 +945,9 @@ static u64 intel_cqm_event_count(struct perf_event *event)
                return __perf_event_count(event);
 
        /*
-        * Only the group leader gets to report values. This stops us
+        * Only the group leader gets to report values except in case of
+        * multiple events in the same group, we still need to read the
+        * other events.This stops us
         * reporting duplicate values to userspace, and gives us a clear
         * rule for which task gets to report the values.
         *
@@ -948,7 +955,7 @@ static u64 intel_cqm_event_count(struct perf_event *event)
         * specific packages - we forfeit that ability when we create
         * task events.
         */
-       if (!cqm_group_leader(event))
+       if (!cqm_group_leader(event) && !event->hw.is_group_event)
                return 0;
 
        /*
index 79ec7bbf01557e523aee3ed263425b6fc3360741..7bb315bec3aa80e961bb2c62924335492acdf76f 100644 (file)
@@ -121,6 +121,7 @@ struct hw_perf_event {
                struct { /* intel_cqm */
                        int                     cqm_state;
                        u32                     cqm_rmid;
+                       int                     is_group_event;
                        struct list_head        cqm_events_entry;
                        struct list_head        cqm_groups_entry;
                        struct list_head        cqm_group_entry;