perf/x86/mbm: Implement RMID recycling
authorVikas Shivappa <[email protected]>
Thu, 10 Mar 2016 23:32:11 +0000 (15:32 -0800)
committerIngo Molnar <[email protected]>
Mon, 21 Mar 2016 08:08:20 +0000 (09:08 +0100)
RMID could be allocated or deallocated as part of RMID recycling.

When an RMID is allocated for MBM event, the MBM counter needs to be
initialized because next time we read the counter we need the previous
value to account for total bytes that went to the memory controller.

Similarly, when RMID is deallocated we need to update the ->count
variable.

Signed-off-by: Vikas Shivappa <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Tony Luck <[email protected]>
Acked-by: Thomas Gleixner <[email protected]>
Cc: Alexander Shishkin <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Denys Vlasenko <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Matt Fleming <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
arch/x86/events/intel/cqm.c

index 610bd8ab37e4c0561e9b73bae06c1f2766f41d5e..a98f472bf6b237784c7f4f680510de577a4c3fe4 100644 (file)
@@ -450,6 +450,7 @@ struct rmid_read {
 
 static void __intel_cqm_event_count(void *info);
 static void init_mbm_sample(u32 rmid, u32 evt_type);
+static void __intel_mbm_event_count(void *info);
 
 static bool is_mbm_event(int e)
 {
@@ -476,8 +477,14 @@ static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid)
                        .rmid = old_rmid,
                };
 
-               on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count,
-                                &rr, 1);
+               if (is_mbm_event(group->attr.config)) {
+                       rr.evt_type = group->attr.config;
+                       on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_count,
+                                        &rr, 1);
+               } else {
+                       on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count,
+                                        &rr, 1);
+               }
                local64_set(&group->count, atomic64_read(&rr.value));
        }
 
@@ -489,6 +496,22 @@ static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid)
 
        raw_spin_unlock_irq(&cache_lock);
 
+       /*
+        * If the allocation is for mbm, init the mbm stats.
+        * Need to check if each event in the group is mbm event
+        * because there could be multiple type of events in the same group.
+        */
+       if (__rmid_valid(rmid)) {
+               event = group;
+               if (is_mbm_event(event->attr.config))
+                       init_mbm_sample(rmid, event->attr.config);
+
+               list_for_each_entry(event, head, hw.cqm_group_entry) {
+                       if (is_mbm_event(event->attr.config))
+                               init_mbm_sample(rmid, event->attr.config);
+               }
+       }
+
        return old_rmid;
 }
 
@@ -978,7 +1001,7 @@ static void intel_cqm_setup_event(struct perf_event *event,
                        /* All tasks in a group share an RMID */
                        event->hw.cqm_rmid = rmid;
                        *group = iter;
-                       if (is_mbm_event(event->attr.config))
+                       if (is_mbm_event(event->attr.config) && __rmid_valid(rmid))
                                init_mbm_sample(rmid, event->attr.config);
                        return;
                }
@@ -996,7 +1019,7 @@ static void intel_cqm_setup_event(struct perf_event *event,
        else
                rmid = __get_rmid();
 
-       if (is_mbm_event(event->attr.config))
+       if (is_mbm_event(event->attr.config) && __rmid_valid(rmid))
                init_mbm_sample(rmid, event->attr.config);
 
        event->hw.cqm_rmid = rmid;