diff options
author | Matt Fleming <matt.fleming@intel.com> | 2014-07-11 19:45:09 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2014-07-11 19:45:09 +0100 |
commit | b28432bdddfde3ad279b9caa6a6a28ab0d083eaa (patch) | |
tree | 060fb081a71edb641322ccbe1934c317ff97f4a0 | |
parent | 76f5509b8ccda621de8367f667650a8b1f035f11 (diff) | |
download | linux-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.c | 37 | ||||
-rw-r--r-- | include/linux/perf_event.h | 1 |
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 */ |