aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2014-07-11 19:45:09 +0100
committerMatt Fleming <matt.fleming@intel.com>2014-07-11 19:45:09 +0100
commitb28432bdddfde3ad279b9caa6a6a28ab0d083eaa (patch)
tree060fb081a71edb641322ccbe1934c317ff97f4a0
parent76f5509b8ccda621de8367f667650a8b1f035f11 (diff)
downloadlinux-experimental/cqm/mfleming-no-cgroup.tar.gz
perf/x86: Perform async counter updateexperimental/cqm/mfleming-no-cgroup
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_qos.c37
-rw-r--r--include/linux/perf_event.h1
2 files changed, 35 insertions, 3 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_qos.c b/arch/x86/kernel/cpu/perf_event_intel_qos.c
index 0cec030ddf123..7a1bb012e4662 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_qos.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_qos.c
@@ -275,6 +275,31 @@ static int intel_qos_setup_event(struct perf_event *event,
return 0;
}
+static void intel_qos_async_read(void *data)
+{
+ struct perf_event *event = data;
+ unsigned long flags;
+ int i, index = 0;
+ u64 val;
+
+ raw_spin_lock_irqsave(&cache_lock, flags);
+
+ for_each_cpu(i, &qos_cpumask) {
+ if (i == smp_processor_id())
+ break;
+ index++;
+ }
+
+ val = __rmid_read(event->hw.qos_rmid);
+ event->hw.qos_package_count[index] = val;
+
+ local64_set(&event->count, 0);
+ for (i = 0; i < cpumask_weight(&qos_cpumask); i++)
+ local64_add(event->hw.qos_package_count[i], &event->count);
+
+ raw_spin_unlock_irqrestore(&cache_lock, flags);
+}
+
static void intel_qos_event_read(struct perf_event *__event)
{
struct perf_event *event;
@@ -335,9 +360,15 @@ static void intel_qos_event_read(struct perf_event *__event)
/* Convert phys_id to hw->qos_package_count index */
for_each_cpu(i, &qos_cpumask) {
- if (phys_id == topology_physical_package_id(i))
- break;
- index++;
+ if (phys_id == topology_physical_package_id(i)) {
+ index = i;
+ continue;
+ }
+
+ event->hw.qos_csd.func = intel_qos_async_read;
+ event->hw.qos_csd.info = event;
+ event->hw.qos_csd.flags = 0;
+ smp_call_function_single_async(i, &event->hw.qos_csd);
}
event->hw.qos_package_count[index] = val;
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 747532903231d..51c5f09802b0f 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -133,6 +133,7 @@ struct hw_perf_event {
struct list_head qos_groups_entry;
struct list_head qos_group_entry;
u64 *qos_package_count;
+ struct call_single_data qos_csd;
};
#ifdef CONFIG_HAVE_HW_BREAKPOINT
struct { /* breakpoint */