aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew Richardson <drew.richardson@arm.com>2015-03-28 12:00:00 -0700
committerDrew Richardson <drew.richardson@arm.com>2015-04-01 14:41:00 -0700
commitabc3535c0d237bf7968b7092e545f2ff422af954 (patch)
tree778f83b3d8fd576762290b58b12c33cca5a193e1
parente8f6a181be0b67fc9d9ac117bc2ed01737be654c (diff)
downloadgator-abc3535c0d237bf7968b7092e545f2ff422af954.tar.gz
gator: Version 5.215.21
Signed-off-by: Drew Richardson <drew.richardson@arm.com>
-rw-r--r--.gitignore2
-rw-r--r--README_Streamline.txt41
-rw-r--r--daemon/Android.mk4
-rw-r--r--daemon/AnnotateListener.cpp30
-rw-r--r--daemon/AnnotateListener.h16
-rw-r--r--daemon/Application.mk2
-rw-r--r--daemon/Buffer.cpp77
-rw-r--r--daemon/Buffer.h25
-rw-r--r--daemon/CCNDriver.cpp5
-rw-r--r--daemon/CCNDriver.h2
-rw-r--r--daemon/CPUFreqDriver.cpp58
-rw-r--r--daemon/CPUFreqDriver.h34
-rw-r--r--daemon/CapturedXML.cpp5
-rw-r--r--daemon/CapturedXML.h2
-rw-r--r--daemon/Child.cpp49
-rw-r--r--daemon/Child.h2
-rw-r--r--daemon/Command.cpp12
-rw-r--r--daemon/Command.h2
-rw-r--r--daemon/Config.h2
-rw-r--r--daemon/ConfigurationXML.cpp10
-rw-r--r--daemon/ConfigurationXML.h2
-rw-r--r--daemon/Counter.h2
-rw-r--r--daemon/DiskIODriver.cpp20
-rw-r--r--daemon/DiskIODriver.h2
-rw-r--r--daemon/Driver.cpp2
-rw-r--r--daemon/Driver.h2
-rw-r--r--daemon/DriverSource.cpp33
-rw-r--r--daemon/DriverSource.h2
-rw-r--r--daemon/DynBuf.cpp16
-rw-r--r--daemon/DynBuf.h2
-rw-r--r--daemon/EventsXML.cpp179
-rw-r--r--daemon/EventsXML.h9
-rw-r--r--daemon/ExternalSource.cpp59
-rw-r--r--daemon/ExternalSource.h3
-rw-r--r--daemon/FSDriver.cpp32
-rw-r--r--daemon/FSDriver.h2
-rw-r--r--daemon/Fifo.cpp6
-rw-r--r--daemon/Fifo.h2
-rw-r--r--daemon/FtraceDriver.cpp119
-rw-r--r--daemon/FtraceDriver.h4
-rw-r--r--daemon/FtraceSource.cpp56
-rw-r--r--daemon/FtraceSource.h2
-rw-r--r--daemon/HwmonDriver.cpp158
-rw-r--r--daemon/HwmonDriver.h2
-rw-r--r--daemon/KMod.cpp6
-rw-r--r--daemon/KMod.h2
-rw-r--r--daemon/LICENSE339
-rw-r--r--daemon/LocalCapture.cpp8
-rw-r--r--daemon/LocalCapture.h2
-rw-r--r--daemon/Logging.cpp10
-rw-r--r--daemon/Logging.h16
-rw-r--r--daemon/MaliVideoDriver.cpp4
-rw-r--r--daemon/MaliVideoDriver.h2
-rw-r--r--daemon/MemInfoDriver.cpp4
-rw-r--r--daemon/MemInfoDriver.h2
-rw-r--r--daemon/Monitor.cpp20
-rw-r--r--daemon/Monitor.h2
-rw-r--r--daemon/NetDriver.cpp6
-rw-r--r--daemon/NetDriver.h2
-rw-r--r--daemon/OlySocket.cpp51
-rw-r--r--daemon/OlySocket.h8
-rw-r--r--daemon/OlyUtility.cpp2
-rw-r--r--daemon/OlyUtility.h2
-rw-r--r--daemon/PerfBuffer.cpp129
-rw-r--r--daemon/PerfBuffer.h3
-rw-r--r--daemon/PerfDriver.cpp181
-rw-r--r--daemon/PerfDriver.h8
-rw-r--r--daemon/PerfGroup.cpp234
-rw-r--r--daemon/PerfGroup.h23
-rw-r--r--daemon/PerfSource.cpp210
-rw-r--r--daemon/PerfSource.h5
-rw-r--r--daemon/Proc.cpp62
-rw-r--r--daemon/Proc.h2
-rw-r--r--daemon/Sender.cpp8
-rw-r--r--daemon/Sender.h2
-rw-r--r--daemon/SessionData.cpp67
-rw-r--r--daemon/SessionData.h11
-rw-r--r--daemon/SessionXML.cpp8
-rw-r--r--daemon/SessionXML.h2
-rw-r--r--daemon/Setup.cpp202
-rw-r--r--daemon/Setup.h4
-rw-r--r--daemon/Source.cpp4
-rw-r--r--daemon/Source.h2
-rw-r--r--daemon/StreamlineSetup.cpp22
-rw-r--r--daemon/StreamlineSetup.h2
-rw-r--r--daemon/UEvent.cpp9
-rw-r--r--daemon/UEvent.h2
-rw-r--r--daemon/UserSpaceSource.cpp37
-rw-r--r--daemon/UserSpaceSource.h2
-rw-r--r--daemon/c++.cpp2
-rw-r--r--daemon/common.mk9
-rw-r--r--daemon/defaults.xml16
-rw-r--r--daemon/escape.c2
-rw-r--r--daemon/events-ARM11.xml2
-rw-r--r--daemon/events-CCI-400.xml4
-rw-r--r--daemon/events-CCI-500.xml75
-rw-r--r--daemon/events-Cortex-A15.xml100
-rw-r--r--daemon/events-Cortex-A17.xml79
-rw-r--r--daemon/events-Cortex-A5.xml52
-rw-r--r--daemon/events-Cortex-A53.xml117
-rw-r--r--daemon/events-Cortex-A57.xml58
-rw-r--r--daemon/events-Cortex-A7.xml65
-rw-r--r--daemon/events-Cortex-A72.xml10
-rw-r--r--daemon/events-Cortex-A8.xml44
-rw-r--r--daemon/events-Cortex-A9.xml66
-rw-r--r--daemon/events-Filesystem.xml3
-rw-r--r--daemon/events-L2C-310.xml4
-rw-r--r--daemon/events-Linux.xml4
-rw-r--r--daemon/events-Mali-4xx.xml4
-rw-r--r--daemon/events-Mali-Midgard.xml17
-rw-r--r--daemon/events-Mali-Midgard_hw.xml75
-rw-r--r--daemon/events-Mali-T60x_hw.xml66
-rw-r--r--daemon/events-Mali-T62x_hw.xml65
-rw-r--r--daemon/events-Mali-T72x_hw.xml56
-rw-r--r--daemon/events-Mali-T76x_hw.xml67
-rw-r--r--daemon/events-Mali-T82x_hw.xml108
-rw-r--r--daemon/events-Mali-T83x_hw.xml108
-rw-r--r--daemon/events-Mali-T86x_hw.xml117
-rw-r--r--daemon/events-Mali-T88x_hw.xml117
-rw-r--r--daemon/events-Other.xml33
-rw-r--r--daemon/events-ftrace.xml21
-rw-r--r--daemon/main.cpp100
-rw-r--r--driver/Makefile17
-rw-r--r--driver/gator.h42
-rw-r--r--driver/gator_annotate.c2
-rw-r--r--driver/gator_annotate_kernel.c2
-rw-r--r--driver/gator_backtrace.c2
-rw-r--r--driver/gator_buffer.c2
-rw-r--r--driver/gator_buffer_write.c2
-rw-r--r--driver/gator_cookies.c2
-rw-r--r--driver/gator_events_armv6.c2
-rw-r--r--driver/gator_events_armv7.c2
-rw-r--r--driver/gator_events_block.c2
-rw-r--r--driver/gator_events_irq.c2
-rw-r--r--driver/gator_events_l2c-310.c2
-rw-r--r--driver/gator_events_mali_4xx.c2
-rw-r--r--driver/gator_events_mali_4xx.h2
-rw-r--r--driver/gator_events_mali_common.c2
-rw-r--r--driver/gator_events_mali_common.h2
-rw-r--r--driver/gator_events_mali_midgard.c2
-rw-r--r--driver/gator_events_mali_midgard_hw.c14
-rw-r--r--driver/gator_events_mali_midgard_hw_test.c2
-rw-r--r--driver/gator_events_meminfo.c5
-rw-r--r--driver/gator_events_mmapped.c2
-rw-r--r--driver/gator_events_net.c2
-rw-r--r--driver/gator_events_perf_pmu.c47
-rw-r--r--driver/gator_events_sched.c2
-rw-r--r--driver/gator_events_scorpion.c2
-rw-r--r--driver/gator_hrtimer_gator.c2
-rw-r--r--driver/gator_iks.c2
-rw-r--r--driver/gator_main.c35
-rw-r--r--driver/gator_marshaling.c16
-rw-r--r--driver/gator_trace_gpu.c2
-rw-r--r--driver/gator_trace_power.c10
-rw-r--r--driver/gator_trace_sched.c2
-rw-r--r--driver/mali/mali_kbase_gator_api.h219
-rw-r--r--driver/mali/mali_mjollnir_profiling_gator_api.h2
-rw-r--r--driver/mali/mali_utgard_profiling_gator_api.h2
-rw-r--r--driver/mali_midgard.mk1
159 files changed, 3198 insertions, 1753 deletions
diff --git a/.gitignore b/.gitignore
index a4f82d3..7f9314d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
daemon/*.d
daemon/*.o
daemon/*_xml.h
+daemon/SrcMd5.cpp
daemon/escape
daemon/events.xml
daemon/gatord
@@ -15,4 +16,5 @@ driver/.tmp_versions
driver/Module.symvers
driver/gator.ko
driver/gator_events.h
+driver/gator_src_md5.c
driver/modules.order
diff --git a/README_Streamline.txt b/README_Streamline.txt
index 7b108d4..4ab6800 100644
--- a/README_Streamline.txt
+++ b/README_Streamline.txt
@@ -23,6 +23,8 @@ menuconfig options (depending on the kernel version, the location of these confi
- Kernel Performance Events And Counters
- [*] Kernel performance events and counters (enables CONFIG_PERF_EVENTS)
- [*] Profiling Support (enables CONFIG_PROFILING)
+- [*] Enable loadable module support (enables CONFIG_MODULES, needed unless the gator driver is built into the kernel)
+ - [*] Module unloading (enables MODULE_UNLOAD)
- Kernel Features
- [*] High Resolution Timer Support (enables CONFIG_HIGH_RES_TIMERS)
- [*] Use local timer interrupts (only required for SMP and for version before Linux 3.12, enables CONFIG_LOCAL_TIMERS)
@@ -30,6 +32,11 @@ menuconfig options (depending on the kernel version, the location of these confi
- CPU Power Management
- CPU Frequency scaling
- [*] CPU Frequency scaling (enables CONFIG_CPU_FREQ)
+- Device Drivers
+ - Graphics support
+ - ARM GPU Configuration
+ - Mali Midgard series support
+ - [*] Streamline Debug support (enables CONFIG_MALI_GATOR_SUPPORT needed as part of Mali Midgard support)
- Kernel hacking
- [*] Compile the kernel with debug info (optional, enables CONFIG_DEBUG_INFO)
- [*] Tracers
@@ -38,6 +45,7 @@ menuconfig options (depending on the kernel version, the location of these confi
(#) The "Trace process context switches and events" is not the only option that enables tracing (CONFIG_GENERIC_TRACER or CONFIG_TRACING as well as CONFIG_CONTEXT_SWITCH_TRACER) and may not be visible in menuconfig as an option if other trace configurations are enabled. Other trace configurations being enabled is sufficient to turn on tracing.
The configuration options:
+CONFIG_MODULES and MODULE_UNLOAD (not needed if the gator driver is built into the kernel)
CONFIG_GENERIC_TRACER or CONFIG_TRACING
CONFIG_CONTEXT_SWITCH_TRACER
CONFIG_PROFILING
@@ -46,6 +54,7 @@ CONFIG_LOCAL_TIMERS (for SMP systems and kernel versions before 3.12)
CONFIG_PERF_EVENTS and CONFIG_HW_PERF_EVENTS (kernel versions 3.0 and greater)
CONFIG_DEBUG_INFO (optional, used for analyzing the kernel)
CONFIG_CPU_FREQ (optional, provides frequency setting of the CPU)
+CONFIG_MALI_GATOR_SUPPORT (needed as part of Mali Midgard support)
These may be verified on a running system using /proc/config.gz (if this file exists) by running 'zcat /proc/config.gz | grep <option>'. For example, confirming that CONFIG_PROFILING is enabled
> zcat /proc/config.gz | grep CONFIG_PROFILING
@@ -63,6 +72,7 @@ To create the gator.ko module,
tar xzf /path/to/DS-5/arm/gator/driver-src/gator-driver.tar.gz
cd gator-driver
make -C <kernel_build_dir> M=`pwd` ARCH=arm CROSS_COMPILE=<...> modules
+whenever possible, use the same toolchain the kernel was built with when building gator.ko
for example when using the linaro-toolchain-binaries
make -C /home/username/kernel_2.6.32/ M=`pwd` ARCH=arm CROSS_COMPILE=/home/username/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux/bin/arm-linux-gnueabihf- modules
If successful, a gator.ko module should be generated
@@ -145,10 +155,9 @@ Attempting to run an incompatible binary often results in the confusing error me
*** Mali GPU ***
-Streamline supports Mali-400, 450, T6xx, and T7xx series GPUs with hardware activity charts, hardware & software counters and an optional 'film strip' showing periodic framebuffer snapshots. Support is chosen at build time and only one type of GPU (and version of driver) is supported at once. For best results build gator in-tree at .../drivers/gator and use the menuconfig options. Details of what these mean or how to build out of tree below.
+Streamline supports Mali-400, 450, T6xx, T7xx, and T8xx series GPUs with hardware activity charts, hardware & software counters and an optional Filmstrip showing periodic framebuffer snapshots. Support is chosen at build time and only one type of GPU (and version of driver) is supported at once. For best results build gator in-tree at .../drivers/gator and use the menuconfig options. Details of what these mean or how to build out of tree below.
Mali-4xx:
- ___To add Mali-4xx support to gator___
GATOR_WITH_MALI_SUPPORT=MALI_4xx # Set by CONFIG_GATOR_MALI_4XXMP
CONFIG_GATOR_MALI_PATH=".../path/to/Mali_DDK_kernel_files/src/devicedrv/mali" # gator source needs to #include "linux/mali_linux_trace.h"
GATOR_MALI_INTERFACE_STYLE=<3|4> # 3=Mali-400 DDK >= r3p0-04rel0 and < r3p2-01rel3
@@ -159,8 +168,7 @@ Mali-4xx:
Kernel driver needs USING_PROFILING=1 # Sets CONFIG_MALI400_PROFILING=y
See the DDK integration guide for more details (the above are the default in later driver versions)
-Mali-T6xx/T7xx:
- ___To add Mali-T6xx support to gator___
+Mali-T6xx/T7xx/T8xx (Midgard):
GATOR_WITH_MALI_SUPPORT=MALI_MIDGARD # Set by CONFIG_GATOR_MALI_MIDGARD
DDK_DIR=".../path/to/Mali_DDK_kernel_files" # gator source needs access to headers under .../kernel/drivers/gpu/arm/...
# (default of . suitable for in-tree builds)
@@ -196,6 +204,31 @@ disable SELinux so that gatorfs can be mounted by running
# setenforce 0
Once gator is started, SELinux can be reenabled
+On some versions of Android, the Mali Filmstrip may not work and produces a dmesg output similar to
+ <4>[ 585.367411] type=1400 audit(1421862808.850:48): avc: denied { search } for pid=3681 comm="mali-renderer" name="/" dev="gatorfs" ino=22378 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:unlabeled:s0 tclass=dir
+To work around this issue, use streamline_annotate.h and streamline_annotate.c from DS-5 v5.20 or later, or disable SELinux by running
+ # setenforce 0
+
+On some versions of Android, annotations may not work unless SELinux is disabled by running
+ # setenforce 0
+
+Some targets do not correctly emit uevents when cores go on/offline. This will cause CPU Activity with user space gator to be either 0% or 100% on a given core and the Heat Map may show a large number of unresolved processes. To work around this issue, user kernel space gator. To test for this run
+ # ./gatord -d | grep uevent
+When cores go on/offline with user space gator something similar to the following should be emitted
+ INFO: read(UEvent.cpp:61): uevent: offline@/devices/system/cpu/cpu1
+ INFO: read(UEvent.cpp:61): uevent: online@/devices/system/cpu/cpu1
+The core which are on/offline can be checked by running
+ # cat /sys/devices/system/cpu/cpu*/online
+This issues affects a given target if the on/offline cores shown by the cat command change but no cpu uevent is emitted.
+
+On some older versions of Android, the following issue may occur when starting gatord when using ndk-build
+ # ./gatord
+ [1] + Stopped (signal) ./gatord
+ #
+ [1] Segmentation fault ./gatord
+ #
+Starting with Android-L only position independent executables (pie) are supported, but some older versions of Android do not support them. To avoid this issue, modify Android.mk and remove the references to pie.
+
*** Profiling the kernel (optional) ***
CONFIG_DEBUG_INFO must be enabled, see "Kernel configuration" section above.
diff --git a/daemon/Android.mk b/daemon/Android.mk
index 970ac69..68f4a83 100644
--- a/daemon/Android.mk
+++ b/daemon/Android.mk
@@ -1,13 +1,12 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-XML_H := $(shell cd $(LOCAL_PATH) && make events_xml.h defaults_xml.h)
+XML_H := $(shell cd $(LOCAL_PATH) && make events_xml.h defaults_xml.h SrcMd5.cpp)
LOCAL_SRC_FILES := \
AnnotateListener.cpp \
Buffer.cpp \
CCNDriver.cpp \
- CPUFreqDriver.cpp \
CapturedXML.cpp \
Child.cpp \
Command.cpp \
@@ -43,6 +42,7 @@ LOCAL_SRC_FILES := \
SessionXML.cpp \
Setup.cpp \
Source.cpp \
+ SrcMd5.cpp \
StreamlineSetup.cpp \
UEvent.cpp \
UserSpaceSource.cpp \
diff --git a/daemon/AnnotateListener.cpp b/daemon/AnnotateListener.cpp
index 50110b4..5966cbe 100644
--- a/daemon/AnnotateListener.cpp
+++ b/daemon/AnnotateListener.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -12,36 +12,56 @@
#include "OlySocket.h"
+static const char STREAMLINE_ANNOTATE_PARENT[] = "\0streamline-annotate-parent";
+
struct AnnotateClient {
AnnotateClient *next;
int fd;
};
-AnnotateListener::AnnotateListener() : mClients(NULL), mSock(NULL) {
+AnnotateListener::AnnotateListener() : mClients(NULL), mSock(NULL), mUds(NULL) {
}
AnnotateListener::~AnnotateListener() {
close();
+ delete mUds;
delete mSock;
}
void AnnotateListener::setup() {
mSock = new OlyServerSocket(8082);
+ mUds = new OlyServerSocket(STREAMLINE_ANNOTATE_PARENT, sizeof(STREAMLINE_ANNOTATE_PARENT), true);
}
-int AnnotateListener::getFd() {
+int AnnotateListener::getSockFd() {
return mSock->getFd();
}
-void AnnotateListener::handle() {
+void AnnotateListener::handleSock() {
AnnotateClient *const client = new AnnotateClient();
client->fd = mSock->acceptConnection();
client->next = mClients;
mClients = client;
}
+int AnnotateListener::getUdsFd() {
+ return mUds->getFd();
+}
+
+void AnnotateListener::handleUds() {
+ AnnotateClient *const client = new AnnotateClient();
+ client->fd = mUds->acceptConnection();
+ client->next = mClients;
+ mClients = client;
+}
+
void AnnotateListener::close() {
- mSock->closeServerSocket();
+ if (mUds != NULL) {
+ mUds->closeServerSocket();
+ }
+ if (mSock != NULL) {
+ mSock->closeServerSocket();
+ }
while (mClients != NULL) {
::close(mClients->fd);
AnnotateClient *next = mClients->next;
diff --git a/daemon/AnnotateListener.h b/daemon/AnnotateListener.h
index cdefef1..6bc747d 100644
--- a/daemon/AnnotateListener.h
+++ b/daemon/AnnotateListener.h
@@ -1,12 +1,15 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-class AnnotateClient;
+#ifndef ANNOTATELISTENER_H
+#define ANNOTATELISTENER_H
+
+struct AnnotateClient;
class OlyServerSocket;
class AnnotateListener {
@@ -15,17 +18,22 @@ public:
~AnnotateListener();
void setup();
- int getFd();
+ int getSockFd();
+ int getUdsFd();
- void handle();
+ void handleSock();
+ void handleUds();
void close();
void signal();
private:
AnnotateClient *mClients;
OlyServerSocket *mSock;
+ OlyServerSocket *mUds;
// Intentionally unimplemented
AnnotateListener(const AnnotateListener &);
AnnotateListener &operator=(const AnnotateListener &);
};
+
+#endif // ANNOTATELISTENER_H
diff --git a/daemon/Application.mk b/daemon/Application.mk
index 3ada471..8b0a788 100644
--- a/daemon/Application.mk
+++ b/daemon/Application.mk
@@ -1,3 +1,3 @@
-APP_PLATFORM := android-8
+APP_PLATFORM := android-9
# Replace armeabi-v7a with arm64-v8a to build an arm64 gatord or with armeabi to build an ARM11 gatord
APP_ABI := armeabi-v7a
diff --git a/daemon/Buffer.cpp b/daemon/Buffer.cpp
index 8fa6280..c4ced9f 100644
--- a/daemon/Buffer.cpp
+++ b/daemon/Buffer.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,17 +13,19 @@
#include "SessionData.h"
#define mask (mSize - 1)
+#define FRAME_HEADER_SIZE 3
enum {
- CODE_PEA = 1,
- CODE_KEYS = 2,
- CODE_FORMAT = 3,
- CODE_MAPS = 4,
- CODE_COMM = 5,
- CODE_KEYS_OLD = 6,
- CODE_ONLINE_CPU = 7,
- CODE_OFFLINE_CPU = 8,
- CODE_KALLSYMS = 9,
+ CODE_PEA = 1,
+ CODE_KEYS = 2,
+ CODE_FORMAT = 3,
+ CODE_MAPS = 4,
+ CODE_COMM = 5,
+ CODE_KEYS_OLD = 6,
+ CODE_ONLINE_CPU = 7,
+ CODE_OFFLINE_CPU = 8,
+ CODE_KALLSYMS = 9,
+ CODE_COUNTERS = 10,
};
// Summary Frame Messages
@@ -47,7 +49,7 @@ enum {
Buffer::Buffer(const int32_t core, const int32_t buftype, const int size, sem_t *const readerSem) : mBuf(new char[size]), mReaderSem(readerSem), mCommitTime(gSessionData->mLiveRate), mSize(size), mReadPos(0), mWritePos(0), mCommitPos(0), mAvailable(true), mIsDone(false), mCore(core), mBufType(buftype) {
if ((mSize & mask) != 0) {
- logg->logError(__FILE__, __LINE__, "Buffer size is not a power of 2");
+ logg->logError("Buffer size is not a power of 2");
handleException();
}
sem_init(&mWriterSem, 0, 0);
@@ -141,7 +143,7 @@ int Buffer::contiguousSpaceAvailable() const {
}
}
-void Buffer::commit(const uint64_t time) {
+void Buffer::commit(const uint64_t time, const bool force) {
// post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload
const int typeLength = gSessionData->mLocalCapture ? 0 : 1;
int length = mWritePos - mCommitPos;
@@ -149,6 +151,10 @@ void Buffer::commit(const uint64_t time) {
length += mSize;
}
length = length - typeLength - sizeof(int32_t);
+ if (!force && !mIsDone && length <= FRAME_HEADER_SIZE) {
+ // Nothing to write, only the frame header is present
+ return;
+ }
for (size_t byte = 0; byte < sizeof(int32_t); byte++) {
mBuf[(mCommitPos + typeLength + byte) & mask] = (length >> byte * 8) & 0xFF;
}
@@ -317,7 +323,7 @@ void Buffer::event64(const int key, const int64_t value) {
}
}
-void Buffer::pea(const uint64_t currTime, const struct perf_event_attr *const pea, int key) {
+void Buffer::marshalPea(const uint64_t currTime, const struct perf_event_attr *const pea, int key) {
while (!checkSpace(2 * MAXSIZE_PACK32 + pea->size)) {
sem_wait(&mWriterSem);
}
@@ -327,7 +333,7 @@ void Buffer::pea(const uint64_t currTime, const struct perf_event_attr *const pe
check(currTime);
}
-void Buffer::keys(const uint64_t currTime, const int count, const __u64 *const ids, const int *const keys) {
+void Buffer::marshalKeys(const uint64_t currTime, const int count, const __u64 *const ids, const int *const keys) {
while (!checkSpace(2 * MAXSIZE_PACK32 + count * (MAXSIZE_PACK32 + MAXSIZE_PACK64))) {
sem_wait(&mWriterSem);
}
@@ -340,7 +346,7 @@ void Buffer::keys(const uint64_t currTime, const int count, const __u64 *const i
check(currTime);
}
-void Buffer::keysOld(const uint64_t currTime, const int keyCount, const int *const keys, const int bytes, const char *const buf) {
+void Buffer::marshalKeysOld(const uint64_t currTime, const int keyCount, const int *const keys, const int bytes, const char *const buf) {
while (!checkSpace((2 + keyCount) * MAXSIZE_PACK32 + bytes)) {
sem_wait(&mWriterSem);
}
@@ -353,7 +359,7 @@ void Buffer::keysOld(const uint64_t currTime, const int keyCount, const int *con
check(currTime);
}
-void Buffer::format(const uint64_t currTime, const int length, const char *const format) {
+void Buffer::marshalFormat(const uint64_t currTime, const int length, const char *const format) {
while (!checkSpace(MAXSIZE_PACK32 + length + 1)) {
sem_wait(&mWriterSem);
}
@@ -362,7 +368,7 @@ void Buffer::format(const uint64_t currTime, const int length, const char *const
check(currTime);
}
-void Buffer::maps(const uint64_t currTime, const int pid, const int tid, const char *const maps) {
+void Buffer::marshalMaps(const uint64_t currTime, const int pid, const int tid, const char *const maps) {
const int mapsLen = strlen(maps) + 1;
while (!checkSpace(3 * MAXSIZE_PACK32 + mapsLen)) {
sem_wait(&mWriterSem);
@@ -374,7 +380,7 @@ void Buffer::maps(const uint64_t currTime, const int pid, const int tid, const c
check(currTime);
}
-void Buffer::comm(const uint64_t currTime, const int pid, const int tid, const char *const image, const char *const comm) {
+void Buffer::marshalComm(const uint64_t currTime, const int pid, const int tid, const char *const image, const char *const comm) {
const int imageLen = strlen(image) + 1;
const int commLen = strlen(comm) + 1;
while (!checkSpace(3 * MAXSIZE_PACK32 + imageLen + commLen)) {
@@ -388,27 +394,27 @@ void Buffer::comm(const uint64_t currTime, const int pid, const int tid, const c
check(currTime);
}
-void Buffer::onlineCPU(const uint64_t currTime, const uint64_t time, const int cpu) {
+void Buffer::onlineCPU(const uint64_t currTime, const int cpu) {
while (!checkSpace(MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
sem_wait(&mWriterSem);
}
packInt(CODE_ONLINE_CPU);
- packInt64(time);
+ packInt64(currTime);
packInt(cpu);
check(currTime);
}
-void Buffer::offlineCPU(const uint64_t currTime, const uint64_t time, const int cpu) {
+void Buffer::offlineCPU(const uint64_t currTime, const int cpu) {
while (!checkSpace(MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
sem_wait(&mWriterSem);
}
packInt(CODE_OFFLINE_CPU);
- packInt64(time);
+ packInt64(currTime);
packInt(cpu);
check(currTime);
}
-void Buffer::kallsyms(const uint64_t currTime, const char *const kallsyms) {
+void Buffer::marshalKallsyms(const uint64_t currTime, const char *const kallsyms) {
const int kallsymsLen = strlen(kallsyms) + 1;
while (!checkSpace(3 * MAXSIZE_PACK32 + kallsymsLen)) {
sem_wait(&mWriterSem);
@@ -418,6 +424,31 @@ void Buffer::kallsyms(const uint64_t currTime, const char *const kallsyms) {
check(currTime);
}
+void Buffer::perfCounterHeader(const uint64_t time) {
+ while (!checkSpace(MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
+ sem_wait(&mWriterSem);
+ }
+ packInt(CODE_COUNTERS);
+ packInt64(time);
+}
+
+void Buffer::perfCounter(const int core, const int key, const int64_t value) {
+ while (!checkSpace(2*MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
+ sem_wait(&mWriterSem);
+ }
+ packInt(core);
+ packInt(key);
+ packInt64(value);
+}
+
+void Buffer::perfCounterFooter(const uint64_t currTime) {
+ while (!checkSpace(MAXSIZE_PACK32)) {
+ sem_wait(&mWriterSem);
+ }
+ packInt(-1);
+ check(currTime);
+}
+
void Buffer::setDone() {
mIsDone = true;
commit(0);
diff --git a/daemon/Buffer.h b/daemon/Buffer.h
index 6cffd8e..13c44e1 100644
--- a/daemon/Buffer.h
+++ b/daemon/Buffer.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -36,7 +36,7 @@ public:
int bytesAvailable() const;
int contiguousSpaceAvailable() const;
- void commit(const uint64_t time);
+ void commit(const uint64_t time, const bool force = false);
void check(const uint64_t time);
// Summary messages
@@ -50,15 +50,18 @@ public:
void event64(int key, int64_t value);
// Perf Attrs messages
- void pea(const uint64_t currTime, const struct perf_event_attr *const pea, int key);
- void keys(const uint64_t currTime, const int count, const __u64 *const ids, const int *const keys);
- void keysOld(const uint64_t currTime, const int keyCount, const int *const keys, const int bytes, const char *const buf);
- void format(const uint64_t currTime, const int length, const char *const format);
- void maps(const uint64_t currTime, const int pid, const int tid, const char *const maps);
- void comm(const uint64_t currTime, const int pid, const int tid, const char *const image, const char *const comm);
- void onlineCPU(const uint64_t currTime, const uint64_t time, const int cpu);
- void offlineCPU(const uint64_t currTime, const uint64_t time, const int cpu);
- void kallsyms(const uint64_t currTime, const char *const kallsyms);
+ void marshalPea(const uint64_t currTime, const struct perf_event_attr *const pea, int key);
+ void marshalKeys(const uint64_t currTime, const int count, const __u64 *const ids, const int *const keys);
+ void marshalKeysOld(const uint64_t currTime, const int keyCount, const int *const keys, const int bytes, const char *const buf);
+ void marshalFormat(const uint64_t currTime, const int length, const char *const format);
+ void marshalMaps(const uint64_t currTime, const int pid, const int tid, const char *const maps);
+ void marshalComm(const uint64_t currTime, const int pid, const int tid, const char *const image, const char *const comm);
+ void onlineCPU(const uint64_t currTime, const int cpu);
+ void offlineCPU(const uint64_t currTime, const int cpu);
+ void marshalKallsyms(const uint64_t currTime, const char *const kallsyms);
+ void perfCounterHeader(const uint64_t time);
+ void perfCounter(const int core, const int key, const int64_t value);
+ void perfCounterFooter(const uint64_t currTime);
void setDone();
bool isDone() const;
diff --git a/daemon/CCNDriver.cpp b/daemon/CCNDriver.cpp
index dd1a2b1..d77513a 100644
--- a/daemon/CCNDriver.cpp
+++ b/daemon/CCNDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -28,7 +28,6 @@ static const char TAG_OPTION_SET[] = "option_set";
static const char ATTR_AVERAGE_SELECTION[] = "average_selection";
static const char ATTR_COUNTER[] = "counter";
-static const char ATTR_COUNTER_SET[] = "counter_set";
static const char ATTR_COUNT[] = "count";
static const char ATTR_DESCRIPTION[] = "description";
static const char ATTR_DISPLAY[] = "display";
@@ -110,7 +109,7 @@ void CCNDriver::readEvents(mxml_node_t *const) {
int type;
if (DriverSource::readIntDriver("/sys/bus/event_source/devices/ccn/type", &type) != 0) {
- logg->logError(__FILE__, __LINE__, "Unable to read CCN-5xx type");
+ logg->logError("Unable to read CCN-5xx type");
handleException();
}
diff --git a/daemon/CCNDriver.h b/daemon/CCNDriver.h
index fb4c717..06ac33f 100644
--- a/daemon/CCNDriver.h
+++ b/daemon/CCNDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/CPUFreqDriver.cpp b/daemon/CPUFreqDriver.cpp
deleted file mode 100644
index 41f9d6f..0000000
--- a/daemon/CPUFreqDriver.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "CPUFreqDriver.h"
-
-#include "Buffer.h"
-#include "DriverSource.h"
-#include "Logging.h"
-#include "SessionData.h"
-
-CPUFreqDriver::CPUFreqDriver() : mPrev() {
-}
-
-CPUFreqDriver::~CPUFreqDriver() {
-}
-
-void CPUFreqDriver::readEvents(mxml_node_t *const) {
- // Only for use with perf
- if (!gSessionData->perf.isSetup()) {
- return;
- }
-
- setCounters(new DriverCounter(getCounters(), strdup("Linux_power_cpu_freq")));
-}
-
-void CPUFreqDriver::read(Buffer *const buffer) {
- char buf[64];
- const DriverCounter *const counter = getCounters();
- if ((counter == NULL) || !counter->isEnabled()) {
- return;
- }
-
- const int key = getCounters()->getKey();
- bool resetCores = false;
- for (int i = 0; i < gSessionData->mCores; ++i) {
- snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu%i/cpufreq/cpuinfo_cur_freq", i);
- int64_t freq;
- if (DriverSource::readInt64Driver(buf, &freq) != 0) {
- freq = 0;
- }
- if (mPrev[i] != freq) {
- mPrev[i] = freq;
- // Change cores
- buffer->event64(2, i);
- resetCores = true;
- buffer->event64(key, 1000*freq);
- }
- }
- if (resetCores) {
- // Revert cores, UserSpaceSource is all on core 0
- buffer->event64(2, 0);
- }
-}
diff --git a/daemon/CPUFreqDriver.h b/daemon/CPUFreqDriver.h
deleted file mode 100644
index ad8c9aa..0000000
--- a/daemon/CPUFreqDriver.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef CPUFREQDRIVER_H
-#define CPUFREQDRIVER_H
-
-#include "Config.h"
-#include "Driver.h"
-
-class CPUFreqDriver : public PolledDriver {
-private:
- typedef PolledDriver super;
-
-public:
- CPUFreqDriver();
- ~CPUFreqDriver();
-
- void readEvents(mxml_node_t *const root);
- void read(Buffer *const buffer);
-
-private:
- int64_t mPrev[NR_CPUS];
-
- // Intentionally unimplemented
- CPUFreqDriver(const CPUFreqDriver &);
- CPUFreqDriver &operator=(const CPUFreqDriver &);
-};
-
-#endif // CPUFREQDRIVER_H
diff --git a/daemon/CapturedXML.cpp b/daemon/CapturedXML.cpp
index 0b5802c..1854c77 100644
--- a/daemon/CapturedXML.cpp
+++ b/daemon/CapturedXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,7 +34,6 @@ mxml_node_t* CapturedXML::getTree(bool includeTime) {
mxmlElementSetAttr(captured, "version", "1");
if (gSessionData->perf.isSetup()) {
mxmlElementSetAttr(captured, "type", "Perf");
- mxmlElementSetAttr(captured, "perf_beta", "yes");
}
mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION);
if (includeTime) { // Send the following only after the capture is complete
@@ -98,7 +97,7 @@ void CapturedXML::write(char* path) {
char* xml = getXML(true);
if (util->writeToDisk(file, xml) < 0) {
- logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file);
+ logg->logError("Error writing %s\nPlease verify the path.", file);
handleException();
}
diff --git a/daemon/CapturedXML.h b/daemon/CapturedXML.h
index b704f6e..69d80c0 100644
--- a/daemon/CapturedXML.h
+++ b/daemon/CapturedXML.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Child.cpp b/daemon/Child.cpp
index 6b5bbb3..a19e9cf 100644
--- a/daemon/Child.cpp
+++ b/daemon/Child.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -150,13 +150,12 @@ static void *senderThread(void *) {
prctl(PR_SET_NAME, (unsigned long)&"gatord-sender", 0, 0, 0);
sem_wait(&haltPipeline);
- while (!primarySource->isDone() ||
- !externalSource->isDone() ||
+ while (!externalSource->isDone() ||
(userSpaceSource != NULL && !userSpaceSource->isDone()) ||
- (ftraceSource != NULL && !ftraceSource->isDone())) {
+ (ftraceSource != NULL && !ftraceSource->isDone()) ||
+ !primarySource->isDone()) {
sem_wait(&senderSem);
- primarySource->write(sender);
externalSource->write(sender);
if (userSpaceSource != NULL) {
userSpaceSource->write(sender);
@@ -164,6 +163,7 @@ static void *senderThread(void *) {
if (ftraceSource != NULL) {
ftraceSource->write(sender);
}
+ primarySource->write(sender);
}
// write end-of-capture sequence
@@ -232,7 +232,7 @@ void Child::run() {
sender = new Sender(socket);
if (mNumConnections > 1) {
- logg->logError(__FILE__, __LINE__, "Session already in progress");
+ logg->logError("Session already in progress");
handleException();
}
@@ -267,7 +267,7 @@ void Child::run() {
char* xmlString;
xmlString = util->readFromDisk(gSessionData->mSessionXMLPath);
if (xmlString == 0) {
- logg->logError(__FILE__, __LINE__, "Unable to read session xml file: %s", gSessionData->mSessionXMLPath);
+ logg->logError("Unable to read session xml file: %s", gSessionData->mSessionXMLPath);
handleException();
}
gSessionData->parseSessionXML(xmlString);
@@ -280,16 +280,27 @@ void Child::run() {
}
if (gSessionData->kmod.isMaliCapture() && (gSessionData->mSampleRate == 0)) {
- logg->logError(__FILE__, __LINE__, "Mali counters are not supported with Sample Rate: None.");
+ logg->logError("Mali counters are not supported with Sample Rate: None.");
handleException();
}
+ // Initialize ftrace source before child as it's slow and dependens on nothing else
+ // If initialized later, us gator with ftrace has time sync issues
+ if (gSessionData->ftraceDriver.countersEnabled()) {
+ ftraceSource = new FtraceSource(&senderSem);
+ if (!ftraceSource->prepare()) {
+ logg->logError("Unable to prepare userspace source for capture");
+ handleException();
+ }
+ ftraceSource->start();
+ }
+
// Must be after session XML is parsed
if (!primarySource->prepare()) {
if (gSessionData->perf.isSetup()) {
- logg->logError(__FILE__, __LINE__, "Unable to prepare gator driver for capture");
+ logg->logError("Unable to communicate with the perf API, please ensure that CONFIG_TRACING and CONFIG_CONTEXT_SWITCH_TRACER are enabled. Please refer to README_Streamline.txt for more information.");
} else {
- logg->logError(__FILE__, __LINE__, "Unable to communicate with the perf API, please ensure that CONFIG_TRACING and CONFIG_CONTEXT_SWITCH_TRACER are enabled. Please refer to README_Streamline.txt for more information.");
+ logg->logError("Unable to prepare gator driver for capture");
}
handleException();
}
@@ -300,7 +311,7 @@ void Child::run() {
// Must be initialized before senderThread is started as senderThread checks externalSource
externalSource = new ExternalSource(&senderSem);
if (!externalSource->prepare()) {
- logg->logError(__FILE__, __LINE__, "Unable to prepare external source for capture");
+ logg->logError("Unable to prepare external source for capture");
handleException();
}
externalSource->start();
@@ -324,21 +335,12 @@ void Child::run() {
if (startUSSource) {
userSpaceSource = new UserSpaceSource(&senderSem);
if (!userSpaceSource->prepare()) {
- logg->logError(__FILE__, __LINE__, "Unable to prepare userspace source for capture");
+ logg->logError("Unable to prepare userspace source for capture");
handleException();
}
userSpaceSource->start();
}
- if (gSessionData->ftraceDriver.countersEnabled()) {
- ftraceSource = new FtraceSource(&senderSem);
- if (!ftraceSource->prepare()) {
- logg->logError(__FILE__, __LINE__, "Unable to prepare userspace source for capture");
- handleException();
- }
- ftraceSource->start();
- }
-
if (gSessionData->mAllowCommands && (gSessionData->mCaptureCommand != NULL)) {
pthread_t thread;
if (pthread_create(&thread, NULL, commandThread, NULL)) {
@@ -347,7 +349,7 @@ void Child::run() {
}
if (!thread_creation_success) {
- logg->logError(__FILE__, __LINE__, "Failed to create gator threads");
+ logg->logError("Failed to create gator threads");
handleException();
}
@@ -357,6 +359,7 @@ void Child::run() {
// Start profiling
primarySource->run();
+ // Wait for the other threads to exit
if (ftraceSource != NULL) {
ftraceSource->join();
}
@@ -364,8 +367,6 @@ void Child::run() {
userSpaceSource->join();
}
externalSource->join();
-
- // Wait for the other threads to exit
pthread_join(senderThreadID, NULL);
// Shutting down the connection should break the stop thread which is stalling on the socket recv() function
diff --git a/daemon/Child.h b/daemon/Child.h
index cc78202..a6c54db 100644
--- a/daemon/Child.h
+++ b/daemon/Child.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Command.cpp b/daemon/Command.cpp
index 28d73cf..0a6e3b9 100644
--- a/daemon/Command.cpp
+++ b/daemon/Command.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -39,7 +39,7 @@ static int getUid(const char *const name, char *const shPath, const char *const
const int pid = fork();
if (pid < 0) {
- logg->logError(__FILE__, __LINE__, "fork failed");
+ logg->logError("fork failed");
handleException();
}
if (pid == 0) {
@@ -94,7 +94,7 @@ void *commandThread(void *) {
const char *const name = gSessionData->mCaptureUser == NULL ? "nobody" : gSessionData->mCaptureUser;
const int uid = getUid(name);
if (uid < 0) {
- logg->logError(__FILE__, __LINE__, "Unable to lookup the user %s, please double check that the user exists", name);
+ logg->logError("Unable to look up the user %s, please double check that the user exists", name);
handleException();
}
@@ -103,13 +103,13 @@ void *commandThread(void *) {
char buf[128];
int pipefd[2];
if (pipe_cloexec(pipefd) != 0) {
- logg->logError(__FILE__, __LINE__, "pipe failed");
+ logg->logError("pipe failed");
handleException();
}
const int pid = fork();
if (pid < 0) {
- logg->logError(__FILE__, __LINE__, "fork failed");
+ logg->logError("fork failed");
handleException();
}
if (pid == 0) {
@@ -163,7 +163,7 @@ void *commandThread(void *) {
close(pipefd[1]);
const ssize_t bytes = read(pipefd[0], buf, sizeof(buf));
if (bytes > 0) {
- logg->logError(__FILE__, __LINE__, buf);
+ logg->logError("%s", buf);
handleException();
}
close(pipefd[0]);
diff --git a/daemon/Command.h b/daemon/Command.h
index 17244b7..2838adc 100644
--- a/daemon/Command.h
+++ b/daemon/Command.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Config.h b/daemon/Config.h
index bee383a..eb31556 100644
--- a/daemon/Config.h
+++ b/daemon/Config.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/ConfigurationXML.cpp b/daemon/ConfigurationXML.cpp
index 6590dd3..be224a4 100644
--- a/daemon/ConfigurationXML.cpp
+++ b/daemon/ConfigurationXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -106,7 +106,7 @@ void ConfigurationXML::validate(void) {
const Counter & counter = gSessionData->mCounters[i];
if (counter.isEnabled()) {
if (strcmp(counter.getType(), "") == 0) {
- logg->logError(__FILE__, __LINE__, "Invalid required attribute in configuration.xml:\n counter=\"%s\"\n event=%d\n", counter.getType(), counter.getEvent());
+ logg->logError("Invalid required attribute in configuration.xml:\n counter=\"%s\"\n event=%d\n", counter.getType(), counter.getEvent());
handleException();
}
@@ -116,7 +116,7 @@ void ConfigurationXML::validate(void) {
if (counter2.isEnabled()) {
// check if the types are the same
if (strcmp(counter.getType(), counter2.getType()) == 0) {
- logg->logError(__FILE__, __LINE__, "Duplicate performance counter type in configuration.xml: %s", counter.getType());
+ logg->logError("Duplicate performance counter type in configuration.xml: %s", counter.getType());
handleException();
}
}
@@ -169,7 +169,7 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
for (Driver *driver = Driver::getHead(); driver != NULL; driver = driver->getNext()) {
if (driver->claimCounter(counter)) {
if (counter.getDriver() != NULL) {
- logg->logError(__FILE__, __LINE__, "More than one driver has claimed %s:%i", counter.getType(), counter.getEvent());
+ logg->logError("More than one driver has claimed %s:%i", counter.getType(), counter.getEvent());
handleException();
}
counter.setDriver(driver);
@@ -210,7 +210,7 @@ void ConfigurationXML::remove() {
getPath(path);
if (::remove(path) != 0) {
- logg->logError(__FILE__, __LINE__, "Invalid configuration.xml file detected and unable to delete it. To resolve, delete configuration.xml on disk");
+ logg->logError("Invalid configuration.xml file detected and unable to delete it. To resolve, delete configuration.xml on disk");
handleException();
}
logg->logMessage("Invalid configuration.xml file detected and removed");
diff --git a/daemon/ConfigurationXML.h b/daemon/ConfigurationXML.h
index efa415e..a986ce9 100644
--- a/daemon/ConfigurationXML.h
+++ b/daemon/ConfigurationXML.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Counter.h b/daemon/Counter.h
index 5202aa0..a4c22f5 100644
--- a/daemon/Counter.h
+++ b/daemon/Counter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/DiskIODriver.cpp b/daemon/DiskIODriver.cpp
index 5deb0f3..af62bb9 100644
--- a/daemon/DiskIODriver.cpp
+++ b/daemon/DiskIODriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -67,7 +67,7 @@ void DiskIODriver::doRead() {
}
if (!mBuf.read("/proc/diskstats")) {
- logg->logError(__FILE__, __LINE__, "Unable to read /proc/diskstats");
+ logg->logError("Unable to read /proc/diskstats");
handleException();
}
@@ -76,9 +76,9 @@ void DiskIODriver::doRead() {
char *lastName = NULL;
int lastNameLen = -1;
- char *start = mBuf.getBuf();
- while (*start != '\0') {
- char *end = strchr(start, '\n');
+ char *line = mBuf.getBuf();
+ while (*line != '\0') {
+ char *end = strchr(line, '\n');
if (end != NULL) {
*end = '\0';
}
@@ -87,15 +87,15 @@ void DiskIODriver::doRead() {
int nameEnd = -1;
int64_t readBytes = -1;
int64_t writeBytes = -1;
- const int count = sscanf(start, "%*d %*d %n%*s%n %*u %*u %" SCNu64 " %*u %*u %*u %" SCNu64, &nameStart, &nameEnd, &readBytes, &writeBytes);
+ const int count = sscanf(line, "%*d %*d %n%*s%n %*u %*u %" SCNu64 " %*u %*u %*u %" SCNu64, &nameStart, &nameEnd, &readBytes, &writeBytes);
if (count != 2) {
- logg->logError(__FILE__, __LINE__, "Unable to parse /proc/diskstats");
+ logg->logError("Unable to parse /proc/diskstats");
handleException();
}
// Skip partitions which are identified if the name is a substring of the last non-partition
- if ((lastName == NULL) || (strncmp(lastName, start + nameStart, lastNameLen) != 0)) {
- lastName = start + nameStart;
+ if ((lastName == NULL) || (strncmp(lastName, line + nameStart, lastNameLen) != 0)) {
+ lastName = line + nameStart;
lastNameLen = nameEnd - nameStart;
mReadBytes += readBytes;
mWriteBytes += writeBytes;
@@ -104,7 +104,7 @@ void DiskIODriver::doRead() {
if (end == NULL) {
break;
}
- start = end + 1;
+ line = end + 1;
}
}
diff --git a/daemon/DiskIODriver.h b/daemon/DiskIODriver.h
index d0db18c..6ecda5a 100644
--- a/daemon/DiskIODriver.h
+++ b/daemon/DiskIODriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Driver.cpp b/daemon/Driver.cpp
index 275da31..72c7314 100644
--- a/daemon/Driver.cpp
+++ b/daemon/Driver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Driver.h b/daemon/Driver.h
index 72870e3..19ec127 100644
--- a/daemon/Driver.h
+++ b/daemon/Driver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/DriverSource.cpp b/daemon/DriverSource.cpp
index 7f299b6..34920ce 100644
--- a/daemon/DriverSource.cpp
+++ b/daemon/DriverSource.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -32,7 +32,7 @@ DriverSource::DriverSource(sem_t *senderSem, sem_t *startProfile) : mBuffer(NULL
mBuffer = new Buffer(0, FRAME_PERF_ATTRS, 4*1024*1024, senderSem);
if (readIntDriver("/dev/gator/version", &driver_version) == -1) {
- logg->logError(__FILE__, __LINE__, "Error reading gator driver version");
+ logg->logError("Error reading gator driver version");
handleException();
}
@@ -40,7 +40,7 @@ DriverSource::DriverSource(sem_t *senderSem, sem_t *startProfile) : mBuffer(NULL
if (driver_version != PROTOCOL_VERSION) {
if ((driver_version > PROTOCOL_DEV) || (PROTOCOL_VERSION > PROTOCOL_DEV)) {
// One of the mismatched versions is development version
- logg->logError(__FILE__, __LINE__,
+ logg->logError(
"DEVELOPMENT BUILD MISMATCH: gator driver version \"%d\" is not in sync with gator daemon version \"%d\".\n"
">> The following must be synchronized from engineering repository:\n"
">> * gator driver\n"
@@ -49,7 +49,7 @@ DriverSource::DriverSource(sem_t *senderSem, sem_t *startProfile) : mBuffer(NULL
handleException();
} else {
// Release version mismatch
- logg->logError(__FILE__, __LINE__,
+ logg->logError(
"gator driver version \"%d\" is different than gator daemon version \"%d\".\n"
">> Please upgrade the driver and daemon to the latest versions.", driver_version, PROTOCOL_VERSION);
handleException();
@@ -58,7 +58,7 @@ DriverSource::DriverSource(sem_t *senderSem, sem_t *startProfile) : mBuffer(NULL
int enable = -1;
if (readIntDriver("/dev/gator/enable", &enable) != 0 || enable != 0) {
- logg->logError(__FILE__, __LINE__, "Driver already enabled, possibly a session is already in progress.");
+ logg->logError("Driver already enabled, possibly a session is already in progress.");
handleException();
}
@@ -68,7 +68,7 @@ DriverSource::DriverSource(sem_t *senderSem, sem_t *startProfile) : mBuffer(NULL
}
if (readIntDriver("/dev/gator/buffer_size", &mBufferSize) || mBufferSize <= 0) {
- logg->logError(__FILE__, __LINE__, "Unable to read the driver buffer size");
+ logg->logError("Unable to read the driver buffer size");
handleException();
}
}
@@ -99,10 +99,11 @@ void DriverSource::bootstrapThread() {
DynBuf printb;
DynBuf b1;
DynBuf b2;
- const uint64_t currTime = getTime();
+ // MonotonicStarted may not be not assigned yet
+ const uint64_t currTime = 0;//getTime() - gSessionData->mMonotonicStarted;
if (!readProcComms(currTime, mBuffer, &printb, &b1, &b2)) {
- logg->logError(__FILE__, __LINE__, "readProcComms failed");
+ logg->logError("readProcComms failed");
handleException();
}
@@ -124,33 +125,33 @@ void DriverSource::run() {
// Set the maximum backtrace depth
if (writeReadDriver("/dev/gator/backtrace_depth", &gSessionData->mBacktraceDepth)) {
- logg->logError(__FILE__, __LINE__, "Unable to set the driver backtrace depth");
+ logg->logError("Unable to set the driver backtrace depth");
handleException();
}
// open the buffer which calls userspace_buffer_open() in the driver
mBufferFD = open("/dev/gator/buffer", O_RDONLY | O_CLOEXEC);
if (mBufferFD < 0) {
- logg->logError(__FILE__, __LINE__, "The gator driver did not set up properly. Please view the linux console or dmesg log for more information on the failure.");
+ logg->logError("The gator driver did not set up properly. Please view the linux console or dmesg log for more information on the failure.");
handleException();
}
// set the tick rate of the profiling timer
if (writeReadDriver("/dev/gator/tick", &gSessionData->mSampleRate) != 0) {
- logg->logError(__FILE__, __LINE__, "Unable to set the driver tick");
+ logg->logError("Unable to set the driver tick");
handleException();
}
// notify the kernel of the response type
int response_type = gSessionData->mLocalCapture ? 0 : RESPONSE_APC_DATA;
if (writeDriver("/dev/gator/response_type", response_type)) {
- logg->logError(__FILE__, __LINE__, "Unable to write the response type");
+ logg->logError("Unable to write the response type");
handleException();
}
// Set the live rate
if (writeReadDriver("/dev/gator/live_rate", &gSessionData->mLiveRate)) {
- logg->logError(__FILE__, __LINE__, "Unable to set the driver live rate");
+ logg->logError("Unable to set the driver live rate");
handleException();
}
@@ -158,7 +159,7 @@ void DriverSource::run() {
// This command makes the driver start profiling by calling gator_op_start() in the driver
if (writeDriver("/dev/gator/enable", "1") != 0) {
- logg->logError(__FILE__, __LINE__, "The gator driver did not start properly. Please view the linux console or dmesg log for more information on the failure.");
+ logg->logError("The gator driver did not start properly. Please view the linux console or dmesg log for more information on the failure.");
handleException();
}
@@ -168,7 +169,7 @@ void DriverSource::run() {
pthread_t bootstrapThreadID;
if (pthread_create(&bootstrapThreadID, NULL, bootstrapThreadStatic, this) != 0) {
- logg->logError(__FILE__, __LINE__, "Unable to start the gator_bootstrap thread");
+ logg->logError("Unable to start the gator_bootstrap thread");
handleException();
}
@@ -190,7 +191,7 @@ void DriverSource::run() {
// In one shot mode, stop collection once all the buffers are filled
if (gSessionData->mOneShot && gSessionData->mSessionIsActive) {
if (bytesCollected == -1 || mFifo->willFill(bytesCollected)) {
- logg->logMessage("One shot");
+ logg->logMessage("One shot (gator.ko)");
child->endSession();
}
}
diff --git a/daemon/DriverSource.h b/daemon/DriverSource.h
index ec27b08..32d983d 100644
--- a/daemon/DriverSource.h
+++ b/daemon/DriverSource.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/DynBuf.cpp b/daemon/DynBuf.cpp
index df20713..690cbcb 100644
--- a/daemon/DynBuf.cpp
+++ b/daemon/DynBuf.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -42,7 +42,7 @@ bool DynBuf::read(const char *const path) {
const int fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
- logg->logMessage("%s(%s:%i): open failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("open failed");
return false;
}
@@ -52,14 +52,14 @@ bool DynBuf::read(const char *const path) {
const size_t minCapacity = length + MIN_BUFFER_FREE + 1;
if (capacity < minCapacity) {
if (resize(minCapacity) != 0) {
- logg->logMessage("%s(%s:%i): DynBuf::resize failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::resize failed");
goto fail;
}
}
const ssize_t bytes = ::read(fd, buf + length, capacity - length - 1);
if (bytes < 0) {
- logg->logMessage("%s(%s:%i): read failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("read failed");
goto fail;
} else if (bytes == 0) {
break;
@@ -105,7 +105,7 @@ bool DynBuf::printf(const char *format, ...) {
if (capacity <= 0) {
if (resize(2 * MIN_BUFFER_FREE) != 0) {
- logg->logMessage("%s(%s:%i): DynBuf::resize failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::resize failed");
return false;
}
}
@@ -114,13 +114,13 @@ bool DynBuf::printf(const char *format, ...) {
int bytes = vsnprintf(buf, capacity, format, ap);
va_end(ap);
if (bytes < 0) {
- logg->logMessage("%s(%s:%i): fsnprintf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("fsnprintf failed");
return false;
}
if (static_cast<size_t>(bytes) > capacity) {
if (resize(bytes + 1) != 0) {
- logg->logMessage("%s(%s:%i): DynBuf::resize failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::resize failed");
return false;
}
@@ -128,7 +128,7 @@ bool DynBuf::printf(const char *format, ...) {
bytes = vsnprintf(buf, capacity, format, ap);
va_end(ap);
if (bytes < 0) {
- logg->logMessage("%s(%s:%i): fsnprintf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("fsnprintf failed");
return false;
}
}
diff --git a/daemon/DynBuf.h b/daemon/DynBuf.h
index 2f4554a..da83cd6 100644
--- a/daemon/DynBuf.h
+++ b/daemon/DynBuf.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/EventsXML.cpp b/daemon/EventsXML.cpp
index d905bba..3fe5ecd 100644
--- a/daemon/EventsXML.cpp
+++ b/daemon/EventsXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,10 +13,35 @@
#include "OlyUtility.h"
#include "SessionData.h"
+class XMLList {
+public:
+ XMLList(XMLList *const prev, mxml_node_t *const node) : mPrev(prev), mNode(node) {}
+
+ XMLList *getPrev() { return mPrev; }
+ mxml_node_t *getNode() const { return mNode; }
+ void setNode(mxml_node_t *const node) { mNode = node; }
+
+ static void free(XMLList *list) {
+ while (list != NULL) {
+ XMLList *prev = list->getPrev();
+ delete list;
+ list = prev;
+ }
+ }
+
+private:
+ XMLList *const mPrev;
+ mxml_node_t *mNode;
+
+ // Intentionally unimplemented
+ XMLList(const XMLList &);
+ XMLList &operator=(const XMLList &);
+};
+
mxml_node_t *EventsXML::getTree() {
#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len
char path[PATH_MAX];
- mxml_node_t *xml;
+ mxml_node_t *xml = NULL;
FILE *fl;
// Avoid unused variable warning
@@ -25,19 +50,147 @@ mxml_node_t *EventsXML::getTree() {
// Load the provided or default events xml
if (gSessionData->mEventsXMLPath) {
strncpy(path, gSessionData->mEventsXMLPath, PATH_MAX);
- } else {
- util->getApplicationFullPath(path, PATH_MAX);
- strncat(path, "events.xml", PATH_MAX - strlen(path) - 1);
+ fl = fopen(path, "r");
+ if (fl) {
+ xml = mxmlLoadFile(NULL, fl, MXML_NO_CALLBACK);
+ fclose(fl);
+ }
}
- fl = fopen(path, "r");
- if (fl) {
- xml = mxmlLoadFile(NULL, fl, MXML_NO_CALLBACK);
- fclose(fl);
- } else {
+ if (xml == NULL) {
logg->logMessage("Unable to locate events.xml, using default");
xml = mxmlLoadString(NULL, (const char *)events_xml, MXML_NO_CALLBACK);
}
+ // Append additional events XML
+ if (gSessionData->mEventsXMLAppend) {
+ fl = fopen(gSessionData->mEventsXMLAppend, "r");
+ if (fl == NULL) {
+ logg->logError("Unable to open additional events XML %s", gSessionData->mEventsXMLAppend);
+ handleException();
+ }
+ mxml_node_t *append = mxmlLoadFile(NULL, fl, MXML_NO_CALLBACK);
+ fclose(fl);
+
+ mxml_node_t *events = mxmlFindElement(xml, xml, "events", NULL, NULL, MXML_DESCEND);
+ if (!events) {
+ logg->logError("Unable to find <events> node in the events.xml, please ensure the first two lines of events XML starts with:\n"
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<events>");
+ handleException();
+ }
+
+ XMLList *categoryList = NULL;
+ XMLList *eventList = NULL;
+ {
+ // Make list of all categories in xml
+ mxml_node_t *node = xml;
+ while (true) {
+ node = mxmlFindElement(node, xml, "category", NULL, NULL, MXML_DESCEND);
+ if (node == NULL) {
+ break;
+ }
+ categoryList = new XMLList(categoryList, node);
+ }
+
+ // Make list of all events in xml
+ node = xml;
+ while (true) {
+ node = mxmlFindElement(node, xml, "event", NULL, NULL, MXML_DESCEND);
+ if (node == NULL) {
+ break;
+ }
+ eventList = new XMLList(eventList, node);
+ }
+ }
+
+ // Handle events
+ for (mxml_node_t *node = mxmlFindElement(append, append, "event", NULL, NULL, MXML_DESCEND),
+ *next = mxmlFindElement(node, append, "event", NULL, NULL, MXML_DESCEND);
+ node != NULL;
+ node = next, next = mxmlFindElement(node, append, "event", NULL, NULL, MXML_DESCEND)) {
+ const char *const category = mxmlElementGetAttr(mxmlGetParent(node), "name");
+ const char *const title = mxmlElementGetAttr(node, "title");
+ const char *const name = mxmlElementGetAttr(node, "name");
+ if (category == NULL || title == NULL || name == NULL) {
+ logg->logError("Not all event XML nodes have the required title and name and parent name attributes");
+ handleException();
+ }
+
+ // Replace any duplicate events
+ for (XMLList *event = eventList; event != NULL; event = event->getPrev()) {
+ const char *const category2 = mxmlElementGetAttr(mxmlGetParent(event->getNode()), "name");
+ const char *const title2 = mxmlElementGetAttr(event->getNode(), "title");
+ const char *const name2 = mxmlElementGetAttr(event->getNode(), "name");
+ if (category2 == NULL || title2 == NULL || name2 == NULL) {
+ logg->logError("Not all event XML nodes have the required title and name and parent name attributes");
+ handleException();
+ }
+
+ if (strcmp(category, category2) == 0 && strcmp(title, title2) == 0 && strcmp(name, name2) == 0) {
+ logg->logMessage("Replacing counter %s %s: %s", category, title, name);
+ mxml_node_t *parent = mxmlGetParent(event->getNode());
+ mxmlDelete(event->getNode());
+ mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
+ event->setNode(node);
+ break;
+ }
+ }
+ }
+
+ // Handle categories
+ for (mxml_node_t *node = mxmlFindElement(append, append, "category", NULL, NULL, MXML_DESCEND),
+ *next = mxmlFindElement(node, append, "category", NULL, NULL, MXML_DESCEND);
+ node != NULL;
+ node = next, next = mxmlFindElement(node, append, "category", NULL, NULL, MXML_DESCEND)) {
+ // After replacing duplicate events, a category may be empty
+ if (mxmlGetFirstChild(node) == NULL) {
+ continue;
+ }
+
+ const char *const name = mxmlElementGetAttr(node, "name");
+ if (name == NULL) {
+ logg->logError("Not all event XML categories have the required name attribute");
+ handleException();
+ }
+
+ // Merge identically named categories
+ bool merged = false;
+ for (XMLList *category = categoryList; category != NULL; category = category->getPrev()) {
+ const char *const name2 = mxmlElementGetAttr(category->getNode(), "name");
+ if (name2 == NULL) {
+ logg->logError("Not all event XML categories have the required name attribute");
+ handleException();
+ }
+
+ if (strcmp(name, name2) == 0) {
+ logg->logMessage("Merging category %s", name);
+ while (true) {
+ mxml_node_t *child = mxmlGetFirstChild(node);
+ if (child == NULL) {
+ break;
+ }
+ mxmlAdd(category->getNode(), MXML_ADD_AFTER, mxmlGetLastChild(category->getNode()), child);
+ }
+ merged = true;
+ break;
+ }
+ }
+
+ if (merged) {
+ continue;
+ }
+
+ // Add new categories
+ logg->logMessage("Appending category %s", name);
+ mxmlAdd(events, MXML_ADD_AFTER, mxmlGetLastChild(events), node);
+ }
+
+ XMLList::free(eventList);
+ XMLList::free(categoryList);
+
+ mxmlDelete(append);
+ }
+
return xml;
}
@@ -47,7 +200,9 @@ char *EventsXML::getXML() {
// Add dynamic events from the drivers
mxml_node_t *events = mxmlFindElement(xml, xml, "events", NULL, NULL, MXML_DESCEND);
if (!events) {
- logg->logError(__FILE__, __LINE__, "Unable to find <events> node in the events.xml");
+ logg->logError("Unable to find <events> node in the events.xml, please ensure the first two lines of events XML are:\n"
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<events>");
handleException();
}
for (Driver *driver = Driver::getHead(); driver != NULL; driver = driver->getNext()) {
@@ -68,7 +223,7 @@ void EventsXML::write(const char *path) {
char *buf = getXML();
if (util->writeToDisk(file, buf) < 0) {
- logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file);
+ logg->logError("Error writing %s\nPlease verify the path.", file);
handleException();
}
diff --git a/daemon/EventsXML.h b/daemon/EventsXML.h
index ff7a02f..2b38fa4 100644
--- a/daemon/EventsXML.h
+++ b/daemon/EventsXML.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,9 +13,16 @@
class EventsXML {
public:
+ EventsXML() {}
+
mxml_node_t *getTree();
char *getXML();
void write(const char* path);
+
+private:
+ // Intentionally unimplemented
+ EventsXML(const EventsXML &);
+ EventsXML &operator=(const EventsXML &);
};
#endif // EVENTS_XML
diff --git a/daemon/ExternalSource.cpp b/daemon/ExternalSource.cpp
index 8f5e6b6..8d71b6d 100644
--- a/daemon/ExternalSource.cpp
+++ b/daemon/ExternalSource.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -12,10 +12,14 @@
#include <sys/prctl.h>
#include <unistd.h>
+#include "Child.h"
#include "Logging.h"
#include "OlySocket.h"
#include "SessionData.h"
+extern Child *child;
+
+static const char STREAMLINE_ANNOTATE[] = "\0streamline-annotate";
static const char MALI_VIDEO[] = "\0mali-video";
static const char MALI_VIDEO_STARTUP[] = "\0mali-video-startup";
static const char MALI_VIDEO_V1[] = "MALI_VIDEO 1\n";
@@ -40,7 +44,7 @@ static bool setNonblock(const int fd) {
return true;
}
-ExternalSource::ExternalSource(sem_t *senderSem) : mBuffer(0, FRAME_EXTERNAL, 128*1024, senderSem), mMonitor(), mMveStartupUds(MALI_VIDEO_STARTUP, sizeof(MALI_VIDEO_STARTUP)), mMaliStartupUds(MALI_GRAPHICS_STARTUP, sizeof(MALI_GRAPHICS_STARTUP)), mAnnotate(8083), mInterruptFd(-1), mMaliUds(-1), mMveUds(-1) {
+ExternalSource::ExternalSource(sem_t *senderSem) : mBuffer(0, FRAME_EXTERNAL, 128*1024, senderSem), mMonitor(), mMveStartupUds(MALI_VIDEO_STARTUP, sizeof(MALI_VIDEO_STARTUP)), mMaliStartupUds(MALI_GRAPHICS_STARTUP, sizeof(MALI_GRAPHICS_STARTUP)), mAnnotate(8083), mAnnotateUds(STREAMLINE_ANNOTATE, sizeof(STREAMLINE_ANNOTATE), true), mInterruptFd(-1), mMaliUds(-1), mMveUds(-1) {
sem_init(&mBufferSem, 0, 0);
}
@@ -49,18 +53,22 @@ ExternalSource::~ExternalSource() {
void ExternalSource::waitFor(const int bytes) {
while (mBuffer.bytesAvailable() <= bytes) {
+ if (gSessionData->mOneShot && gSessionData->mSessionIsActive) {
+ logg->logMessage("One shot (external)");
+ child->endSession();
+ }
sem_wait(&mBufferSem);
}
}
void ExternalSource::configureConnection(const int fd, const char *const handshake, size_t size) {
if (!setNonblock(fd)) {
- logg->logError(__FILE__, __LINE__, "Unable to set nonblock on fh");
+ logg->logError("Unable to set nonblock on fh");
handleException();
}
if (!mMonitor.add(fd)) {
- logg->logError(__FILE__, __LINE__, "Unable to add fh to monitor");
+ logg->logError("Unable to add fh to monitor");
handleException();
}
@@ -68,7 +76,7 @@ void ExternalSource::configureConnection(const int fd, const char *const handsha
waitFor(Buffer::MAXSIZE_PACK32 + size - 1);
mBuffer.packInt(fd);
mBuffer.writeBytes(handshake, size - 1);
- mBuffer.commit(1);
+ mBuffer.commit(1, true);
}
bool ExternalSource::connectMali() {
@@ -106,6 +114,7 @@ bool ExternalSource::prepare() {
!setNonblock(mMveStartupUds.getFd()) || !mMonitor.add(mMveStartupUds.getFd()) ||
!setNonblock(mMaliStartupUds.getFd()) || !mMonitor.add(mMaliStartupUds.getFd()) ||
!setNonblock(mAnnotate.getFd()) || !mMonitor.add(mAnnotate.getFd()) ||
+ !setNonblock(mAnnotateUds.getFd()) || !mMonitor.add(mAnnotateUds.getFd()) ||
false) {
return false;
}
@@ -122,18 +131,21 @@ void ExternalSource::run() {
prctl(PR_SET_NAME, (unsigned long)&"gatord-external", 0, 0, 0);
if (pipe_cloexec(pipefd) != 0) {
- logg->logError(__FILE__, __LINE__, "pipe failed");
+ logg->logError("pipe failed");
handleException();
}
mInterruptFd = pipefd[1];
if (!mMonitor.add(pipefd[0])) {
- logg->logError(__FILE__, __LINE__, "Monitor::add failed");
+ logg->logError("Monitor::add failed");
handleException();
}
// Notify annotate clients to retry connecting to gatord
- gSessionData->annotateListener.signal();
+ uint64_t val = 1;
+ if (::write(gSessionData->mAnnotateStart, &val, sizeof(val)) != sizeof(val)) {
+ logg->logMessage("Writing to annotate pipe failed");
+ }
while (gSessionData->mSessionIsActive) {
struct epoll_event events[16];
@@ -141,11 +153,11 @@ void ExternalSource::run() {
while (sem_trywait(&mBufferSem) == 0);
int ready = mMonitor.wait(events, ARRAY_LENGTH(events), -1);
if (ready < 0) {
- logg->logError(__FILE__, __LINE__, "Monitor::wait failed");
+ logg->logError("Monitor::wait failed");
handleException();
}
- const uint64_t currTime = getTime();
+ const uint64_t currTime = getTime() - gSessionData->mMonotonicStarted;
for (int i = 0; i < ready; ++i) {
const int fd = events[i].data.fd;
@@ -155,7 +167,7 @@ void ExternalSource::run() {
// Don't read from this connection, establish a new connection to Mali-V500
close(client);
if (!connectMve()) {
- logg->logError(__FILE__, __LINE__, "Unable to configure incoming Mali video connection");
+ logg->logError("Unable to configure incoming Mali video connection");
handleException();
}
} else if (fd == mMaliStartupUds.getFd()) {
@@ -164,13 +176,19 @@ void ExternalSource::run() {
// Don't read from this connection, establish a new connection to Mali Graphics
close(client);
if (!connectMali()) {
- logg->logError(__FILE__, __LINE__, "Unable to configure incoming Mali graphics connection");
+ logg->logError("Unable to configure incoming Mali graphics connection");
handleException();
}
} else if (fd == mAnnotate.getFd()) {
int client = mAnnotate.acceptConnection();
if (!setNonblock(client) || !mMonitor.add(client)) {
- logg->logError(__FILE__, __LINE__, "Unable to set socket options on incoming annotation connection");
+ logg->logError("Unable to set socket options on incoming annotation connection");
+ handleException();
+ }
+ } else if (fd == mAnnotateUds.getFd()) {
+ int client = mAnnotateUds.acceptConnection();
+ if (!setNonblock(client) || !mMonitor.add(client)) {
+ logg->logError("Unable to set socket options on incoming annotation connection");
handleException();
}
} else if (fd == pipefd[0]) {
@@ -190,28 +208,29 @@ void ExternalSource::run() {
if (bytes < 0) {
if (errno == EAGAIN) {
// Nothing left to read
- mBuffer.commit(currTime);
+ mBuffer.commit(currTime, true);
break;
}
// Something else failed, close the socket
- mBuffer.commit(currTime);
+ mBuffer.commit(currTime, true);
mBuffer.packInt(-1);
mBuffer.packInt(fd);
- mBuffer.commit(currTime);
+ // Here and other commits, always force-flush the buffer as this frame don't work like others
+ mBuffer.commit(currTime, true);
close(fd);
break;
} else if (bytes == 0) {
// The other side is closed
- mBuffer.commit(currTime);
+ mBuffer.commit(currTime, true);
mBuffer.packInt(-1);
mBuffer.packInt(fd);
- mBuffer.commit(currTime);
+ mBuffer.commit(currTime, true);
close(fd);
break;
}
mBuffer.advanceWrite(bytes);
- mBuffer.commit(currTime);
+ mBuffer.commit(currTime, true);
// Short reads also mean nothing is left to read
if (bytes < contiguous) {
@@ -238,7 +257,7 @@ void ExternalSource::interrupt() {
int8_t c = 0;
// Write to the pipe to wake the monitor which will cause mSessionIsActive to be reread
if (::write(mInterruptFd, &c, sizeof(c)) != sizeof(c)) {
- logg->logError(__FILE__, __LINE__, "write failed");
+ logg->logError("write failed");
handleException();
}
}
diff --git a/daemon/ExternalSource.h b/daemon/ExternalSource.h
index 919e75e..25ae7cd 100644
--- a/daemon/ExternalSource.h
+++ b/daemon/ExternalSource.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -41,6 +41,7 @@ private:
OlyServerSocket mMveStartupUds;
OlyServerSocket mMaliStartupUds;
OlyServerSocket mAnnotate;
+ OlyServerSocket mAnnotateUds;
int mInterruptFd;
int mMaliUds;
int mMveUds;
diff --git a/daemon/FSDriver.cpp b/daemon/FSDriver.cpp
index dd8eb80..afac9df 100644
--- a/daemon/FSDriver.cpp
+++ b/daemon/FSDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -42,7 +42,7 @@ FSCounter::FSCounter(DriverCounter *next, char *name, char *path, const char *re
if (result != 0) {
char buf[128];
regerror(result, &mReg, buf, sizeof(buf));
- logg->logError(__FILE__, __LINE__, "Invalid regex '%s': %s", regex, buf);
+ logg->logError("Invalid regex '%s': %s", regex, buf);
handleException();
}
}
@@ -79,21 +79,19 @@ int64_t FSCounter::read() {
regmatch_t match[2];
int result = regexec(&mReg, buf, 2, match, 0);
if (result != 0) {
- regerror(result, &mReg, buf, sizeof(buf));
- logg->logError(__FILE__, __LINE__, "Parsing %s failed: %s", mPath, buf);
- handleException();
+ // No match
+ return 0;
}
if (match[1].rm_so < 0) {
- logg->logError(__FILE__, __LINE__, "Parsing %s failed", mPath);
- handleException();
- }
-
- errno = 0;
- value = strtoll(buf + match[1].rm_so, NULL, 0);
- if (errno != 0) {
- logg->logError(__FILE__, __LINE__, "Parsing %s failed: %s", mPath, strerror(errno));
- handleException();
+ value = 1;
+ } else {
+ errno = 0;
+ value = strtoll(buf + match[1].rm_so, NULL, 0);
+ if (errno != 0) {
+ logg->logError("Parsing %s failed: %s", mPath, strerror(errno));
+ handleException();
+ }
}
} else {
if (DriverSource::readInt64Driver(mPath, &value) != 0) {
@@ -103,7 +101,7 @@ int64_t FSCounter::read() {
return value;
fail:
- logg->logError(__FILE__, __LINE__, "Unable to read %s", mPath);
+ logg->logError("Unable to read %s", mPath);
handleException();
}
@@ -126,7 +124,7 @@ void FSDriver::readEvents(mxml_node_t *const xml) {
}
if (counter[0] == '/') {
- logg->logError(__FILE__, __LINE__, "Old style filesystem counter (%s) detected, please create a new unique counter value and move the filename into the path attribute, see events-Filesystem.xml for examples", counter);
+ logg->logError("Old style filesystem counter (%s) detected, please create a new unique counter value and move the filename into the path attribute, see events-Filesystem.xml for examples", counter);
handleException();
}
@@ -136,7 +134,7 @@ void FSDriver::readEvents(mxml_node_t *const xml) {
const char *path = mxmlElementGetAttr(node, "path");
if (path == NULL) {
- logg->logError(__FILE__, __LINE__, "The filesystem counter %s is missing the required path attribute", counter);
+ logg->logError("The filesystem counter %s is missing the required path attribute", counter);
handleException();
}
const char *regex = mxmlElementGetAttr(node, "regex");
diff --git a/daemon/FSDriver.h b/daemon/FSDriver.h
index a7dc8b4..63a4e90 100644
--- a/daemon/FSDriver.h
+++ b/daemon/FSDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Fifo.cpp b/daemon/Fifo.cpp
index 41275fd..8d3b9ff 100644
--- a/daemon/Fifo.cpp
+++ b/daemon/Fifo.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -24,12 +24,12 @@ Fifo::Fifo(int singleBufferSize, int bufferSize, sem_t* readerSem) {
mEnd = false;
if (mBuffer == NULL) {
- logg->logError(__FILE__, __LINE__, "failed to allocate %d bytes", bufferSize + singleBufferSize);
+ logg->logError("failed to allocate %d bytes", bufferSize + singleBufferSize);
handleException();
}
if (sem_init(&mWaitForSpaceSem, 0, 0)) {
- logg->logError(__FILE__, __LINE__, "sem_init() failed");
+ logg->logError("sem_init() failed");
handleException();
}
}
diff --git a/daemon/Fifo.h b/daemon/Fifo.h
index 21c8d85..01fa11b 100644
--- a/daemon/Fifo.h
+++ b/daemon/Fifo.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/FtraceDriver.cpp b/daemon/FtraceDriver.cpp
index b156f1c..98bd0a5 100644
--- a/daemon/FtraceDriver.cpp
+++ b/daemon/FtraceDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -9,56 +9,80 @@
#include "FtraceDriver.h"
#include <regex.h>
+#include <unistd.h>
+#include "DriverSource.h"
#include "Logging.h"
+#include "Setup.h"
class FtraceCounter : public DriverCounter {
public:
- FtraceCounter(DriverCounter *next, char *name, const char *regex);
+ FtraceCounter(DriverCounter *next, char *name, const char *regex, const char *enable);
~FtraceCounter();
+ void prepare();
int read(const char *const line, int64_t *values);
+ void stop();
private:
- regex_t reg;
+ regex_t mReg;
+ char *const mEnable;
+ int mWasEnabled;
// Intentionally unimplemented
FtraceCounter(const FtraceCounter &);
FtraceCounter &operator=(const FtraceCounter &);
};
-FtraceCounter::FtraceCounter(DriverCounter *next, char *name, const char *regex) : DriverCounter(next, name) {
- int result = regcomp(&reg, regex, REG_EXTENDED);
+FtraceCounter::FtraceCounter(DriverCounter *next, char *name, const char *regex, const char *enable) : DriverCounter(next, name), mEnable(enable == NULL ? NULL : strdup(enable)) {
+ int result = regcomp(&mReg, regex, REG_EXTENDED);
if (result != 0) {
char buf[128];
- regerror(result, &reg, buf, sizeof(buf));
- logg->logError(__FILE__, __LINE__, "Invalid regex '%s': %s", regex, buf);
+ regerror(result, &mReg, buf, sizeof(buf));
+ logg->logError("Invalid regex '%s': %s", regex, buf);
handleException();
}
}
FtraceCounter::~FtraceCounter() {
- regfree(&reg);
+ regfree(&mReg);
+ if (mEnable != NULL) {
+ free(mEnable);
+ }
+}
+
+void FtraceCounter::prepare() {
+ if (mEnable == NULL) {
+ return;
+ }
+
+ char buf[1<<10];
+ snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/events/%s/enable", mEnable);
+ if ((DriverSource::readIntDriver(buf, &mWasEnabled) != 0) ||
+ (DriverSource::writeDriver(buf, 1) != 0)) {
+ logg->logError("Unable to read or write to %s", buf);
+ handleException();
+ }
}
int FtraceCounter::read(const char *const line, int64_t *values) {
regmatch_t match[2];
- int result = regexec(&reg, line, 2, match, 0);
+ int result = regexec(&mReg, line, 2, match, 0);
if (result != 0) {
// No match
return 0;
}
+ int64_t value;
if (match[1].rm_so < 0) {
- logg->logError(__FILE__, __LINE__, "Parsing %s failed", getName());
- handleException();
- }
-
- errno = 0;
- int64_t value = strtoll(line + match[1].rm_so, NULL, 0);
- if (errno != 0) {
- logg->logError(__FILE__, __LINE__, "Parsing %s failed: %s", getName(), strerror(errno));
- handleException();
+ value = 1;
+ } else {
+ errno = 0;
+ value = strtoll(line + match[1].rm_so, NULL, 0);
+ if (errno != 0) {
+ logg->logError("Parsing %s failed: %s", getName(), strerror(errno));
+ handleException();
+ }
}
values[0] = getKey();
@@ -67,6 +91,16 @@ int FtraceCounter::read(const char *const line, int64_t *values) {
return 1;
}
+void FtraceCounter::stop() {
+ if (mEnable == NULL) {
+ return;
+ }
+
+ char buf[1<<10];
+ snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/events/%s/enable", mEnable);
+ DriverSource::writeDriver(buf, mWasEnabled);
+}
+
FtraceDriver::FtraceDriver() : mValues(NULL) {
}
@@ -75,6 +109,19 @@ FtraceDriver::~FtraceDriver() {
}
void FtraceDriver::readEvents(mxml_node_t *const xml) {
+ // Check the kernel version
+ int release[3];
+ if (!getLinuxVersion(release)) {
+ logg->logError("getLinuxVersion failed");
+ handleException();
+ }
+
+ // The perf clock was added in 3.10
+ if (KERNEL_VERSION(release[0], release[1], release[2]) < KERNEL_VERSION(3, 10, 0)) {
+ logg->logMessage("Unsupported kernel version, to use ftrace please upgrade to Linux 3.10 or later");
+ return;
+ }
+
mxml_node_t *node = xml;
int count = 0;
while (true) {
@@ -93,16 +140,37 @@ void FtraceDriver::readEvents(mxml_node_t *const xml) {
const char *regex = mxmlElementGetAttr(node, "regex");
if (regex == NULL) {
- logg->logError(__FILE__, __LINE__, "The regex counter %s is missing the required regex attribute", counter);
+ logg->logError("The regex counter %s is missing the required regex attribute", counter);
handleException();
}
- setCounters(new FtraceCounter(getCounters(), strdup(counter), regex));
- ++count;
+ bool addCounter = true;
+ const char *enable = mxmlElementGetAttr(node, "enable");
+ if (enable != NULL) {
+ char buf[1<<10];
+ snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/events/%s/enable", enable);
+ if (access(buf, W_OK) != 0) {
+ logg->logMessage("Disabling counter %s, %s not found", counter, buf);
+ addCounter = false;
+ }
+ }
+ if (addCounter) {
+ setCounters(new FtraceCounter(getCounters(), strdup(counter), regex, enable));
+ ++count;
+ }
}
mValues = new int64_t[2*count];
}
+void FtraceDriver::prepare() {
+ for (FtraceCounter *counter = static_cast<FtraceCounter *>(getCounters()); counter != NULL; counter = static_cast<FtraceCounter *>(counter->getNext())) {
+ if (!counter->isEnabled()) {
+ continue;
+ }
+ counter->prepare();
+ }
+}
+
int FtraceDriver::read(const char *line, int64_t **buf) {
int count = 0;
@@ -116,3 +184,12 @@ int FtraceDriver::read(const char *line, int64_t **buf) {
*buf = mValues;
return count;
}
+
+void FtraceDriver::stop() {
+ for (FtraceCounter *counter = static_cast<FtraceCounter *>(getCounters()); counter != NULL; counter = static_cast<FtraceCounter *>(counter->getNext())) {
+ if (!counter->isEnabled()) {
+ continue;
+ }
+ counter->stop();
+ }
+}
diff --git a/daemon/FtraceDriver.h b/daemon/FtraceDriver.h
index 5f958be..b79dc91 100644
--- a/daemon/FtraceDriver.h
+++ b/daemon/FtraceDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -18,7 +18,9 @@ public:
void readEvents(mxml_node_t *const xml);
+ void prepare();
int read(const char *line, int64_t **buf);
+ void stop();
private:
int64_t *mValues;
diff --git a/daemon/FtraceSource.cpp b/daemon/FtraceSource.cpp
index 5216333..14a48b3 100644
--- a/daemon/FtraceSource.cpp
+++ b/daemon/FtraceSource.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -14,10 +14,13 @@
#include <sys/syscall.h>
#include <unistd.h>
+#include "Child.h"
#include "DriverSource.h"
#include "Logging.h"
#include "SessionData.h"
+extern Child *child;
+
static void handler(int signum)
{
(void)signum;
@@ -35,18 +38,20 @@ bool FtraceSource::prepare() {
act.sa_handler = handler;
act.sa_flags = (int)SA_RESETHAND;
if (sigaction(SIGUSR1, &act, NULL) != 0) {
- logg->logError(__FILE__, __LINE__, "sigaction failed: %s\n", strerror(errno));
+ logg->logError("sigaction failed: %s\n", strerror(errno));
handleException();
}
}
+ gSessionData->ftraceDriver.prepare();
+
if (DriverSource::readIntDriver("/sys/kernel/debug/tracing/tracing_on", &mTracingOn)) {
- logg->logError(__FILE__, __LINE__, "Unable to read if ftrace is enabled");
+ logg->logError("Unable to read if ftrace is enabled");
handleException();
}
if (DriverSource::writeDriver("/sys/kernel/debug/tracing/tracing_on", "0") != 0) {
- logg->logError(__FILE__, __LINE__, "Unable to turn ftrace off before truncating the buffer");
+ logg->logError("Unable to turn ftrace off before truncating the buffer");
handleException();
}
@@ -54,20 +59,20 @@ bool FtraceSource::prepare() {
int fd;
fd = open("/sys/kernel/debug/tracing/trace", O_WRONLY | O_TRUNC | O_CLOEXEC, 0666);
if (fd < 0) {
- logg->logError(__FILE__, __LINE__, "Unable truncate ftrace buffer: %s", strerror(errno));
+ logg->logError("Unable truncate ftrace buffer: %s", strerror(errno));
handleException();
}
close(fd);
}
if (DriverSource::writeDriver("/sys/kernel/debug/tracing/trace_clock", "perf") != 0) {
- logg->logError(__FILE__, __LINE__, "Unable to switch ftrace to the perf clock, please ensure you are running Linux 3.10 or later");
+ logg->logError("Unable to switch ftrace to the perf clock, please ensure you are running Linux 3.10 or later");
handleException();
}
mFtraceFh = fopen_cloexec("/sys/kernel/debug/tracing/trace_pipe", "rb");
if (mFtraceFh == NULL) {
- logg->logError(__FILE__, __LINE__, "Unable to open trace_pipe");
+ logg->logError("Unable to open trace_pipe");
handleException();
}
@@ -79,10 +84,25 @@ void FtraceSource::run() {
mTid = syscall(__NR_gettid);
if (DriverSource::writeDriver("/sys/kernel/debug/tracing/tracing_on", "1") != 0) {
- logg->logError(__FILE__, __LINE__, "Unable to turn ftrace on");
+ logg->logError("Unable to turn ftrace on");
handleException();
}
+ // Wait until monotonicStarted is set before sending data
+ int64_t monotonicStarted = 0;
+ while (monotonicStarted <= 0 && gSessionData->mSessionIsActive) {
+ usleep(10);
+
+ if (gSessionData->perf.isSetup()) {
+ monotonicStarted = gSessionData->mMonotonicStarted;
+ } else {
+ if (DriverSource::readInt64Driver("/dev/gator/started", &monotonicStarted) == -1) {
+ logg->logError("Error reading gator driver start time");
+ handleException();
+ }
+ }
+ }
+
while (gSessionData->mSessionIsActive) {
char buf[1<<12];
@@ -91,22 +111,26 @@ void FtraceSource::run() {
// Interrupted by interrupt - likely user request to terminate
break;
}
- logg->logError(__FILE__, __LINE__, "Unable read trace data: %s", strerror(errno));
+ logg->logError("Unable read trace data: %s", strerror(errno));
handleException();
}
- const uint64_t currTime = getTime();
+ const uint64_t currTime = getTime() - gSessionData->mMonotonicStarted;
char *const colon = strstr(buf, ": ");
if (colon == NULL) {
- logg->logError(__FILE__, __LINE__, "Unable find colon: %s", buf);
+ if (strstr(buf, " [LOST ") != NULL) {
+ logg->logError("Ftrace events lost, aborting the capture. It is recommended to discard this report and collect a new capture. If this error occurs often, please reduce the number of ftrace counters selected or the amount of ftrace events generated.");
+ } else {
+ logg->logError("Unable to find colon: %s", buf);
+ }
handleException();
}
*colon = '\0';
char *const space = strrchr(buf, ' ');
if (space == NULL) {
- logg->logError(__FILE__, __LINE__, "Unable find space: %s", buf);
+ logg->logError("Unable to find space: %s", buf);
handleException();
}
*colon = ':';
@@ -117,7 +141,7 @@ void FtraceSource::run() {
errno = 0;
const long long time = strtod(space, NULL) * 1000000000;
if (errno != 0) {
- logg->logError(__FILE__, __LINE__, "Unable to parse time: %s", strerror(errno));
+ logg->logError("Unable to parse time: %s", strerror(errno));
handleException();
}
mBuffer.event64(-1, time);
@@ -127,6 +151,11 @@ void FtraceSource::run() {
}
mBuffer.check(currTime);
+
+ if (gSessionData->mOneShot && gSessionData->mSessionIsActive && (mBuffer.bytesAvailable() <= 0)) {
+ logg->logMessage("One shot (ftrace)");
+ child->endSession();
+ }
}
}
@@ -136,6 +165,7 @@ void FtraceSource::run() {
DriverSource::writeDriver("/sys/kernel/debug/tracing/tracing_on", mTracingOn);
fclose(mFtraceFh);
DriverSource::writeDriver("/sys/kernel/debug/tracing/trace_clock", "local");
+ gSessionData->ftraceDriver.stop();
}
void FtraceSource::interrupt() {
diff --git a/daemon/FtraceSource.h b/daemon/FtraceSource.h
index 2391b88..bc068d2 100644
--- a/daemon/FtraceSource.h
+++ b/daemon/FtraceSource.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/HwmonDriver.cpp b/daemon/HwmonDriver.cpp
index 9d161ae..d8353b0 100644
--- a/daemon/HwmonDriver.cpp
+++ b/daemon/HwmonDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -23,7 +23,7 @@ static sensors_subfeature_type getInput(const sensors_feature_type type) {
case SENSORS_FEATURE_CURR: return SENSORS_SUBFEATURE_CURR_INPUT;
case SENSORS_FEATURE_HUMIDITY: return SENSORS_SUBFEATURE_HUMIDITY_INPUT;
default:
- logg->logError(__FILE__, __LINE__, "Unsupported hwmon feature %i", type);
+ logg->logError("Unsupported hwmon feature %i", type);
handleException();
}
};
@@ -33,112 +33,112 @@ public:
HwmonCounter(DriverCounter *next, char *const name, const sensors_chip_name *chip, const sensors_feature *feature);
~HwmonCounter();
- const char *getLabel() const { return label; }
- const char *getTitle() const { return title; }
- bool isDuplicate() const { return duplicate; }
- const char *getDisplay() const { return display; }
- const char *getCounterClass() const { return counter_class; }
- const char *getUnit() const { return unit; }
- int getModifier() const { return modifier; }
+ const char *getLabel() const { return mLabel; }
+ const char *getTitle() const { return mTitle; }
+ bool isDuplicate() const { return mDuplicate; }
+ const char *getDisplay() const { return mDisplay; }
+ const char *getCounterClass() const { return mCounterClass; }
+ const char *getUnit() const { return mUnit; }
+ double getMultiplier() const { return mMultiplier; }
int64_t read();
private:
void init(const sensors_chip_name *chip, const sensors_feature *feature);
- const sensors_chip_name *chip;
- const sensors_feature *feature;
- char *label;
- const char *title;
- const char *display;
- const char *counter_class;
- const char *unit;
- double previous_value;
- int modifier;
- int monotonic: 1,
- duplicate : 1;
+ const sensors_chip_name *mChip;
+ const sensors_feature *mFeature;
+ char *mLabel;
+ const char *mTitle;
+ const char *mDisplay;
+ const char *mCounterClass;
+ const char *mUnit;
+ double mPreviousValue;
+ double mMultiplier;
+ int mMonotonic: 1,
+ mDuplicate : 1;
// Intentionally unimplemented
HwmonCounter(const HwmonCounter &);
HwmonCounter &operator=(const HwmonCounter &);
};
-HwmonCounter::HwmonCounter(DriverCounter *next, char *const name, const sensors_chip_name *chip, const sensors_feature *feature) : DriverCounter(next, name), chip(chip), feature(feature), duplicate(false) {
- label = sensors_get_label(chip, feature);
+HwmonCounter::HwmonCounter(DriverCounter *next, char *const name, const sensors_chip_name *const chip, const sensors_feature *feature) : DriverCounter(next, name), mChip(chip), mFeature(feature), mDuplicate(false) {
+ mLabel = sensors_get_label(mChip, mFeature);
- switch (feature->type) {
+ switch (mFeature->type) {
case SENSORS_FEATURE_IN:
- title = "Voltage";
- display = "maximum";
- counter_class = "absolute";
- unit = "V";
- modifier = 1000;
- monotonic = false;
+ mTitle = "Voltage";
+ mDisplay = "maximum";
+ mCounterClass = "absolute";
+ mUnit = "V";
+ mMultiplier = 0.001;
+ mMonotonic = false;
break;
case SENSORS_FEATURE_FAN:
- title = "Fan";
- display = "average";
- counter_class = "absolute";
- unit = "RPM";
- modifier = 1;
- monotonic = false;
+ mTitle = "Fan";
+ mDisplay = "average";
+ mCounterClass = "absolute";
+ mUnit = "RPM";
+ mMultiplier = 1.0;
+ mMonotonic = false;
break;
case SENSORS_FEATURE_TEMP:
- title = "Temperature";
- display = "maximum";
- counter_class = "absolute";
- unit = "°C";
- modifier = 1000;
- monotonic = false;
+ mTitle = "Temperature";
+ mDisplay = "maximum";
+ mCounterClass = "absolute";
+ mUnit = "°C";
+ mMultiplier = 0.001;
+ mMonotonic = false;
break;
case SENSORS_FEATURE_POWER:
- title = "Power";
- display = "maximum";
- counter_class = "absolute";
- unit = "W";
- modifier = 1000000;
- monotonic = false;
+ mTitle = "Power";
+ mDisplay = "maximum";
+ mCounterClass = "absolute";
+ mUnit = "W";
+ mMultiplier = 0.000001;
+ mMonotonic = false;
break;
case SENSORS_FEATURE_ENERGY:
- title = "Energy";
- display = "accumulate";
- counter_class = "delta";
- unit = "J";
- modifier = 1000000;
- monotonic = true;
+ mTitle = "Energy";
+ mDisplay = "accumulate";
+ mCounterClass = "delta";
+ mUnit = "J";
+ mMultiplier = 0.000001;
+ mMonotonic = true;
break;
case SENSORS_FEATURE_CURR:
- title = "Current";
- display = "maximum";
- counter_class = "absolute";
- unit = "A";
- modifier = 1000;
- monotonic = false;
+ mTitle = "Current";
+ mDisplay = "maximum";
+ mCounterClass = "absolute";
+ mUnit = "A";
+ mMultiplier = 0.001;
+ mMonotonic = false;
break;
case SENSORS_FEATURE_HUMIDITY:
- title = "Humidity";
- display = "average";
- counter_class = "absolute";
- unit = "%";
- modifier = 1000;
- monotonic = false;
+ mTitle = "Humidity";
+ mDisplay = "average";
+ mCounterClass = "absolute";
+ mUnit = "%";
+ mMultiplier = 0.001;
+ mMonotonic = false;
break;
default:
- logg->logError(__FILE__, __LINE__, "Unsupported hwmon feature %i", feature->type);
+ logg->logError("Unsupported hwmon feature %i", mFeature->type);
handleException();
}
for (HwmonCounter * counter = static_cast<HwmonCounter *>(next); counter != NULL; counter = static_cast<HwmonCounter *>(counter->getNext())) {
- if (strcmp(label, counter->getLabel()) == 0 && strcmp(title, counter->getTitle()) == 0) {
- duplicate = true;
- counter->duplicate = true;
+ if (strcmp(mLabel, counter->getLabel()) == 0 && strcmp(mTitle, counter->getTitle()) == 0) {
+ mDuplicate = true;
+ counter->mDuplicate = true;
break;
}
}
}
HwmonCounter::~HwmonCounter() {
- free((void *)label);
+ free((void *)mLabel);
}
int64_t HwmonCounter::read() {
@@ -147,19 +147,19 @@ int64_t HwmonCounter::read() {
const sensors_subfeature *subfeature;
// Keep in sync with the read check in HwmonDriver::readEvents
- subfeature = sensors_get_subfeature(chip, feature, getInput(feature->type));
+ subfeature = sensors_get_subfeature(mChip, mFeature, getInput(mFeature->type));
if (!subfeature) {
- logg->logError(__FILE__, __LINE__, "No input value for hwmon sensor %s", label);
+ logg->logError("No input value for hwmon sensor %s", mLabel);
handleException();
}
- if (sensors_get_value(chip, subfeature->number, &value) != 0) {
- logg->logError(__FILE__, __LINE__, "Can't get input value for hwmon sensor %s", label);
+ if (sensors_get_value(mChip, subfeature->number, &value) != 0) {
+ logg->logError("Can't get input value for hwmon sensor %s", mLabel);
handleException();
}
- result = (monotonic ? value - previous_value : value);
- previous_value = value;
+ result = (mMonotonic ? value - mPreviousValue : value);
+ mPreviousValue = value;
return result;
}
@@ -209,7 +209,7 @@ void HwmonDriver::readEvents(mxml_node_t *const) {
void HwmonDriver::writeEvents(mxml_node_t *root) const {
root = mxmlNewElement(root, "category");
- mxmlElementSetAttr(root, "name", "hwmon");
+ mxmlElementSetAttr(root, "name", "Hardware Monitor");
char buf[1024];
for (HwmonCounter *counter = static_cast<HwmonCounter *>(getCounters()); counter != NULL; counter = static_cast<HwmonCounter *>(counter->getNext())) {
@@ -224,8 +224,8 @@ void HwmonDriver::writeEvents(mxml_node_t *root) const {
mxmlElementSetAttr(node, "display", counter->getDisplay());
mxmlElementSetAttr(node, "class", counter->getCounterClass());
mxmlElementSetAttr(node, "units", counter->getUnit());
- if (counter->getModifier() != 1) {
- mxmlElementSetAttrf(node, "modifier", "%d", counter->getModifier());
+ if (counter->getMultiplier() != 1.0) {
+ mxmlElementSetAttrf(node, "multiplier", "%lf", counter->getMultiplier());
}
if (strcmp(counter->getDisplay(), "average") == 0 || strcmp(counter->getDisplay(), "maximum") == 0) {
mxmlElementSetAttr(node, "average_selection", "yes");
diff --git a/daemon/HwmonDriver.h b/daemon/HwmonDriver.h
index f28d825..f15d557 100644
--- a/daemon/HwmonDriver.h
+++ b/daemon/HwmonDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/KMod.cpp b/daemon/KMod.cpp
index fe9dc6a..e33b499 100644
--- a/daemon/KMod.cpp
+++ b/daemon/KMod.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -83,13 +83,13 @@ void KMod::setupCounter(Counter &counter) {
if (access(text, F_OK) == 0) {
int count = counter.getCount();
if (DriverSource::writeReadDriver(text, &count) && counter.getCount() > 0) {
- logg->logError(__FILE__, __LINE__, "Cannot enable EBS for %s:%i with a count of %d\n", counter.getType(), counter.getEvent(), counter.getCount());
+ logg->logError("Cannot enable EBS for %s:%i with a count of %d\n", counter.getType(), counter.getEvent(), counter.getCount());
handleException();
}
counter.setCount(count);
} else if (counter.getCount() > 0) {
ConfigurationXML::remove();
- logg->logError(__FILE__, __LINE__, "Event Based Sampling is only supported with kernel versions 3.0.0 and higher with CONFIG_PERF_EVENTS=y, and CONFIG_HW_PERF_EVENTS=y. The invalid configuration.xml has been removed.\n");
+ logg->logError("Event Based Sampling is only supported with kernel versions 3.0.0 and higher with CONFIG_PERF_EVENTS=y, and CONFIG_HW_PERF_EVENTS=y. The invalid configuration.xml has been removed.\n");
handleException();
}
}
diff --git a/daemon/KMod.h b/daemon/KMod.h
index 900a60e..7f06b4b 100644
--- a/daemon/KMod.h
+++ b/daemon/KMod.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/LICENSE b/daemon/LICENSE
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/daemon/LICENSE
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/daemon/LocalCapture.cpp b/daemon/LocalCapture.cpp
index d2a4b79..5689987 100644
--- a/daemon/LocalCapture.cpp
+++ b/daemon/LocalCapture.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -27,7 +27,7 @@ LocalCapture::~LocalCapture() {}
void LocalCapture::createAPCDirectory(char* target_path) {
gSessionData->mAPCDir = createUniqueDirectory(target_path, ".apc");
if ((removeDirAndAllContents(gSessionData->mAPCDir) != 0 || mkdir(gSessionData->mAPCDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)) {
- logg->logError(__FILE__, __LINE__, "Unable to create directory %s", gSessionData->mAPCDir);
+ logg->logError("Unable to create directory %s", gSessionData->mAPCDir);
handleException();
}
}
@@ -40,7 +40,7 @@ void LocalCapture::write(char* string) {
// Write the file
if (util->writeToDisk(file, string) < 0) {
- logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file);
+ logg->logError("Error writing %s\nPlease verify the path.", file);
handleException();
}
@@ -55,7 +55,7 @@ char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* e
// Ensure the path is an absolute path, i.e. starts with a slash
if (initialPath == 0 || strlen(initialPath) == 0) {
- logg->logError(__FILE__, __LINE__, "Missing -o command line option required for a local capture.");
+ logg->logError("Missing -o command line option required for a local capture.");
handleException();
} else if (initialPath[0] != '/') {
if (getcwd(path, PATH_MAX) == 0) {
diff --git a/daemon/LocalCapture.h b/daemon/LocalCapture.h
index 25d281f..807f49d 100644
--- a/daemon/LocalCapture.h
+++ b/daemon/LocalCapture.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Logging.cpp b/daemon/Logging.cpp
index 41ffa1a..8846622 100644
--- a/daemon/Logging.cpp
+++ b/daemon/Logging.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -39,12 +39,12 @@ Logging::Logging(bool debug) {
Logging::~Logging() {
}
-void Logging::logError(const char* file, int line, const char* fmt, ...) {
+void Logging::_logError(const char *function, const char *file, int line, const char *fmt, ...) {
va_list args;
MUTEX_LOCK();
if (mDebug) {
- snprintf(mErrBuf, sizeof(mErrBuf), "ERROR[%s:%d]: ", file, line);
+ snprintf(mErrBuf, sizeof(mErrBuf), "ERROR: %s(%s:%i): ", function, file, line);
} else {
mErrBuf[0] = 0;
}
@@ -59,12 +59,12 @@ void Logging::logError(const char* file, int line, const char* fmt, ...) {
MUTEX_UNLOCK();
}
-void Logging::logMessage(const char* fmt, ...) {
+void Logging::_logMessage(const char *function, const char *file, int line, const char *fmt, ...) {
if (mDebug) {
va_list args;
MUTEX_LOCK();
- strcpy(mLogBuf, "INFO: ");
+ snprintf(mLogBuf, sizeof(mLogBuf), "INFO: %s(%s:%i): ", function, file, line);
va_start(args, fmt);
vsnprintf(mLogBuf + strlen(mLogBuf), sizeof(mLogBuf) - 2 - strlen(mLogBuf), fmt, args); // subtract 2 for \n and \0
diff --git a/daemon/Logging.h b/daemon/Logging.h
index 09e93ff..a7b4523 100644
--- a/daemon/Logging.h
+++ b/daemon/Logging.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,10 +17,14 @@ class Logging {
public:
Logging(bool debug);
~Logging();
- void logError(const char* file, int line, const char* fmt, ...);
- void logMessage(const char* fmt, ...);
- char* getLastError() {return mErrBuf;}
- char* getLastMessage() {return mLogBuf;}
+#define logError(...) _logError(__func__, __FILE__, __LINE__, __VA_ARGS__)
+ __attribute__ ((format (printf, 5, 6)))
+ void _logError(const char *function, const char *file, int line, const char *fmt, ...);
+#define logMessage(...) _logMessage(__func__, __FILE__, __LINE__, __VA_ARGS__)
+ __attribute__ ((format (printf, 5, 6)))
+ void _logMessage(const char *function, const char *file, int line, const char *fmt, ...);
+ char *getLastError() {return mErrBuf;}
+ char *getLastMessage() {return mLogBuf;}
private:
char mErrBuf[4096]; // Arbitrarily large buffer to hold a string
@@ -29,7 +33,7 @@ private:
pthread_mutex_t mLoggingMutex;
};
-extern Logging* logg;
+extern Logging *logg;
extern void handleException() __attribute__ ((noreturn));
diff --git a/daemon/MaliVideoDriver.cpp b/daemon/MaliVideoDriver.cpp
index 5eef264..2db332d 100644
--- a/daemon/MaliVideoDriver.cpp
+++ b/daemon/MaliVideoDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -109,7 +109,7 @@ static bool writeAll(const int mveUds, const char *const buf, const int pos) {
while (written < pos) {
size_t bytes = ::write(mveUds, buf + written, pos - written);
if (bytes <= 0) {
- logg->logMessage("%s(%s:%i): write failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("write failed");
return false;
}
written += bytes;
diff --git a/daemon/MaliVideoDriver.h b/daemon/MaliVideoDriver.h
index 204a57a..35b0558 100644
--- a/daemon/MaliVideoDriver.h
+++ b/daemon/MaliVideoDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/MemInfoDriver.cpp b/daemon/MemInfoDriver.cpp
index cce15c1..6818b97 100644
--- a/daemon/MemInfoDriver.cpp
+++ b/daemon/MemInfoDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -59,7 +59,7 @@ void MemInfoDriver::read(Buffer *const buffer) {
}
if (!mBuf.read("/proc/meminfo")) {
- logg->logError(__FILE__, __LINE__, "Failed to read /proc/meminfo");
+ logg->logError("Failed to read /proc/meminfo");
handleException();
}
diff --git a/daemon/MemInfoDriver.h b/daemon/MemInfoDriver.h
index eb1b041..ffeaf30 100644
--- a/daemon/MemInfoDriver.h
+++ b/daemon/MemInfoDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Monitor.cpp b/daemon/Monitor.cpp
index 74f22ee..0428887 100644
--- a/daemon/Monitor.cpp
+++ b/daemon/Monitor.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -38,17 +38,17 @@ bool Monitor::init() {
mFd = epoll_create(16);
#endif
if (mFd < 0) {
- logg->logMessage("%s(%s:%i): epoll_create1 failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("epoll_create1 failed");
return false;
}
#ifndef EPOLL_CLOEXEC
- int fdf = fcntl(mFd, F_GETFD);
- if ((fdf == -1) || (fcntl(mFd, F_SETFD, fdf | FD_CLOEXEC) != 0)) {
- logg->logMessage("%s(%s:%i): fcntl failed", __FUNCTION__, __FILE__, __LINE__);
- ::close(mFd);
- return -1;
- }
+ int fdf = fcntl(mFd, F_GETFD);
+ if ((fdf == -1) || (fcntl(mFd, F_SETFD, fdf | FD_CLOEXEC) != 0)) {
+ logg->logMessage("fcntl failed");
+ ::close(mFd);
+ return -1;
+ }
#endif
return true;
@@ -60,7 +60,7 @@ bool Monitor::add(const int fd) {
event.data.fd = fd;
event.events = EPOLLIN;
if (epoll_ctl(mFd, EPOLL_CTL_ADD, fd, &event) != 0) {
- logg->logMessage("%s(%s:%i): epoll_ctl failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("epoll_ctl failed");
return false;
}
@@ -74,7 +74,7 @@ int Monitor::wait(struct epoll_event *const events, int maxevents, int timeout)
if (errno == EINTR) {
result = 0;
} else {
- logg->logMessage("%s(%s:%i): epoll_wait failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("epoll_wait failed");
}
}
diff --git a/daemon/Monitor.h b/daemon/Monitor.h
index 7194e0e..55368fc 100644
--- a/daemon/Monitor.h
+++ b/daemon/Monitor.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/NetDriver.cpp b/daemon/NetDriver.cpp
index e75c069..56b25e0 100644
--- a/daemon/NetDriver.cpp
+++ b/daemon/NetDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -108,7 +108,7 @@ bool NetDriver::doRead() {
void NetDriver::start() {
if (!doRead()) {
- logg->logError(__FILE__, __LINE__, "Unable to read network stats");
+ logg->logError("Unable to read network stats");
handleException();
}
// Initialize previous values
@@ -122,7 +122,7 @@ void NetDriver::start() {
void NetDriver::read(Buffer *const buffer) {
if (!doRead()) {
- logg->logError(__FILE__, __LINE__, "Unable to read network stats");
+ logg->logError("Unable to read network stats");
handleException();
}
super::read(buffer);
diff --git a/daemon/NetDriver.h b/daemon/NetDriver.h
index 50ff850..5f72280 100644
--- a/daemon/NetDriver.h
+++ b/daemon/NetDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/OlySocket.cpp b/daemon/OlySocket.cpp
index aa0ce49..078d202 100644
--- a/daemon/OlySocket.cpp
+++ b/daemon/OlySocket.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
+#include <stddef.h>
#endif
#include "Logging.h"
@@ -78,7 +79,7 @@ OlyServerSocket::OlyServerSocket(int port) {
#ifdef WIN32
WSADATA wsaData;
if (WSAStartup(0x0202, &wsaData) != 0) {
- logg->logError(__FILE__, __LINE__, "Windows socket initialization failed");
+ logg->logError("Windows socket initialization failed");
handleException();
}
#endif
@@ -97,11 +98,11 @@ OlySocket::OlySocket(int socketID) : mSocketID(socketID) {
__a > __b ? __b : __a; \
})
-OlyServerSocket::OlyServerSocket(const char* path, const size_t pathSize) {
+OlyServerSocket::OlyServerSocket(const char* path, const size_t pathSize, const bool calculateAddrlen) {
// Create socket
mFDServer = socket_cloexec(PF_UNIX, SOCK_STREAM, 0);
if (mFDServer < 0) {
- logg->logError(__FILE__, __LINE__, "Error creating server socket");
+ logg->logError("Error creating server socket");
handleException();
}
@@ -113,19 +114,19 @@ OlyServerSocket::OlyServerSocket(const char* path, const size_t pathSize) {
sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0';
// Bind the socket to an address
- if (bind(mFDServer, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
- logg->logError(__FILE__, __LINE__, "Binding of server socket failed.");
+ if (bind(mFDServer, (const struct sockaddr*)&sockaddr, calculateAddrlen ? offsetof(struct sockaddr_un, sun_path) + pathSize - 1 : sizeof(sockaddr)) < 0) {
+ logg->logError("Binding of server socket failed.");
handleException();
}
// Listen for connections on this socket
if (listen(mFDServer, 1) < 0) {
- logg->logError(__FILE__, __LINE__, "Listening of server socket failed");
+ logg->logError("Listening of server socket failed");
handleException();
}
}
-int OlySocket::connect(const char* path, const size_t pathSize) {
+int OlySocket::connect(const char* path, const size_t pathSize, const bool calculateAddrlen) {
int fd = socket_cloexec(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
return -1;
@@ -138,7 +139,7 @@ int OlySocket::connect(const char* path, const size_t pathSize) {
memcpy(sockaddr.sun_path, path, MIN(pathSize, sizeof(sockaddr.sun_path)));
sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0';
- if (::connect(fd, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
+ if (::connect(fd, (const struct sockaddr*)&sockaddr, calculateAddrlen ? offsetof(struct sockaddr_un, sun_path) + pathSize - 1 : sizeof(sockaddr)) < 0) {
close(fd);
return -1;
}
@@ -174,11 +175,11 @@ void OlySocket::closeSocket() {
}
void OlyServerSocket::closeServerSocket() {
- if (CLOSE_SOCKET(mFDServer) != 0) {
- logg->logError(__FILE__, __LINE__, "Failed to close server socket.");
+ if (mFDServer > 0 && CLOSE_SOCKET(mFDServer) != 0) {
+ logg->logError("Failed to close server socket.");
handleException();
}
- mFDServer = 0;
+ mFDServer = -1;
}
void OlyServerSocket::createServerSocket(int port) {
@@ -190,7 +191,7 @@ void OlyServerSocket::createServerSocket(int port) {
family = AF_INET;
mFDServer = socket_cloexec(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (mFDServer < 0) {
- logg->logError(__FILE__, __LINE__, "Error creating server socket");
+ logg->logError("Error creating server socket");
handleException();
}
}
@@ -198,10 +199,16 @@ void OlyServerSocket::createServerSocket(int port) {
// Enable address reuse, another solution would be to create the server socket once and only close it when the object exits
int on = 1;
if (setsockopt(mFDServer, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) {
- logg->logError(__FILE__, __LINE__, "Setting server socket options failed");
+ logg->logError("Setting server socket reuse option failed");
handleException();
}
+ // Listen on both IPv4 and IPv6
+ on = 0;
+ if (setsockopt(mFDServer, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(on)) != 0) {
+ logg->logMessage("setsockopt IPV6_V6ONLY failed");
+ }
+
// Create sockaddr_in structure, ensuring non-populated fields are zero
struct sockaddr_in6 sockaddr;
memset((void*)&sockaddr, 0, sizeof(sockaddr));
@@ -211,13 +218,13 @@ void OlyServerSocket::createServerSocket(int port) {
// Bind the socket to an address
if (bind(mFDServer, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
- logg->logError(__FILE__, __LINE__, "Binding of server socket failed.\nIs an instance already running?");
+ logg->logError("Binding of server socket on port %i failed.\nIs an instance already running or is another application using that port?", port);
handleException();
}
// Listen for connections on this socket
if (listen(mFDServer, 1) < 0) {
- logg->logError(__FILE__, __LINE__, "Listening of server socket failed");
+ logg->logError("Listening of server socket failed");
handleException();
}
}
@@ -227,14 +234,14 @@ void OlyServerSocket::createServerSocket(int port) {
int OlyServerSocket::acceptConnection() {
int socketID;
if (mFDServer <= 0) {
- logg->logError(__FILE__, __LINE__, "Attempting multiple connections on a single connection server socket or attempting to accept on a client socket");
+ logg->logError("Attempting multiple connections on a single connection server socket or attempting to accept on a client socket");
handleException();
}
// Accept a connection, note that this call blocks until a client connects
socketID = accept_cloexec(mFDServer, NULL, NULL);
if (socketID < 0) {
- logg->logError(__FILE__, __LINE__, "Socket acceptance failed");
+ logg->logError("Socket acceptance failed");
handleException();
}
return socketID;
@@ -248,7 +255,7 @@ void OlySocket::send(const char* buffer, int size) {
while (size > 0) {
int n = ::send(mSocketID, buffer, size, 0);
if (n < 0) {
- logg->logError(__FILE__, __LINE__, "Socket send error");
+ logg->logError("Socket send error");
handleException();
}
size -= n;
@@ -264,7 +271,7 @@ int OlySocket::receive(char* buffer, int size) {
int bytes = recv(mSocketID, buffer, size, 0);
if (bytes < 0) {
- logg->logError(__FILE__, __LINE__, "Socket receive error");
+ logg->logError("Socket receive error");
handleException();
} else if (bytes == 0) {
logg->logMessage("Socket disconnected");
@@ -279,7 +286,7 @@ int OlySocket::receiveNBytes(char* buffer, int size) {
while (size > 0 && buffer != NULL) {
bytes = recv(mSocketID, buffer, size, 0);
if (bytes < 0) {
- logg->logError(__FILE__, __LINE__, "Socket receive error");
+ logg->logError("Socket receive error");
handleException();
} else if (bytes == 0) {
logg->logMessage("Socket disconnected");
@@ -304,7 +311,7 @@ int OlySocket::receiveString(char* buffer, int size) {
// Receive a single character
int bytes = recv(mSocketID, &buffer[bytes_received], 1, 0);
if (bytes < 0) {
- logg->logError(__FILE__, __LINE__, "Socket receive error");
+ logg->logError("Socket receive error");
handleException();
} else if (bytes == 0) {
logg->logMessage("Socket disconnected");
diff --git a/daemon/OlySocket.h b/daemon/OlySocket.h
index 6b53b01..757a252 100644
--- a/daemon/OlySocket.h
+++ b/daemon/OlySocket.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -12,7 +12,7 @@
#include <stddef.h>
#ifdef WIN32
-typedef socklen_t int;
+typedef int socklen_t;
#else
#include <sys/socket.h>
#endif
@@ -20,7 +20,7 @@ typedef socklen_t int;
class OlySocket {
public:
#ifndef WIN32
- static int connect(const char* path, const size_t pathSize);
+ static int connect(const char* path, const size_t pathSize, const bool calculateAddrlen = false);
#endif
OlySocket(int socketID);
@@ -43,7 +43,7 @@ class OlyServerSocket {
public:
OlyServerSocket(int port);
#ifndef WIN32
- OlyServerSocket(const char* path, const size_t pathSize);
+ OlyServerSocket(const char* path, const size_t pathSize, const bool calculateAddrlen = false);
#endif
~OlyServerSocket();
diff --git a/daemon/OlyUtility.cpp b/daemon/OlyUtility.cpp
index 45340a2..6f40168 100644
--- a/daemon/OlyUtility.cpp
+++ b/daemon/OlyUtility.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/OlyUtility.h b/daemon/OlyUtility.h
index 1d26beb..1525081 100644
--- a/daemon/OlyUtility.h
+++ b/daemon/OlyUtility.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/PerfBuffer.cpp b/daemon/PerfBuffer.cpp
index f127c99..3b9da1d 100644
--- a/daemon/PerfBuffer.cpp
+++ b/daemon/PerfBuffer.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -35,14 +35,14 @@ PerfBuffer::~PerfBuffer() {
bool PerfBuffer::useFd(const int cpu, const int fd) {
if (mFds[cpu] < 0) {
if (mBuf[cpu] != MAP_FAILED) {
- logg->logMessage("%s(%s:%i): cpu %i already online or not correctly cleaned up", __FUNCTION__, __FILE__, __LINE__, cpu);
+ logg->logMessage("cpu %i already online or not correctly cleaned up", cpu);
return false;
}
// The buffer isn't mapped yet
mBuf[cpu] = mmap(NULL, gSessionData->mPageSize + BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mBuf[cpu] == MAP_FAILED) {
- logg->logMessage("%s(%s:%i): mmap failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("mmap failed");
return false;
}
mFds[cpu] = fd;
@@ -50,17 +50,17 @@ bool PerfBuffer::useFd(const int cpu, const int fd) {
// Check the version
struct perf_event_mmap_page *pemp = static_cast<struct perf_event_mmap_page *>(mBuf[cpu]);
if (pemp->compat_version != 0) {
- logg->logMessage("%s(%s:%i): Incompatible perf_event_mmap_page compat_version", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("Incompatible perf_event_mmap_page compat_version");
return false;
}
} else {
if (mBuf[cpu] == MAP_FAILED) {
- logg->logMessage("%s(%s:%i): cpu already online or not correctly cleaned up", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("cpu already online or not correctly cleaned up");
return false;
}
if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, mFds[cpu]) < 0) {
- logg->logMessage("%s(%s:%i): ioctl failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("ioctl failed");
return false;
}
}
@@ -79,8 +79,8 @@ bool PerfBuffer::isEmpty() {
if (mBuf[cpu] != MAP_FAILED) {
// Take a snapshot of the positions
struct perf_event_mmap_page *pemp = static_cast<struct perf_event_mmap_page *>(mBuf[cpu]);
- const __u64 head = pemp->data_head;
- const __u64 tail = pemp->data_tail;
+ const __u64 head = ACCESS_ONCE(pemp->data_head);
+ const __u64 tail = ACCESS_ONCE(pemp->data_tail);
if (head != tail) {
return false;
@@ -91,42 +91,105 @@ bool PerfBuffer::isEmpty() {
return true;
}
-static void compressAndSend(const int cpu, const __u64 head, __u64 tail, const uint8_t *const b, Sender *const sender) {
- // Pick a big size but something smaller than the chunkSize in Sender::writeData which is 100k
- char buf[1<<16];
- int writePos = 0;
- const int typeLength = gSessionData->mLocalCapture ? 0 : 1;
+bool PerfBuffer::isFull() {
+ for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
+ if (mBuf[cpu] != MAP_FAILED) {
+ // Take a snapshot of the positions
+ struct perf_event_mmap_page *pemp = static_cast<struct perf_event_mmap_page *>(mBuf[cpu]);
+ const __u64 head = ACCESS_ONCE(pemp->data_head);
- while (head > tail) {
- writePos = 0;
- if (!gSessionData->mLocalCapture) {
- buf[writePos++] = RESPONSE_APC_DATA;
+ if (head + 2000 <= (unsigned int)BUF_SIZE) {
+ return true;
+ }
}
- // Reserve space for size
- writePos += sizeof(uint32_t);
- Buffer::packInt(buf, sizeof(buf), writePos, FRAME_PERF);
- Buffer::packInt(buf, sizeof(buf), writePos, cpu);
+ }
+
+ return false;
+}
+
+class PerfFrame {
+public:
+ PerfFrame(Sender *const sender) : mSender(sender), mWritePos(-1), mCpuSizePos(-1) {}
+
+ void add(const int cpu, const __u64 head, __u64 tail, const uint8_t *const b) {
+ cpuHeader(cpu);
while (head > tail) {
const int count = reinterpret_cast<const struct perf_event_header *>(b + (tail & BUF_MASK))->size/sizeof(uint64_t);
// Can this whole message be written as Streamline assumes events are not split between frames
- if (sizeof(buf) <= writePos + count*Buffer::MAXSIZE_PACK64) {
- break;
+ if (sizeof(mBuf) <= mWritePos + count*Buffer::MAXSIZE_PACK64) {
+ send();
+ cpuHeader(cpu);
}
for (int i = 0; i < count; ++i) {
// Must account for message size
- Buffer::packInt64(buf, sizeof(buf), writePos, *reinterpret_cast<const uint64_t *>(b + (tail & BUF_MASK)));
+ Buffer::packInt64(mBuf, sizeof(mBuf), mWritePos, *reinterpret_cast<const uint64_t *>(b + (tail & BUF_MASK)));
tail += sizeof(uint64_t);
}
}
+ }
+
+ void send() {
+ if (mWritePos > 0) {
+ writeFrameSize();
+ mSender->writeData(mBuf, mWritePos, RESPONSE_APC_DATA);
+ mWritePos = -1;
+ mCpuSizePos = -1;
+ }
+ }
- // Write size
- Buffer::writeLEInt(reinterpret_cast<unsigned char *>(buf + typeLength), writePos - typeLength - sizeof(uint32_t));
- sender->writeData(buf, writePos, RESPONSE_APC_DATA);
+private:
+ void writeFrameSize() {
+ writeCpuSize();
+ const int typeLength = gSessionData->mLocalCapture ? 0 : 1;
+ Buffer::writeLEInt(reinterpret_cast<unsigned char *>(mBuf + typeLength), mWritePos - typeLength - sizeof(uint32_t));
}
-}
+
+ void frameHeader() {
+ if (mWritePos < 0) {
+ mWritePos = 0;
+ mCpuSizePos = -1;
+ if (!gSessionData->mLocalCapture) {
+ mBuf[mWritePos++] = RESPONSE_APC_DATA;
+ }
+ // Reserve space for frame size
+ mWritePos += sizeof(uint32_t);
+ Buffer::packInt(mBuf, sizeof(mBuf), mWritePos, FRAME_PERF);
+ }
+ }
+
+ void writeCpuSize() {
+ if (mCpuSizePos >= 0) {
+ Buffer::writeLEInt(reinterpret_cast<unsigned char *>(mBuf + mCpuSizePos), mWritePos - mCpuSizePos - sizeof(uint32_t));
+ }
+ }
+
+ void cpuHeader(const int cpu) {
+ if (sizeof(mBuf) <= mWritePos + Buffer::MAXSIZE_PACK32 + sizeof(uint32_t)) {
+ send();
+ }
+ frameHeader();
+ writeCpuSize();
+ Buffer::packInt(mBuf, sizeof(mBuf), mWritePos, cpu);
+ mCpuSizePos = mWritePos;
+ // Reserve space for cpu size
+ mWritePos += sizeof(uint32_t);
+ }
+
+ // Pick a big size but something smaller than the chunkSize in Sender::writeData which is 100k
+ char mBuf[1<<16];
+ Sender *const mSender;
+ int mWritePos;
+ int mCpuSizePos;
+
+ // Intentionally unimplemented
+ PerfFrame(const PerfFrame &);
+ PerfFrame& operator=(const PerfFrame &);
+};
bool PerfBuffer::send(Sender *const sender) {
+ PerfFrame frame(sender);
+
for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
if (mBuf[cpu] == MAP_FAILED) {
continue;
@@ -134,12 +197,12 @@ bool PerfBuffer::send(Sender *const sender) {
// Take a snapshot of the positions
struct perf_event_mmap_page *pemp = static_cast<struct perf_event_mmap_page *>(mBuf[cpu]);
- const __u64 head = pemp->data_head;
- const __u64 tail = pemp->data_tail;
+ const __u64 head = ACCESS_ONCE(pemp->data_head);
+ const __u64 tail = ACCESS_ONCE(pemp->data_tail);
if (head > tail) {
const uint8_t *const b = static_cast<uint8_t *>(mBuf[cpu]) + gSessionData->mPageSize;
- compressAndSend(cpu, head, tail, b, sender);
+ frame.add(cpu, head, tail, b);
// Update tail with the data read
pemp->data_tail = head;
@@ -150,9 +213,11 @@ bool PerfBuffer::send(Sender *const sender) {
mBuf[cpu] = MAP_FAILED;
mDiscard[cpu] = false;
mFds[cpu] = -1;
- logg->logMessage("%s(%s:%i): Unmaped cpu %i", __FUNCTION__, __FILE__, __LINE__, cpu);
+ logg->logMessage("Unmaped cpu %i", cpu);
}
}
+ frame.send();
+
return true;
}
diff --git a/daemon/PerfBuffer.h b/daemon/PerfBuffer.h
index 25a1062..a2d0e9b 100644
--- a/daemon/PerfBuffer.h
+++ b/daemon/PerfBuffer.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -24,6 +24,7 @@ public:
bool useFd(const int cpu, const int fd);
void discard(const int cpu);
bool isEmpty();
+ bool isFull();
bool send(Sender *const sender);
private:
diff --git a/daemon/PerfDriver.cpp b/daemon/PerfDriver.cpp
index 42cbff6..796ee75 100644
--- a/daemon/PerfDriver.cpp
+++ b/daemon/PerfDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -40,25 +40,25 @@ struct gator_cpu {
// From gator_main.c
static const struct gator_cpu gator_cpus[] = {
- { 0xb36, "ARM1136", "ARM_ARM11", 3 },
- { 0xb56, "ARM1156", "ARM_ARM11", 3 },
- { 0xb76, "ARM1176", "ARM_ARM11", 3 },
- { 0xb02, "ARM11MPCore", "ARM_ARM11MPCore", 3 },
- { 0xc05, "Cortex-A5", "ARMv7_Cortex_A5", 2 },
- { 0xc07, "Cortex-A7", "ARMv7_Cortex_A7", 4 },
- { 0xc08, "Cortex-A8", "ARMv7_Cortex_A8", 4 },
- { 0xc09, "Cortex-A9", "ARMv7_Cortex_A9", 6 },
- { 0xc0f, "Cortex-A15", "ARMv7_Cortex_A15", 6 },
- { 0xc0e, "Cortex-A17", "ARMv7_Cortex_A17", 6 },
- { 0x00f, "Scorpion", "Scorpion", 4 },
- { 0x02d, "ScorpionMP", "ScorpionMP", 4 },
- { 0x049, "KraitSIM", "Krait", 4 },
- { 0x04d, "Krait", "Krait", 4 },
- { 0x06f, "Krait S4 Pro", "Krait", 4 },
- { 0xd03, "Cortex-A53", "ARM_Cortex-A53", 6 },
- { 0xd07, "Cortex-A57", "ARM_Cortex-A57", 6 },
- { 0xd08, "Cortex-A72", "ARM_Cortex-A72", 6 },
- { 0xd0f, "AArch64", "ARM_AArch64", 6 },
+ { 0x41b36, "ARM1136", "ARM_ARM11", 3 },
+ { 0x41b56, "ARM1156", "ARM_ARM11", 3 },
+ { 0x41b76, "ARM1176", "ARM_ARM11", 3 },
+ { 0x41b02, "ARM11MPCore", "ARM_ARM11MPCore", 3 },
+ { 0x41c05, "Cortex-A5", "ARMv7_Cortex_A5", 2 },
+ { 0x41c07, "Cortex-A7", "ARMv7_Cortex_A7", 4 },
+ { 0x41c08, "Cortex-A8", "ARMv7_Cortex_A8", 4 },
+ { 0x41c09, "Cortex-A9", "ARMv7_Cortex_A9", 6 },
+ { 0x41c0f, "Cortex-A15", "ARMv7_Cortex_A15", 6 },
+ { 0x41c0d, "Cortex-A17", "ARMv7_Cortex_A17", 6 },
+ { 0x41c0e, "Cortex-A17", "ARMv7_Cortex_A17", 6 },
+ { 0x5100f, "Scorpion", "Scorpion", 4 },
+ { 0x5102d, "ScorpionMP", "ScorpionMP", 4 },
+ { 0x51049, "KraitSIM", "Krait", 4 },
+ { 0x5104d, "Krait", "Krait", 4 },
+ { 0x5106f, "Krait S4 Pro", "Krait", 4 },
+ { 0x41d03, "Cortex-A53", "ARM_Cortex-A53", 6 },
+ { 0x41d07, "Cortex-A57", "ARM_Cortex-A57", 6 },
+ { 0x41d08, "Cortex-A72", "ARM_Cortex-A72", 6 },
};
static const char OLD_PMU_PREFIX[] = "ARMv7 Cortex-";
@@ -70,17 +70,19 @@ struct uncore_counter {
// gatorfs event name
const char *const gatorName;
const int count;
+ const bool hasCyclesCounter;
};
static const struct uncore_counter uncore_counters[] = {
- { "CCI_400", "CCI_400", 4 },
- { "CCI_400-r1", "CCI_400-r1", 4 },
- { "ccn", "ARM_CCN_5XX", 8 },
+ { "CCI_400", "CCI_400", 4, true },
+ { "CCI_400-r1", "CCI_400-r1", 4, true },
+ { "CCI_500", "CCI_500", 8, false },
+ { "ccn", "ARM_CCN_5XX", 8, true },
};
class PerfCounter : public DriverCounter {
public:
- PerfCounter(DriverCounter *next, const char *name, uint32_t type, uint64_t config, bool perCpu) : DriverCounter(next, name), mType(type), mCount(0), mConfig(config), mPerCpu(perCpu) {}
+ PerfCounter(DriverCounter *next, const char *name, uint32_t type, uint64_t config, uint64_t sampleType, uint64_t flags) : DriverCounter(next, name), mType(type), mConfig(config), mSampleType(sampleType), mFlags(flags), mCount(0) {}
~PerfCounter() {
}
@@ -90,13 +92,41 @@ public:
void setCount(const int count) { mCount = count; }
uint64_t getConfig() const { return mConfig; }
void setConfig(const uint64_t config) { mConfig = config; }
- bool isPerCpu() const { return mPerCpu; }
+ uint64_t getSampleType() const { return mSampleType; }
+ uint64_t getFlags() const { return mFlags; }
+ virtual void read(Buffer *const, const int) {}
private:
const uint32_t mType;
- int mCount;
uint64_t mConfig;
- bool mPerCpu;
+ const uint64_t mSampleType;
+ const uint64_t mFlags;
+ int mCount;
+
+ // Intentionally undefined
+ PerfCounter(const PerfCounter &);
+ PerfCounter &operator=(const PerfCounter &);
+};
+
+class CPUFreqDriver : public PerfCounter {
+public:
+ CPUFreqDriver(DriverCounter *next, uint64_t id) : PerfCounter(next, "Linux_power_cpu_freq", PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_RAW, PERF_GROUP_LEADER | PERF_GROUP_PER_CPU) {}
+
+ void read(Buffer *const buffer, const int cpu) {
+ char buf[64];
+
+ snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu%i/cpufreq/cpuinfo_cur_freq", cpu);
+ int64_t freq;
+ if (DriverSource::readInt64Driver(buf, &freq) != 0) {
+ freq = 0;
+ }
+ buffer->perfCounter(cpu, getKey(), 1000*freq);
+ }
+
+private:
+ // Intentionally undefined
+ CPUFreqDriver(const CPUFreqDriver &);
+ CPUFreqDriver &operator=(const CPUFreqDriver &);
};
PerfDriver::PerfDriver() : mIsSetup(false), mLegacySupport(false) {
@@ -109,27 +139,32 @@ void PerfDriver::addCpuCounters(const char *const counterName, const int type, c
int len = snprintf(NULL, 0, "%s_ccnt", counterName) + 1;
char *name = new char[len];
snprintf(name, len, "%s_ccnt", counterName);
- setCounters(new PerfCounter(getCounters(), name, type, -1, true));
+ setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU));
for (int j = 0; j < numCounters; ++j) {
len = snprintf(NULL, 0, "%s_cnt%d", counterName, j) + 1;
name = new char[len];
snprintf(name, len, "%s_cnt%d", counterName, j);
- setCounters(new PerfCounter(getCounters(), name, type, -1, true));
+ setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU));
}
}
-void PerfDriver::addUncoreCounters(const char *const counterName, const int type, const int numCounters) {
- int len = snprintf(NULL, 0, "%s_ccnt", counterName) + 1;
- char *name = new char[len];
- snprintf(name, len, "%s_ccnt", counterName);
- setCounters(new PerfCounter(getCounters(), name, type, -1, false));
+void PerfDriver::addUncoreCounters(const char *const counterName, const int type, const int numCounters, const bool hasCyclesCounter) {
+ int len;
+ char *name;
+
+ if (hasCyclesCounter) {
+ len = snprintf(NULL, 0, "%s_ccnt", counterName) + 1;
+ name = new char[len];
+ snprintf(name, len, "%s_ccnt", counterName);
+ setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, 0));
+ }
for (int j = 0; j < numCounters; ++j) {
len = snprintf(NULL, 0, "%s_cnt%d", counterName, j) + 1;
name = new char[len];
snprintf(name, len, "%s_cnt%d", counterName, j);
- setCounters(new PerfCounter(getCounters(), name, type, -1, false));
+ setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, 0));
}
}
@@ -137,18 +172,18 @@ bool PerfDriver::setup() {
// Check the kernel version
int release[3];
if (!getLinuxVersion(release)) {
- logg->logMessage("%s(%s:%i): getLinuxVersion failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("getLinuxVersion failed");
return false;
}
if (KERNEL_VERSION(release[0], release[1], release[2]) < KERNEL_VERSION(3, 4, 0)) {
- logg->logMessage("%s(%s:%i): Unsupported kernel version", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("Unsupported kernel version");
return false;
}
mLegacySupport = KERNEL_VERSION(release[0], release[1], release[2]) < KERNEL_VERSION(3, 12, 0);
if (access(EVENTS_PATH, R_OK) != 0) {
- logg->logMessage("%s(%s:%i): " EVENTS_PATH " does not exist, is CONFIG_TRACING and CONFIG_CONTEXT_SWITCH_TRACER enabled?", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage(EVENTS_PATH " does not exist, is CONFIG_TRACING and CONFIG_CONTEXT_SWITCH_TRACER enabled?");
return false;
}
@@ -156,7 +191,7 @@ bool PerfDriver::setup() {
bool foundCpu = false;
DIR *dir = opendir(PERF_DEVICES);
if (dir == NULL) {
- logg->logMessage("%s(%s:%i): opendif failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("opendir failed");
return false;
}
@@ -199,7 +234,7 @@ bool PerfDriver::setup() {
}
logg->logMessage("Adding uncore counters for %s", uncore_counters[i].gatorName);
- addUncoreCounters(uncore_counters[i].gatorName, type, uncore_counters[i].count);
+ addUncoreCounters(uncore_counters[i].gatorName, type, uncore_counters[i].count, uncore_counters[i].hasCyclesCounter);
}
}
closedir(dir);
@@ -217,13 +252,11 @@ bool PerfDriver::setup() {
}
}
- /*
if (!foundCpu) {
- // If all else fails, use the perf architected counters
- // 9 because that's how many are in events-Perf-Hardware.xml - assume they can all be enabled at once
- addCpuCounters("Perf_Hardware", PERF_TYPE_HARDWARE, 9);
+ // If all else fails, use the ARM architected counters
+ logg->logMessage("Using Other cpu");
+ addCpuCounters("Other", PERF_TYPE_RAW, 6);
}
- */
// Add supported software counters
long long id;
@@ -231,20 +264,25 @@ bool PerfDriver::setup() {
id = getTracepointId("irq/softirq_exit", &printb);
if (id >= 0) {
- setCounters(new PerfCounter(getCounters(), "Linux_irq_softirq", PERF_TYPE_TRACEPOINT, id, true));
+ setCounters(new PerfCounter(getCounters(), "Linux_irq_softirq", PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU));
}
id = getTracepointId("irq/irq_handler_exit", &printb);
if (id >= 0) {
- setCounters(new PerfCounter(getCounters(), "Linux_irq_irq", PERF_TYPE_TRACEPOINT, id, true));
+ setCounters(new PerfCounter(getCounters(), "Linux_irq_irq", PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU));
}
id = getTracepointId(SCHED_SWITCH, &printb);
if (id >= 0) {
- setCounters(new PerfCounter(getCounters(), "Linux_sched_switch", PERF_TYPE_TRACEPOINT, id, true));
+ setCounters(new PerfCounter(getCounters(), "Linux_sched_switch", PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU));
+ }
+
+ id = getTracepointId(CPU_FREQUENCY, &printb);
+ if (id >= 0) {
+ setCounters(new CPUFreqDriver(getCounters(), id));
}
- setCounters(new PerfCounter(getCounters(), "Linux_cpu_wait_contention", TYPE_DERIVED, -1, false));
+ setCounters(new PerfCounter(getCounters(), "Linux_cpu_wait_contention", TYPE_DERIVED, -1, 0, 0));
//Linux_cpu_wait_io
@@ -255,7 +293,7 @@ bool PerfDriver::setup() {
bool PerfDriver::summary(Buffer *const buffer) {
struct utsname utsname;
if (uname(&utsname) != 0) {
- logg->logMessage("%s(%s:%i): uname failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("uname failed");
return false;
}
@@ -264,25 +302,26 @@ bool PerfDriver::summary(Buffer *const buffer) {
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
- logg->logMessage("%s(%s:%i): clock_gettime failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("clock_gettime failed");
return false;
}
const int64_t timestamp = (int64_t)ts.tv_sec * NS_PER_S + ts.tv_nsec;
const uint64_t monotonicStarted = getTime();
gSessionData->mMonotonicStarted = monotonicStarted;
+ const uint64_t currTime = 0;//getTime() - gSessionData->mMonotonicStarted;
- buffer->summary(monotonicStarted, timestamp, monotonicStarted, monotonicStarted, buf);
+ buffer->summary(currTime, timestamp, monotonicStarted, monotonicStarted, buf);
for (int i = 0; i < gSessionData->mCores; ++i) {
- coreName(monotonicStarted, buffer, i);
+ coreName(currTime, buffer, i);
}
- buffer->commit(monotonicStarted);
+ buffer->commit(currTime);
return true;
}
-void PerfDriver::coreName(const uint32_t startTime, Buffer *const buffer, const int cpu) {
+void PerfDriver::coreName(const uint64_t currTime, Buffer *const buffer, const int cpu) {
// Don't send information on a cpu we know nothing about
if (gSessionData->mCpuIds[cpu] == -1) {
return;
@@ -294,8 +333,8 @@ void PerfDriver::coreName(const uint32_t startTime, Buffer *const buffer, const
break;
}
}
- if (gator_cpus[j].cpuid == gSessionData->mCpuIds[cpu]) {
- buffer->coreName(startTime, cpu, gSessionData->mCpuIds[cpu], gator_cpus[j].core_name);
+ if (j < ARRAY_LENGTH(gator_cpus) && gator_cpus[j].cpuid == gSessionData->mCpuIds[cpu]) {
+ buffer->coreName(currTime, cpu, gSessionData->mCpuIds[cpu], gator_cpus[j].core_name);
} else {
char buf[32];
if (gSessionData->mCpuIds[cpu] == -1) {
@@ -303,7 +342,7 @@ void PerfDriver::coreName(const uint32_t startTime, Buffer *const buffer, const
} else {
snprintf(buf, sizeof(buf), "Unknown (0x%.3x)", gSessionData->mCpuIds[cpu]);
}
- buffer->coreName(startTime, cpu, gSessionData->mCpuIds[cpu], buf);
+ buffer->coreName(currTime, cpu, gSessionData->mCpuIds[cpu], buf);
}
}
@@ -326,8 +365,17 @@ void PerfDriver::setupCounter(Counter &counter) {
bool PerfDriver::enable(const uint64_t currTime, PerfGroup *const group, Buffer *const buffer) const {
for (PerfCounter *counter = static_cast<PerfCounter *>(getCounters()); counter != NULL; counter = static_cast<PerfCounter *>(counter->getNext())) {
if (counter->isEnabled() && (counter->getType() != TYPE_DERIVED)) {
- if (!group->add(currTime, buffer, counter->getKey(), counter->getType(), counter->getConfig(), counter->getCount(), counter->getCount() > 0 ? PERF_SAMPLE_TID | PERF_SAMPLE_IP : 0, counter->isPerCpu() ? PERF_GROUP_PER_CPU : 0)) {
- logg->logMessage("%s(%s:%i): PerfGroup::add failed", __FUNCTION__, __FILE__, __LINE__);
+ int count = counter->getCount();
+ uint64_t sampleType = counter->getSampleType();
+ if (sampleType & PERF_SAMPLE_RAW) {
+ // If raw is enabled, every sample is needed
+ count = 1;
+ }
+ if (!group->add(currTime, buffer, counter->getKey(), counter->getType(), counter->getConfig(), count,
+ // use getCount instead of count as EBS counters need TID and IP but RAW tracepoints don't
+ (counter->getCount() > 0 ? PERF_SAMPLE_TID | PERF_SAMPLE_IP : 0) | sampleType,
+ counter->getFlags())) {
+ logg->logMessage("PerfGroup::add failed");
return false;
}
}
@@ -336,15 +384,24 @@ bool PerfDriver::enable(const uint64_t currTime, PerfGroup *const group, Buffer
return true;
}
+void PerfDriver::read(Buffer *const buffer, const int cpu) {
+ for (PerfCounter *counter = static_cast<PerfCounter *>(getCounters()); counter != NULL; counter = static_cast<PerfCounter *>(counter->getNext())) {
+ if (!counter->isEnabled()) {
+ continue;
+ }
+ counter->read(buffer, cpu);
+ }
+}
+
long long PerfDriver::getTracepointId(const char *const name, DynBuf *const printb) {
if (!printb->printf(EVENTS_PATH "/%s/id", name)) {
- logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::printf failed");
return -1;
}
int64_t result;
if (DriverSource::readInt64Driver(printb->getBuf(), &result) != 0) {
- logg->logMessage("%s(%s:%i): DriverSource::readInt64Driver failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DriverSource::readInt64Driver failed");
return -1;
}
diff --git a/daemon/PerfDriver.h b/daemon/PerfDriver.h
index 846203a..95b42bf 100644
--- a/daemon/PerfDriver.h
+++ b/daemon/PerfDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
#define SCHED_SWITCH "sched/sched_switch"
#define CPU_IDLE "power/cpu_idle"
+#define CPU_FREQUENCY "power/cpu_frequency"
class Buffer;
class DynBuf;
@@ -33,18 +34,19 @@ public:
bool setup();
bool summary(Buffer *const buffer);
- void coreName(const uint32_t startTime, Buffer *const buffer, const int cpu);
+ void coreName(const uint64_t currTime, Buffer *const buffer, const int cpu);
bool isSetup() const { return mIsSetup; }
void setupCounter(Counter &counter);
bool enable(const uint64_t currTime, PerfGroup *const group, Buffer *const buffer) const;
+ void read(Buffer *const buffer, const int cpu);
static long long getTracepointId(const char *const name, DynBuf *const printb);
private:
void addCpuCounters(const char *const counterName, const int type, const int numCounters);
- void addUncoreCounters(const char *const counterName, const int type, const int numCounters);
+ void addUncoreCounters(const char *const counterName, const int type, const int numCounters, const bool hasCyclesCounter);
bool mIsSetup;
bool mLegacySupport;
diff --git a/daemon/PerfGroup.cpp b/daemon/PerfGroup.cpp
index 4fd960a..cfc62e4 100644
--- a/daemon/PerfGroup.cpp
+++ b/daemon/PerfGroup.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -16,17 +16,21 @@
#include <unistd.h>
#include "Buffer.h"
+#include "DynBuf.h"
#include "Logging.h"
#include "Monitor.h"
#include "PerfBuffer.h"
#include "SessionData.h"
+static const int schedSwitchKey = getEventKey();
+static const int clockKey = getEventKey();
+
#define DEFAULT_PEA_ARGS(pea, additionalSampleType) \
pea.size = sizeof(pea); \
/* Emit time, read_format below, group leader id, and raw tracepoint info */ \
pea.sample_type = (gSessionData->perf.getLegacySupport() \
- ? PERF_SAMPLE_TID | PERF_SAMPLE_IP | PERF_SAMPLE_TIME | PERF_SAMPLE_READ | PERF_SAMPLE_ID \
- : PERF_SAMPLE_TIME | PERF_SAMPLE_READ | PERF_SAMPLE_IDENTIFIER ) | additionalSampleType; \
+ ? PERF_SAMPLE_TID | PERF_SAMPLE_IP | PERF_SAMPLE_ID \
+ : PERF_SAMPLE_IDENTIFIER ) | PERF_SAMPLE_TIME | additionalSampleType; \
/* Emit emit value in group format */ \
pea.read_format = PERF_FORMAT_ID | PERF_FORMAT_GROUP; \
/* start out disabled */ \
@@ -49,11 +53,12 @@ static int sys_perf_event_open(struct perf_event_attr *const attr, const pid_t p
return fd;
}
-PerfGroup::PerfGroup(PerfBuffer *const pb) : mPb(pb) {
+PerfGroup::PerfGroup(PerfBuffer *const pb) : mPb(pb), mSchedSwitchId(-1) {
memset(&mAttrs, 0, sizeof(mAttrs));
- memset(&mPerCpu, 0, sizeof(mPerCpu));
+ memset(&mFlags, 0, sizeof(mFlags));
memset(&mKeys, -1, sizeof(mKeys));
memset(&mFds, -1, sizeof(mFds));
+ memset(&mLeaders, -1, sizeof(mLeaders));
}
PerfGroup::~PerfGroup() {
@@ -64,7 +69,7 @@ PerfGroup::~PerfGroup() {
}
}
-bool PerfGroup::add(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags) {
+int PerfGroup::doAdd(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags) {
int i;
for (i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
if (mKeys[i] < 0) {
@@ -73,8 +78,8 @@ bool PerfGroup::add(const uint64_t currTime, Buffer *const buffer, const int key
}
if (i >= ARRAY_LENGTH(mKeys)) {
- logg->logMessage("%s(%s:%i): Too many counters", __FUNCTION__, __FILE__, __LINE__);
- return false;
+ logg->logMessage("Too many counters");
+ return -1;
}
DEFAULT_PEA_ARGS(mAttrs[i], sampleType);
@@ -82,121 +87,230 @@ bool PerfGroup::add(const uint64_t currTime, Buffer *const buffer, const int key
mAttrs[i].config = config;
mAttrs[i].sample_period = sample;
// always be on the CPU but only a group leader can be pinned
- mAttrs[i].pinned = (i == 0 ? 1 : 0);
+ mAttrs[i].pinned = (flags & PERF_GROUP_LEADER ? 1 : 0);
mAttrs[i].mmap = (flags & PERF_GROUP_MMAP ? 1 : 0);
mAttrs[i].comm = (flags & PERF_GROUP_COMM ? 1 : 0);
mAttrs[i].freq = (flags & PERF_GROUP_FREQ ? 1 : 0);
mAttrs[i].task = (flags & PERF_GROUP_TASK ? 1 : 0);
mAttrs[i].sample_id_all = (flags & PERF_GROUP_SAMPLE_ID_ALL ? 1 : 0);
- mPerCpu[i] = (flags & PERF_GROUP_PER_CPU);
+ mFlags[i] = flags;
mKeys[i] = key;
- buffer->pea(currTime, &mAttrs[i], key);
+ buffer->marshalPea(currTime, &mAttrs[i], key);
+
+ return i;
+}
+
+/* Counters from different hardware PMUs need to be in different
+ * groups. Software counters can be in the same group as the CPU and
+ * should be marked as PERF_GROUP_CPU. The big and little clusters can
+ * be in the same group as only one or the other will be available on
+ * a given CPU.
+ */
+int PerfGroup::getEffectiveType(const int type, const int flags) {
+ const int effectiveType = flags & PERF_GROUP_CPU ? (int)PERF_TYPE_HARDWARE : type;
+ if (effectiveType >= ARRAY_LENGTH(mLeaders)) {
+ logg->logError("perf type is too large, please increase the size of PerfGroup::mLeaders");
+ handleException();
+ }
+ return effectiveType;
+}
+
+bool PerfGroup::createCpuGroup(const uint64_t currTime, Buffer *const buffer) {
+ if (mSchedSwitchId < 0) {
+ DynBuf b;
+ mSchedSwitchId = PerfDriver::getTracepointId(SCHED_SWITCH, &b);
+ if (mSchedSwitchId < 0) {
+ logg->logMessage("Unable to read sched_switch id");
+ return false;
+ }
+ }
+
+ mLeaders[PERF_TYPE_HARDWARE] = doAdd(currTime, buffer, schedSwitchKey, PERF_TYPE_TRACEPOINT, mSchedSwitchId, 1, PERF_SAMPLE_READ | PERF_SAMPLE_RAW, PERF_GROUP_MMAP | PERF_GROUP_COMM | PERF_GROUP_TASK | PERF_GROUP_SAMPLE_ID_ALL | PERF_GROUP_PER_CPU | PERF_GROUP_LEADER | PERF_GROUP_CPU);
+ if (mLeaders[PERF_TYPE_HARDWARE] < 0) {
+ return false;
+ }
+
+ if (gSessionData->mSampleRate > 0 && !gSessionData->mIsEBS && doAdd(currTime, buffer, clockKey, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, 1000000000UL / gSessionData->mSampleRate, PERF_SAMPLE_TID | PERF_SAMPLE_IP | PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU) < 0) {
+ return false;
+ }
return true;
}
+bool PerfGroup::add(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags) {
+ const int effectiveType = getEffectiveType(type, flags);
+
+ // Does a group exist for this already?
+ if (!(flags & PERF_GROUP_LEADER) && mLeaders[effectiveType] < 0) {
+ // Create it
+ if (effectiveType == PERF_TYPE_HARDWARE) {
+ if (!createCpuGroup(currTime, buffer)) {
+ return false;
+ }
+ } else {
+ // Non-CPU PMUs are sampled every 100ms for Sample Rate: None and EBS, otherwise they would never be sampled
+ const uint64_t timeout = gSessionData->mSampleRate > 0 && !gSessionData->mIsEBS ? 1000000000UL / gSessionData->mSampleRate : 100000000UL;
+ // PERF_SAMPLE_TID | PERF_SAMPLE_IP aren't helpful on non-CPU or 'uncore' PMUs - which CPU is the right one to sample? But removing it causes problems, remove it later.
+ mLeaders[effectiveType] = doAdd(currTime, buffer, clockKey, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, timeout, PERF_SAMPLE_TID | PERF_SAMPLE_IP | PERF_SAMPLE_READ, PERF_GROUP_LEADER);
+ if (mLeaders[effectiveType] < 0) {
+ return false;
+ }
+ }
+ }
+
+ if (!(flags & PERF_GROUP_LEADER) && effectiveType != PERF_TYPE_HARDWARE && (flags & PERF_GROUP_PER_CPU)) {
+ logg->logError("'uncore' counters are not permitted to be per-cpu");
+ handleException();
+ }
+
+ return doAdd(currTime, buffer, key, type, config, sample, sampleType, flags) >= 0;
+}
+
int PerfGroup::prepareCPU(const int cpu, Monitor *const monitor) {
- logg->logMessage("%s(%s:%i): Onlining cpu %i", __FUNCTION__, __FILE__, __LINE__, cpu);
+ logg->logMessage("Onlining cpu %i", cpu);
for (int i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
if (mKeys[i] < 0) {
continue;
}
- if ((cpu != 0) && !mPerCpu[i]) {
+ if ((cpu != 0) && !(mFlags[i] & PERF_GROUP_PER_CPU)) {
continue;
}
- const int offset = i * gSessionData->mCores;
- if (mFds[cpu + offset] >= 0) {
- logg->logMessage("%s(%s:%i): cpu already online or not correctly cleaned up", __FUNCTION__, __FILE__, __LINE__);
+ const int offset = i * gSessionData->mCores + cpu;
+ if (mFds[offset] >= 0) {
+ logg->logMessage("cpu already online or not correctly cleaned up");
return PG_FAILURE;
}
- logg->logMessage("%s(%s:%i): perf_event_open cpu: %i type: %lli config: %lli sample: %lli sample_type: 0x%llx pinned: %i mmap: %i comm: %i freq: %i task: %i sample_id_all: %i", __FUNCTION__, __FILE__, __LINE__, cpu, (long long)mAttrs[i].type, (long long)mAttrs[i].config, (long long)mAttrs[i].sample_period, (long long)mAttrs[i].sample_type, mAttrs[i].pinned, mAttrs[i].mmap, mAttrs[i].comm, mAttrs[i].freq, mAttrs[i].task, mAttrs[i].sample_id_all);
- mFds[cpu + offset] = sys_perf_event_open(&mAttrs[i], -1, cpu, i == 0 ? -1 : mFds[cpu], i == 0 ? 0 : PERF_FLAG_FD_OUTPUT);
- if (mFds[cpu + offset] < 0) {
- logg->logMessage("%s(%s:%i): failed %s", __FUNCTION__, __FILE__, __LINE__, strerror(errno));
+ logg->logMessage("perf_event_open cpu: %i type: %i config: %lli sample: %lli sample_type: 0x%llx pinned: %lli mmap: %lli comm: %lli freq: %lli task: %lli sample_id_all: %lli", cpu, mAttrs[i].type, mAttrs[i].config, mAttrs[i].sample_period, mAttrs[i].sample_type, mAttrs[i].pinned, mAttrs[i].mmap, mAttrs[i].comm, mAttrs[i].freq, mAttrs[i].task, mAttrs[i].sample_id_all);
+ mFds[offset] = sys_perf_event_open(&mAttrs[i], -1, cpu, mAttrs[i].pinned ? -1 : mFds[mLeaders[getEffectiveType(mAttrs[i].type, mFlags[i])] * gSessionData->mCores + cpu], mAttrs[i].pinned ? 0 : PERF_FLAG_FD_OUTPUT);
+ if (mFds[offset] < 0) {
+ logg->logMessage("failed %s", strerror(errno));
if (errno == ENODEV) {
+ // The core is offline
return PG_CPU_OFFLINE;
}
+#ifndef USE_STRICTER_CHECK
continue;
+#else
+ if (errno == ENOENT) {
+ // This event doesn't apply to this CPU but should apply to a different one, ex bL
+ continue;
+ }
+ logg->logMessage("perf_event_open failed");
+ return PG_FAILURE;
+#endif
}
- if (!mPb->useFd(cpu, mFds[cpu + offset])) {
- logg->logMessage("%s(%s:%i): PerfBuffer::useFd failed", __FUNCTION__, __FILE__, __LINE__);
+ if (!mPb->useFd(cpu, mFds[offset])) {
+ logg->logMessage("PerfBuffer::useFd failed");
return PG_FAILURE;
}
- if (!monitor->add(mFds[cpu + offset])) {
- logg->logMessage("%s(%s:%i): Monitor::add failed", __FUNCTION__, __FILE__, __LINE__);
- return PG_FAILURE;
+ if (!monitor->add(mFds[offset])) {
+ logg->logMessage("Monitor::add failed");
+ return PG_FAILURE;
}
}
return PG_SUCCESS;
}
-int PerfGroup::onlineCPU(const uint64_t currTime, const int cpu, const bool start, Buffer *const buffer) {
- __u64 ids[ARRAY_LENGTH(mKeys)];
- int coreKeys[ARRAY_LENGTH(mKeys)];
- int idCount = 0;
+static bool readAndSend(const uint64_t currTime, Buffer *const buffer, const int fd, const int keyCount, const int *const keys) {
+ char buf[1024];
+ ssize_t bytes = read(fd, buf, sizeof(buf));
+ if (bytes < 0) {
+ logg->logMessage("read failed");
+ return false;
+ }
+ buffer->marshalKeysOld(currTime, keyCount, keys, bytes, buf);
- for (int i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
- const int fd = mFds[cpu + i * gSessionData->mCores];
- if (fd < 0) {
- continue;
- }
+ return true;
+}
- coreKeys[idCount] = mKeys[i];
- if (!gSessionData->perf.getLegacySupport() && ioctl(fd, PERF_EVENT_IOC_ID, &ids[idCount]) != 0 &&
- // Workaround for running 32-bit gatord on 64-bit systems, kernel patch in the works
- ioctl(fd, (PERF_EVENT_IOC_ID & ~IOCSIZE_MASK) | (8 << _IOC_SIZESHIFT), &ids[idCount]) != 0) {
- logg->logMessage("%s(%s:%i): ioctl failed", __FUNCTION__, __FILE__, __LINE__);
- return 0;
- }
- ++idCount;
- }
+int PerfGroup::onlineCPU(const uint64_t currTime, const int cpu, const bool enable, Buffer *const buffer) {
+ bool addedEvents = false;
if (!gSessionData->perf.getLegacySupport()) {
- buffer->keys(currTime, idCount, ids, coreKeys);
+ int idCount = 0;
+ int coreKeys[ARRAY_LENGTH(mKeys)];
+ __u64 ids[ARRAY_LENGTH(mKeys)];
+
+ for (int i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
+ const int fd = mFds[cpu + i * gSessionData->mCores];
+ if (fd < 0) {
+ continue;
+ }
+
+ coreKeys[idCount] = mKeys[i];
+ if (ioctl(fd, PERF_EVENT_IOC_ID, &ids[idCount]) != 0 &&
+ // Workaround for running 32-bit gatord on 64-bit systems, kernel patch in the works
+ ioctl(fd, (PERF_EVENT_IOC_ID & ~IOCSIZE_MASK) | (8 << _IOC_SIZESHIFT), &ids[idCount]) != 0) {
+ logg->logMessage("ioctl failed");
+ return 0;
+ }
+ ++idCount;
+ addedEvents = true;
+ }
+
+ buffer->marshalKeys(currTime, idCount, ids, coreKeys);
} else {
- char buf[1024];
- ssize_t bytes = read(mFds[cpu], buf, sizeof(buf));
- if (bytes < 0) {
- logg->logMessage("read failed");
- return 0;
+ int idCounts[ARRAY_LENGTH(mLeaders)] = { 0 };
+ int coreKeys[ARRAY_LENGTH(mLeaders)][ARRAY_LENGTH(mKeys)];
+ for (int i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
+ const int fd = mFds[cpu + i * gSessionData->mCores];
+ if (fd < 0) {
+ continue;
+ }
+
+ const int effectiveType = getEffectiveType(mAttrs[i].type, mFlags[i]);
+ if (mAttrs[i].pinned && mLeaders[effectiveType] != i) {
+ if (!readAndSend(currTime, buffer, fd, 1, mKeys + i)) {
+ return 0;
+ }
+ } else {
+ coreKeys[effectiveType][idCounts[effectiveType]] = mKeys[i];
+ ++idCounts[effectiveType];
+ addedEvents = true;
+ }
+ }
+
+ for (int i = 0; i < ARRAY_LENGTH(mLeaders); ++i) {
+ if (idCounts[i] > 0 && !readAndSend(currTime, buffer, mFds[mLeaders[i] * gSessionData->mCores + cpu], idCounts[i], coreKeys[i])) {
+ return 0;
+ }
}
- buffer->keysOld(currTime, idCount, coreKeys, bytes, buf);
}
- if (start) {
+ if (enable) {
for (int i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
int offset = i * gSessionData->mCores + cpu;
if (mFds[offset] >= 0 && ioctl(mFds[offset], PERF_EVENT_IOC_ENABLE, 0) < 0) {
- logg->logMessage("%s(%s:%i): ioctl failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("ioctl failed");
return 0;
}
}
}
- if (idCount == 0) {
- logg->logMessage("%s(%s:%i): no events came online", __FUNCTION__, __FILE__, __LINE__);
+ if (!addedEvents) {
+ logg->logMessage("no events came online");
}
- return idCount;
+ return 1;
}
bool PerfGroup::offlineCPU(const int cpu) {
- logg->logMessage("%s(%s:%i): Offlining cpu %i", __FUNCTION__, __FILE__, __LINE__, cpu);
+ logg->logMessage("Offlining cpu %i", cpu);
- for (int i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
+ for (int i = ARRAY_LENGTH(mKeys) - 1; i >= 0; --i) {
int offset = i * gSessionData->mCores + cpu;
if (mFds[offset] >= 0 && ioctl(mFds[offset], PERF_EVENT_IOC_DISABLE, 0) < 0) {
- logg->logMessage("%s(%s:%i): ioctl failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("ioctl failed");
return false;
}
}
@@ -204,7 +318,7 @@ bool PerfGroup::offlineCPU(const int cpu) {
// Mark the buffer so that it will be released next time it's read
mPb->discard(cpu);
- for (int i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
+ for (int i = ARRAY_LENGTH(mKeys) - 1; i >= 0; --i) {
if (mKeys[i] < 0) {
continue;
}
@@ -222,7 +336,7 @@ bool PerfGroup::offlineCPU(const int cpu) {
bool PerfGroup::start() {
for (int pos = 0; pos < ARRAY_LENGTH(mFds); ++pos) {
if (mFds[pos] >= 0 && ioctl(mFds[pos], PERF_EVENT_IOC_ENABLE, 0) < 0) {
- logg->logMessage("%s(%s:%i): ioctl failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("ioctl failed");
goto fail;
}
}
diff --git a/daemon/PerfGroup.h b/daemon/PerfGroup.h
index f7b3d72..f30d3a6 100644
--- a/daemon/PerfGroup.h
+++ b/daemon/PerfGroup.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -27,6 +27,8 @@ enum PerfGroupFlags {
PERF_GROUP_TASK = 1 << 3,
PERF_GROUP_SAMPLE_ID_ALL = 1 << 4,
PERF_GROUP_PER_CPU = 1 << 5,
+ PERF_GROUP_LEADER = 1 << 6,
+ PERF_GROUP_CPU = 1 << 7,
};
enum {
@@ -40,22 +42,29 @@ public:
PerfGroup(PerfBuffer *const pb);
~PerfGroup();
+ bool createCpuGroup(const uint64_t currTime, Buffer *const buffer);
bool add(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags);
// Safe to call concurrently
int prepareCPU(const int cpu, Monitor *const monitor);
// Not safe to call concurrently. Returns the number of events enabled
- int onlineCPU(const uint64_t currTime, const int cpu, const bool start, Buffer *const buffer);
+ int onlineCPU(const uint64_t currTime, const int cpu, const bool enable, Buffer *const buffer);
bool offlineCPU(int cpu);
bool start();
void stop();
private:
- // +1 for the group leader
- struct perf_event_attr mAttrs[MAX_PERFORMANCE_COUNTERS + 1];
- bool mPerCpu[MAX_PERFORMANCE_COUNTERS + 1];
- int mKeys[MAX_PERFORMANCE_COUNTERS + 1];
- int mFds[NR_CPUS * (MAX_PERFORMANCE_COUNTERS + 1)];
+ int getEffectiveType(const int type, const int flags);
+ int doAdd(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags);
+
+ // 2* to be conservative for sched_switch, cpu_idle, hrtimer and non-CPU groups
+ struct perf_event_attr mAttrs[2*MAX_PERFORMANCE_COUNTERS];
PerfBuffer *const mPb;
+ int mFlags[2*MAX_PERFORMANCE_COUNTERS];
+ int mKeys[2*MAX_PERFORMANCE_COUNTERS];
+ int mFds[NR_CPUS * (2*MAX_PERFORMANCE_COUNTERS)];
+ // Offset in mAttrs, mFlags and mKeys of the group leaders for each perf type
+ int mLeaders[16];
+ int mSchedSwitchId;
// Intentionally undefined
PerfGroup(const PerfGroup &);
diff --git a/daemon/PerfSource.cpp b/daemon/PerfSource.cpp
index 193b778..2c45de8 100644
--- a/daemon/PerfSource.cpp
+++ b/daemon/PerfSource.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -31,16 +31,18 @@
extern Child *child;
+static const int cpuIdleKey = getEventKey();
+
static bool sendTracepointFormat(const uint64_t currTime, Buffer *const buffer, const char *const name, DynBuf *const printb, DynBuf *const b) {
if (!printb->printf(EVENTS_PATH "/%s/format", name)) {
- logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::printf failed");
return false;
}
if (!b->read(printb->getBuf())) {
- logg->logMessage("%s(%s:%i): DynBuf::read failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::read failed");
return false;
}
- buffer->format(currTime, b->getLength(), b->getBuf());
+ buffer->marshalFormat(currTime, b->getLength(), b->getBuf());
return true;
}
@@ -58,18 +60,18 @@ static void *syncFunc(void *arg)
{
sigset_t set;
if (sigfillset(&set) != 0) {
- logg->logError(__FILE__, __LINE__, "sigfillset failed");
+ logg->logError("sigfillset failed");
handleException();
}
if ((err = pthread_sigmask(SIG_SETMASK, &set, NULL)) != 0) {
- logg->logError(__FILE__, __LINE__, "pthread_sigmask failed");
+ logg->logError("pthread_sigmask failed");
handleException();
}
}
for (;;) {
if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) {
- logg->logError(__FILE__, __LINE__, "clock_gettime failed");
+ logg->logError("clock_gettime failed");
handleException();
}
const int64_t currTime = ts.tv_sec * NS_PER_S + ts.tv_nsec;
@@ -95,7 +97,7 @@ static void *syncFunc(void *arg)
static long getMaxCoreNum() {
DIR *dir = opendir("/sys/devices/system/cpu");
if (dir == NULL) {
- logg->logError(__FILE__, __LINE__, "Unable to determine the number of cores on the target, opendir failed");
+ logg->logError("Unable to determine the number of cores on the target, opendir failed");
handleException();
}
@@ -114,22 +116,22 @@ static long getMaxCoreNum() {
closedir(dir);
if (maxCoreNum < 1) {
- logg->logError(__FILE__, __LINE__, "Unable to determine the number of cores on the target, no cpu# directories found");
+ logg->logError("Unable to determine the number of cores on the target, no cpu# directories found");
handleException();
}
if (maxCoreNum >= NR_CPUS) {
- logg->logError(__FILE__, __LINE__, "Too many cores on the target, please increase NR_CPUS in Config.h");
+ logg->logError("Too many cores on the target, please increase NR_CPUS in Config.h");
handleException();
}
return maxCoreNum;
}
-PerfSource::PerfSource(sem_t *senderSem, sem_t *startProfile) : mSummary(0, FRAME_SUMMARY, 1024, senderSem), mBuffer(0, FRAME_PERF_ATTRS, 1024*1024, senderSem), mCountersBuf(), mCountersGroup(&mCountersBuf), mIdleGroup(&mCountersBuf), mMonitor(), mUEvent(), mSenderSem(senderSem), mStartProfile(startProfile), mInterruptFd(-1), mIsDone(false) {
+PerfSource::PerfSource(sem_t *senderSem, sem_t *startProfile) : mSummary(0, FRAME_SUMMARY, 1024, senderSem), mBuffer(NULL), mCountersBuf(), mCountersGroup(&mCountersBuf), mMonitor(), mUEvent(), mSenderSem(senderSem), mStartProfile(startProfile), mInterruptFd(-1), mIsDone(false) {
long l = sysconf(_SC_PAGE_SIZE);
if (l < 0) {
- logg->logError(__FILE__, __LINE__, "Unable to obtain the page size");
+ logg->logError("Unable to obtain the page size");
handleException();
}
gSessionData->mPageSize = static_cast<int>(l);
@@ -137,15 +139,18 @@ PerfSource::PerfSource(sem_t *senderSem, sem_t *startProfile) : mSummary(0, FRAM
}
PerfSource::~PerfSource() {
+ delete mBuffer;
}
bool PerfSource::prepare() {
DynBuf printb;
DynBuf b1;
- long long schedSwitchId;
long long cpuIdleId;
- const uint64_t currTime = getTime();
+ // MonotonicStarted has not yet been assigned!
+ const uint64_t currTime = 0;//getTime() - gSessionData->mMonotonicStarted;
+
+ mBuffer = new Buffer(0, FRAME_PERF_ATTRS, gSessionData->mTotalBufferSize*1024*1024, mSenderSem);
// Reread cpuinfo since cores may have changed since startup
gSessionData->readCpuInfo();
@@ -155,72 +160,59 @@ bool PerfSource::prepare() {
|| !mUEvent.init()
|| !mMonitor.add(mUEvent.getFd())
- || (schedSwitchId = PerfDriver::getTracepointId(SCHED_SWITCH, &printb)) < 0
- || !sendTracepointFormat(currTime, &mBuffer, SCHED_SWITCH, &printb, &b1)
+ || !sendTracepointFormat(currTime, mBuffer, SCHED_SWITCH, &printb, &b1)
|| (cpuIdleId = PerfDriver::getTracepointId(CPU_IDLE, &printb)) < 0
- || !sendTracepointFormat(currTime, &mBuffer, CPU_IDLE, &printb, &b1)
+ || !sendTracepointFormat(currTime, mBuffer, CPU_IDLE, &printb, &b1)
- // Only want RAW but not IP on sched_switch and don't want TID on SAMPLE_ID
- || !mCountersGroup.add(currTime, &mBuffer, 100/**/, PERF_TYPE_TRACEPOINT, schedSwitchId, 1, PERF_SAMPLE_RAW, PERF_GROUP_MMAP | PERF_GROUP_COMM | PERF_GROUP_TASK | PERF_GROUP_SAMPLE_ID_ALL | PERF_GROUP_PER_CPU)
- || !mIdleGroup.add(currTime, &mBuffer, 101/**/, PERF_TYPE_TRACEPOINT, cpuIdleId, 1, PERF_SAMPLE_RAW, PERF_GROUP_PER_CPU)
+ || !sendTracepointFormat(currTime, mBuffer, CPU_FREQUENCY, &printb, &b1)
- // Only want TID and IP but not RAW on timer
- || (gSessionData->mSampleRate > 0 && !gSessionData->mIsEBS && !mCountersGroup.add(currTime, &mBuffer, 102/**/, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, 1000000000UL / gSessionData->mSampleRate, PERF_SAMPLE_TID | PERF_SAMPLE_IP, PERF_GROUP_PER_CPU))
+ || !mCountersGroup.createCpuGroup(currTime, mBuffer)
+ || !mCountersGroup.add(currTime, mBuffer, cpuIdleKey, PERF_TYPE_TRACEPOINT, cpuIdleId, 1, PERF_SAMPLE_RAW, PERF_GROUP_LEADER | PERF_GROUP_PER_CPU)
- || !gSessionData->perf.enable(currTime, &mCountersGroup, &mBuffer)
+ || !gSessionData->perf.enable(currTime, &mCountersGroup, mBuffer)
|| 0) {
- logg->logMessage("%s(%s:%i): perf setup failed, are you running Linux 3.4 or later?", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("perf setup failed, are you running Linux 3.4 or later?");
return false;
}
for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
const int result = mCountersGroup.prepareCPU(cpu, &mMonitor);
if ((result != PG_SUCCESS) && (result != PG_CPU_OFFLINE)) {
- logg->logError(__FILE__, __LINE__, "PerfGroup::prepareCPU on mCountersGroup failed");
- handleException();
- }
- }
- for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
- const int result = mIdleGroup.prepareCPU(cpu, &mMonitor);
- if ((result != PG_SUCCESS) && (result != PG_CPU_OFFLINE)) {
- logg->logError(__FILE__, __LINE__, "PerfGroup::prepareCPU on mIdleGroup failed");
+ logg->logError("PerfGroup::prepareCPU on mCountersGroup failed");
handleException();
}
}
int numEvents = 0;
for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
- numEvents += mCountersGroup.onlineCPU(currTime, cpu, false, &mBuffer);
- }
- for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
- numEvents += mIdleGroup.onlineCPU(currTime, cpu, false, &mBuffer);
+ numEvents += mCountersGroup.onlineCPU(currTime, cpu, false, mBuffer);
}
if (numEvents <= 0) {
- logg->logMessage("%s(%s:%i): PerfGroup::onlineCPU failed on all cores", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("PerfGroup::onlineCPU failed on all cores");
return false;
}
// Send the summary right before the start so that the monotonic delta is close to the start time
if (!gSessionData->perf.summary(&mSummary)) {
- logg->logError(__FILE__, __LINE__, "PerfDriver::summary failed", __FUNCTION__, __FILE__, __LINE__);
- handleException();
+ logg->logError("PerfDriver::summary failed");
+ handleException();
}
// Start the timer thread to used to sync perf and monotonic raw times
pthread_t syncThread;
if (pthread_create(&syncThread, NULL, syncFunc, NULL)) {
- logg->logError(__FILE__, __LINE__, "pthread_create failed", __FUNCTION__, __FILE__, __LINE__);
- handleException();
+ logg->logError("pthread_create failed");
+ handleException();
}
struct sched_param param;
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
if (pthread_setschedparam(syncThread, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
- logg->logError(__FILE__, __LINE__, "pthread_setschedparam failed");
- handleException();
+ logg->logError("pthread_setschedparam failed");
+ handleException();
}
- mBuffer.commit(currTime);
+ mBuffer->commit(currTime);
return true;
}
@@ -240,18 +232,17 @@ void *procFunc(void *arg) {
// Gator runs at a high priority, reset the priority to the default
if (setpriority(PRIO_PROCESS, syscall(__NR_gettid), 0) == -1) {
- logg->logError(__FILE__, __LINE__, "setpriority failed");
+ logg->logError("setpriority failed");
handleException();
}
if (!readProcMaps(args->mCurrTime, args->mBuffer, &printb, &b)) {
- logg->logError(__FILE__, __LINE__, "readProcMaps failed");
+ logg->logError("readProcMaps failed");
handleException();
}
- args->mBuffer->commit(args->mCurrTime);
if (!readKallsyms(args->mCurrTime, args->mBuffer, &args->mIsDone)) {
- logg->logError(__FILE__, __LINE__, "readKallsyms failed");
+ logg->logError("readKallsyms failed");
handleException();
}
args->mBuffer->commit(args->mCurrTime);
@@ -266,67 +257,72 @@ void PerfSource::run() {
pthread_t procThread;
ProcThreadArgs procThreadArgs;
+ if (pipe_cloexec(pipefd) != 0) {
+ logg->logError("pipe failed");
+ handleException();
+ }
+ mInterruptFd = pipefd[1];
+
+ if (!mMonitor.add(pipefd[0])) {
+ logg->logError("Monitor::add failed");
+ handleException();
+ }
+
{
DynBuf printb;
DynBuf b1;
DynBuf b2;
- const uint64_t currTime = getTime();
+ const uint64_t currTime = getTime() - gSessionData->mMonotonicStarted;
// Start events before reading proc to avoid race conditions
- if (!mCountersGroup.start() || !mIdleGroup.start()) {
- logg->logError(__FILE__, __LINE__, "PerfGroup::start failed", __FUNCTION__, __FILE__, __LINE__);
+ if (!mCountersGroup.start()) {
+ logg->logError("PerfGroup::start failed");
handleException();
}
- if (!readProcComms(currTime, &mBuffer, &printb, &b1, &b2)) {
- logg->logError(__FILE__, __LINE__, "readProcComms failed");
+ mBuffer->perfCounterHeader(currTime);
+ for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
+ gSessionData->perf.read(mBuffer, cpu);
+ }
+ mBuffer->perfCounterFooter(currTime);
+
+ if (!readProcComms(currTime, mBuffer, &printb, &b1, &b2)) {
+ logg->logError("readProcComms failed");
handleException();
}
- mBuffer.commit(currTime);
+ mBuffer->commit(currTime);
// Postpone reading kallsyms as on android adb gets too backed up and data is lost
- procThreadArgs.mBuffer = &mBuffer;
+ procThreadArgs.mBuffer = mBuffer;
procThreadArgs.mCurrTime = currTime;
procThreadArgs.mIsDone = false;
if (pthread_create(&procThread, NULL, procFunc, &procThreadArgs)) {
- logg->logError(__FILE__, __LINE__, "pthread_create failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logError("pthread_create failed");
handleException();
}
}
- if (pipe_cloexec(pipefd) != 0) {
- logg->logError(__FILE__, __LINE__, "pipe failed");
- handleException();
- }
- mInterruptFd = pipefd[1];
-
- if (!mMonitor.add(pipefd[0])) {
- logg->logError(__FILE__, __LINE__, "Monitor::add failed");
- handleException();
- }
-
- int timeout = -1;
- if (gSessionData->mLiveRate > 0) {
- timeout = gSessionData->mLiveRate/NS_PER_MS;
- }
-
sem_post(mStartProfile);
+ const uint64_t NO_RATE = ~0ULL;
+ const uint64_t rate = gSessionData->mLiveRate > 0 && gSessionData->mSampleRate > 0 ? gSessionData->mLiveRate : NO_RATE;
+ uint64_t nextTime = 0;
+ int timeout = rate != NO_RATE ? 0 : -1;
while (gSessionData->mSessionIsActive) {
// +1 for uevents, +1 for pipe
struct epoll_event events[NR_CPUS + 2];
int ready = mMonitor.wait(events, ARRAY_LENGTH(events), timeout);
if (ready < 0) {
- logg->logError(__FILE__, __LINE__, "Monitor::wait failed");
+ logg->logError("Monitor::wait failed");
handleException();
}
- const uint64_t currTime = getTime();
+ const uint64_t currTime = getTime() - gSessionData->mMonotonicStarted;
for (int i = 0; i < ready; ++i) {
if (events[i].data.fd == mUEvent.getFd()) {
if (!handleUEvent(currTime)) {
- logg->logError(__FILE__, __LINE__, "PerfSource::handleUEvent failed");
+ logg->logError("PerfSource::handleUEvent failed");
handleException();
}
break;
@@ -337,18 +333,24 @@ void PerfSource::run() {
sem_post(mSenderSem);
// In one shot mode, stop collection once all the buffers are filled
- // Assume timeout == 0 in this case
- if (gSessionData->mOneShot && gSessionData->mSessionIsActive) {
- logg->logMessage("%s(%s:%i): One shot", __FUNCTION__, __FILE__, __LINE__);
+ if (gSessionData->mOneShot && gSessionData->mSessionIsActive && ((mSummary.bytesAvailable() <= 0) || (mBuffer->bytesAvailable() <= 0) || mCountersBuf.isFull())) {
+ logg->logMessage("One shot (perf)");
child->endSession();
}
+
+ if (rate != NO_RATE) {
+ while (currTime > nextTime) {
+ nextTime += rate;
+ }
+ // + NS_PER_MS - 1 to ensure always rounding up
+ timeout = max(0, (int)((nextTime + NS_PER_MS - 1 - getTime() + gSessionData->mMonotonicStarted)/NS_PER_MS));
+ }
}
procThreadArgs.mIsDone = true;
pthread_join(procThread, NULL);
- mIdleGroup.stop();
mCountersGroup.stop();
- mBuffer.setDone();
+ mBuffer->setDone();
mIsDone = true;
// send a notification that data is ready
@@ -362,57 +364,53 @@ void PerfSource::run() {
bool PerfSource::handleUEvent(const uint64_t currTime) {
UEventResult result;
if (!mUEvent.read(&result)) {
- logg->logMessage("%s(%s:%i): UEvent::Read failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("UEvent::Read failed");
return false;
}
if (strcmp(result.mSubsystem, "cpu") == 0) {
if (strncmp(result.mDevPath, CPU_DEVPATH, sizeof(CPU_DEVPATH) - 1) != 0) {
- logg->logMessage("%s(%s:%i): Unexpected cpu DEVPATH format", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("Unexpected cpu DEVPATH format");
return false;
}
char *endptr;
errno = 0;
int cpu = strtol(result.mDevPath + sizeof(CPU_DEVPATH) - 1, &endptr, 10);
if (errno != 0 || *endptr != '\0') {
- logg->logMessage("%s(%s:%i): strtol failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("strtol failed");
return false;
}
if (cpu >= gSessionData->mCores) {
- logg->logError(__FILE__, __LINE__, "Only %i cores are expected but core %i reports %s", gSessionData->mCores, cpu, result.mAction);
+ logg->logError("Only %i cores are expected but core %i reports %s", gSessionData->mCores, cpu, result.mAction);
handleException();
}
if (strcmp(result.mAction, "online") == 0) {
- mBuffer.onlineCPU(currTime, currTime - gSessionData->mMonotonicStarted, cpu);
+ mBuffer->onlineCPU(currTime, cpu);
// Only call onlineCPU if prepareCPU succeeded
- bool result = false;
+ bool ret = false;
int err = mCountersGroup.prepareCPU(cpu, &mMonitor);
if (err == PG_CPU_OFFLINE) {
- result = true;
+ ret = true;
} else if (err == PG_SUCCESS) {
- if (mCountersGroup.onlineCPU(currTime, cpu, true, &mBuffer)) {
- err = mIdleGroup.prepareCPU(cpu, &mMonitor);
- if (err == PG_CPU_OFFLINE) {
- result = true;
- } else if (err == PG_SUCCESS) {
- if (mIdleGroup.onlineCPU(currTime, cpu, true, &mBuffer)) {
- result = true;
- }
- }
+ if (mCountersGroup.onlineCPU(currTime, cpu, true, mBuffer) > 0) {
+ mBuffer->perfCounterHeader(currTime);
+ gSessionData->perf.read(mBuffer, cpu);
+ mBuffer->perfCounterFooter(currTime);
+ ret = true;
}
}
- mBuffer.commit(currTime);
+ mBuffer->commit(currTime);
gSessionData->readCpuInfo();
gSessionData->perf.coreName(currTime, &mSummary, cpu);
mSummary.commit(currTime);
- return result;
+ return ret;
} else if (strcmp(result.mAction, "offline") == 0) {
- const bool result = mCountersGroup.offlineCPU(cpu) && mIdleGroup.offlineCPU(cpu);
- mBuffer.offlineCPU(currTime, currTime - gSessionData->mMonotonicStarted, cpu);
- return result;
+ const bool ret = mCountersGroup.offlineCPU(cpu);
+ mBuffer->offlineCPU(currTime, cpu);
+ return ret;
}
}
@@ -424,14 +422,14 @@ void PerfSource::interrupt() {
int8_t c = 0;
// Write to the pipe to wake the monitor which will cause mSessionIsActive to be reread
if (::write(mInterruptFd, &c, sizeof(c)) != sizeof(c)) {
- logg->logError(__FILE__, __LINE__, "write failed");
+ logg->logError("write failed");
handleException();
}
}
}
bool PerfSource::isDone () {
- return mBuffer.isDone() && mIsDone && mCountersBuf.isEmpty();
+ return mBuffer->isDone() && mIsDone && mCountersBuf.isEmpty();
}
void PerfSource::write (Sender *sender) {
@@ -439,11 +437,11 @@ void PerfSource::write (Sender *sender) {
mSummary.write(sender);
gSessionData->mSentSummary = true;
}
- if (!mBuffer.isDone()) {
- mBuffer.write(sender);
+ if (!mBuffer->isDone()) {
+ mBuffer->write(sender);
}
if (!mCountersBuf.send(sender)) {
- logg->logError(__FILE__, __LINE__, "PerfBuffer::send failed");
+ logg->logError("PerfBuffer::send failed");
handleException();
}
}
diff --git a/daemon/PerfSource.h b/daemon/PerfSource.h
index ce1eafe..feec1c2 100644
--- a/daemon/PerfSource.h
+++ b/daemon/PerfSource.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -36,10 +36,9 @@ private:
bool handleUEvent(const uint64_t currTime);
Buffer mSummary;
- Buffer mBuffer;
+ Buffer *mBuffer;
PerfBuffer mCountersBuf;
PerfGroup mCountersGroup;
- PerfGroup mIdleGroup;
Monitor mMonitor;
UEvent mUEvent;
sem_t *const mSenderSem;
diff --git a/daemon/Proc.cpp b/daemon/Proc.cpp
index e6b26b1..4ba59b6 100644
--- a/daemon/Proc.cpp
+++ b/daemon/Proc.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -31,20 +31,20 @@ struct ProcStat {
static bool readProcStat(ProcStat *const ps, const char *const pathname, DynBuf *const b) {
if (!b->read(pathname)) {
- logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the thread exited", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::read failed, likely because the thread exited");
// This is not a fatal error - the thread just doesn't exist any more
return true;
}
char *comm = strchr(b->getBuf(), '(');
if (comm == NULL) {
- logg->logMessage("%s(%s:%i): parsing stat failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("parsing stat failed");
return false;
}
++comm;
char *const str = strrchr(comm, ')');
if (str == NULL) {
- logg->logMessage("%s(%s:%i): parsing stat failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("parsing stat failed");
return false;
}
*str = '\0';
@@ -53,7 +53,7 @@ static bool readProcStat(ProcStat *const ps, const char *const pathname, DynBuf
const int count = sscanf(str + 2, " %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %ld", &ps->numThreads);
if (count != 1) {
- logg->logMessage("%s(%s:%i): sscanf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("sscanf failed");
return false;
}
@@ -65,7 +65,7 @@ static const char APP_PROCESS[] = "app_process";
static const char *readProcExe(DynBuf *const printb, const int pid, const int tid, DynBuf *const b) {
if (tid == -1 ? !printb->printf("/proc/%i/exe", pid)
: !printb->printf("/proc/%i/task/%i/exe", pid, tid)) {
- logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::printf failed");
return NULL;
}
@@ -82,7 +82,7 @@ static const char *readProcExe(DynBuf *const printb, const int pid, const int ti
// readlink /proc/[pid]/exe returns ENOENT for kernel threads
image = "\0";
} else {
- logg->logMessage("%s(%s:%i): DynBuf::readlink failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::readlink failed");
return NULL;
}
@@ -94,12 +94,12 @@ static const char *readProcExe(DynBuf *const printb, const int pid, const int ti
if (tid == -1 ? !printb->printf("/proc/%i/cmdline", pid)
: !printb->printf("/proc/%i/task/%i/cmdline", pid, tid)) {
- logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::printf failed");
return NULL;
}
if (!b->read(printb->getBuf())) {
- logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the thread exited", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::read failed, likely because the thread exited");
return NULL;
}
@@ -110,12 +110,12 @@ static bool readProcTask(const uint64_t currTime, Buffer *const buffer, const in
bool result = false;
if (!b1->printf("/proc/%i/task", pid)) {
- logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::printf failed");
return result;
}
DIR *task = opendir(b1->getBuf());
if (task == NULL) {
- logg->logMessage("%s(%s:%i): opendir failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("opendir failed");
// This is not a fatal error - the thread just doesn't exist any more
return true;
}
@@ -130,22 +130,22 @@ static bool readProcTask(const uint64_t currTime, Buffer *const buffer, const in
}
if (!printb->printf("/proc/%i/task/%i/stat", pid, tid)) {
- logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::printf failed");
goto fail;
}
ProcStat ps;
if (!readProcStat(&ps, printb->getBuf(), b1)) {
- logg->logMessage("%s(%s:%i): readProcStat failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("readProcStat failed");
goto fail;
}
const char *const image = readProcExe(printb, pid, tid, b2);
if (image == NULL) {
- logg->logMessage("%s(%s:%i): readImage failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("readImage failed");
goto fail;
}
- buffer->comm(currTime, pid, tid, image, ps.comm);
+ buffer->marshalComm(currTime, pid, tid, image, ps.comm);
}
result = true;
@@ -161,7 +161,7 @@ bool readProcComms(const uint64_t currTime, Buffer *const buffer, DynBuf *const
DIR *proc = opendir("/proc");
if (proc == NULL) {
- logg->logMessage("%s(%s:%i): opendir failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("opendir failed");
return result;
}
@@ -175,26 +175,26 @@ bool readProcComms(const uint64_t currTime, Buffer *const buffer, DynBuf *const
}
if (!printb->printf("/proc/%i/stat", pid)) {
- logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::printf failed");
goto fail;
}
ProcStat ps;
if (!readProcStat(&ps, printb->getBuf(), b1)) {
- logg->logMessage("%s(%s:%i): readProcStat failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("readProcStat failed");
goto fail;
}
if (ps.numThreads <= 1) {
const char *const image = readProcExe(printb, pid, -1, b1);
if (image == NULL) {
- logg->logMessage("%s(%s:%i): readImage failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("readImage failed");
goto fail;
}
- buffer->comm(currTime, pid, pid, image, ps.comm);
+ buffer->marshalComm(currTime, pid, pid, image, ps.comm);
} else {
if (!readProcTask(currTime, buffer, pid, printb, b1, b2)) {
- logg->logMessage("%s(%s:%i): readProcTask failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("readProcTask failed");
goto fail;
}
}
@@ -213,7 +213,7 @@ bool readProcMaps(const uint64_t currTime, Buffer *const buffer, DynBuf *const p
DIR *proc = opendir("/proc");
if (proc == NULL) {
- logg->logMessage("%s(%s:%i): opendir failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("opendir failed");
return result;
}
@@ -227,16 +227,16 @@ bool readProcMaps(const uint64_t currTime, Buffer *const buffer, DynBuf *const p
}
if (!printb->printf("/proc/%i/maps", pid)) {
- logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::printf failed");
goto fail;
}
if (!b->read(printb->getBuf())) {
- logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the process exited", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("DynBuf::read failed, likely because the process exited");
// This is not a fatal error - the process just doesn't exist any more
continue;
}
- buffer->maps(currTime, pid, pid, b->getBuf());
+ buffer->marshalMaps(currTime, pid, pid, b->getBuf());
}
result = true;
@@ -251,7 +251,7 @@ bool readKallsyms(const uint64_t currTime, Buffer *const buffer, const bool *con
int fd = ::open("/proc/kallsyms", O_RDONLY | O_CLOEXEC);
if (fd < 0) {
- logg->logMessage("%s(%s:%i): open failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("open failed");
return true;
};
@@ -260,7 +260,7 @@ bool readKallsyms(const uint64_t currTime, Buffer *const buffer, const bool *con
while (gSessionData->mSessionIsActive && !ACCESS_ONCE(*isDone)) {
// Assert there is still space in the buffer
if (sizeof(buf) - pos - 1 == 0) {
- logg->logError(__FILE__, __LINE__, "no space left in buffer");
+ logg->logError("no space left in buffer");
handleException();
}
@@ -268,13 +268,13 @@ bool readKallsyms(const uint64_t currTime, Buffer *const buffer, const bool *con
// -1 to reserve space for \0
const ssize_t bytes = ::read(fd, buf + pos, sizeof(buf) - pos - 1);
if (bytes < 0) {
- logg->logError(__FILE__, __LINE__, "read failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logError("read failed");
handleException();
}
if (bytes == 0) {
// Assert the buffer is empty
if (pos != 0) {
- logg->logError(__FILE__, __LINE__, "buffer not empty on eof");
+ logg->logError("buffer not empty on eof");
handleException();
}
break;
@@ -288,13 +288,13 @@ bool readKallsyms(const uint64_t currTime, Buffer *const buffer, const bool *con
if (buf[newline] == '\n') {
const char was = buf[newline + 1];
buf[newline + 1] = '\0';
- buffer->kallsyms(currTime, buf);
+ buffer->marshalKallsyms(currTime, buf);
// Sleep 3 ms to avoid sending out too much data too quickly
usleep(3000);
buf[0] = was;
// Assert the memory regions do not overlap
if (pos - newline >= newline + 1) {
- logg->logError(__FILE__, __LINE__, "memcpy src and dst overlap");
+ logg->logError("memcpy src and dst overlap");
handleException();
}
if (pos - newline - 2 > 0) {
diff --git a/daemon/Proc.h b/daemon/Proc.h
index 2a1a7cb..fcc48c5 100644
--- a/daemon/Proc.h
+++ b/daemon/Proc.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Sender.cpp b/daemon/Sender.cpp
index 8a54a66..d7ad757 100644
--- a/daemon/Sender.cpp
+++ b/daemon/Sender.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -30,7 +30,7 @@ Sender::Sender(OlySocket* socket) {
// Streamline will send data prior to the magic sequence for legacy support, which should be ignored for v4+
while (strcmp("STREAMLINE", streamline) != 0) {
if (mDataSocket->receiveString(streamline, sizeof(streamline)) == -1) {
- logg->logError(__FILE__, __LINE__, "Socket disconnected");
+ logg->logError("Socket disconnected");
handleException();
}
}
@@ -67,7 +67,7 @@ void Sender::createDataFile(char* apcDir) {
sprintf(mDataFileName, "%s/0000000000", apcDir);
mDataFile = fopen_cloexec(mDataFileName, "wb");
if (!mDataFile) {
- logg->logError(__FILE__, __LINE__, "Failed to open binary file: %s", mDataFileName);
+ logg->logError("Failed to open binary file: %s", mDataFileName);
handleException();
}
}
@@ -120,7 +120,7 @@ void Sender::writeData(const char* data, int length, int type) {
logg->logMessage("Writing data with length %d", length);
// Send data to the data file
if (fwrite(data, 1, length, mDataFile) != (unsigned int)length) {
- logg->logError(__FILE__, __LINE__, "Failed writing binary file %s", mDataFileName);
+ logg->logError("Failed writing binary file %s", mDataFileName);
handleException();
}
}
diff --git a/daemon/Sender.h b/daemon/Sender.h
index 5aa9117..8f54202 100644
--- a/daemon/Sender.h
+++ b/daemon/Sender.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/SessionData.cpp b/daemon/SessionData.cpp
index 0e65d78..2b661bd 100644
--- a/daemon/SessionData.cpp
+++ b/daemon/SessionData.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,7 +13,6 @@
#include <sys/mman.h>
#include <unistd.h>
-#include "CPUFreqDriver.h"
#include "DiskIODriver.h"
#include "FSDriver.h"
#include "HwmonDriver.h"
@@ -31,8 +30,7 @@ SessionData::SessionData() {
usDrivers[1] = new FSDriver();
usDrivers[2] = new MemInfoDriver();
usDrivers[3] = new NetDriver();
- usDrivers[4] = new CPUFreqDriver();
- usDrivers[5] = new DiskIODriver();
+ usDrivers[4] = new DiskIODriver();
initialize();
}
@@ -50,7 +48,7 @@ void SessionData::initialize() {
// Share mCpuIds across all instances of gatord
mCpuIds = (int *)mmap(NULL, cpuIdSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (mCpuIds == MAP_FAILED) {
- logg->logError(__FILE__, __LINE__, "Unable to mmap shared memory for cpuids");
+ logg->logError("Unable to mmap shared memory for cpuids");
handleException();
}
memset(mCpuIds, -1, cpuIdSize);
@@ -61,6 +59,7 @@ void SessionData::initialize() {
mConfigurationXMLPath = NULL;
mSessionXMLPath = NULL;
mEventsXMLPath = NULL;
+ mEventsXMLAppend = NULL;
mTargetPath = NULL;
mAPCDir = NULL;
mCaptureWorkingDir = NULL;
@@ -75,6 +74,7 @@ void SessionData::initialize() {
// sysconf(_SC_NPROCESSORS_CONF) is unreliable on 2.6 Android, get the value from the kernel module
mCores = 1;
mPageSize = 0;
+ mAnnotateStart = -1;
}
void SessionData::parseSessionXML(char* xmlString) {
@@ -91,7 +91,7 @@ void SessionData::parseSessionXML(char* xmlString) {
} else if (strcmp(session.parameters.sample_rate, "none") == 0) {
mSampleRate = 0;
} else {
- logg->logError(__FILE__, __LINE__, "Invalid sample rate (%s) in session xml.", session.parameters.sample_rate);
+ logg->logError("Invalid sample rate (%s) in session xml.", session.parameters.sample_rate);
handleException();
}
mBacktraceDepth = session.parameters.call_stack_unwinding == true ? 128 : 0;
@@ -108,7 +108,7 @@ void SessionData::parseSessionXML(char* xmlString) {
} else if (strcmp(session.parameters.buffer_mode, "large") == 0) {
mTotalBufferSize = 16;
} else {
- logg->logError(__FILE__, __LINE__, "Invalid value for buffer mode in session xml.");
+ logg->logError("Invalid value for buffer mode in session xml.");
handleException();
}
@@ -120,7 +120,7 @@ void SessionData::parseSessionXML(char* xmlString) {
}
if (!mAllowCommands && (mCaptureCommand != NULL)) {
- logg->logError(__FILE__, __LINE__, "Running a command during a capture is not currently allowed. Please restart gatord with the -a flag.");
+ logg->logError("Running a command during a capture is not currently allowed. Please restart gatord with the -a flag.");
handleException();
}
}
@@ -139,6 +139,20 @@ void SessionData::readModel() {
fclose(fh);
}
+static void setImplementer(int &cpuId, const int implementer) {
+ if (cpuId == -1) {
+ cpuId = 0;
+ }
+ cpuId |= implementer << 12;
+}
+
+static void setPart(int &cpuId, const int part) {
+ if (cpuId == -1) {
+ cpuId = 0;
+ }
+ cpuId |= part;
+}
+
void SessionData::readCpuInfo() {
char temp[256]; // arbitrarily large amount
mMaxCpuId = -1;
@@ -150,7 +164,7 @@ void SessionData::readCpuInfo() {
return;
}
- bool foundCoreName = false;
+ bool foundCoreName = (strcmp(mCoreName, CORE_NAME_UNKNOWN) != 0);
int processor = -1;
while (fgets(temp, sizeof(temp), f)) {
const size_t len = strlen(temp);
@@ -166,10 +180,11 @@ void SessionData::readCpuInfo() {
temp[len - 1] = '\0';
}
- const bool foundHardware = strstr(temp, "Hardware") != 0;
+ const bool foundHardware = !foundCoreName && strstr(temp, "Hardware") != 0;
+ const bool foundCPUImplementer = strstr(temp, "CPU implementer") != 0;
const bool foundCPUPart = strstr(temp, "CPU part") != 0;
const bool foundProcessor = strstr(temp, "processor") != 0;
- if (foundHardware || foundCPUPart || foundProcessor) {
+ if (foundHardware || foundCPUImplementer || foundCPUPart || foundProcessor) {
char* position = strchr(temp, ':');
if (position == NULL || (unsigned int)(position - temp) + 2 >= strlen(temp)) {
logg->logMessage("Unknown format of /proc/cpuinfo\n"
@@ -178,22 +193,31 @@ void SessionData::readCpuInfo() {
}
position += 2;
- if (foundHardware && (strcmp(mCoreName, CORE_NAME_UNKNOWN) == 0)) {
+ if (foundHardware) {
strncpy(mCoreName, position, sizeof(mCoreName));
mCoreName[sizeof(mCoreName) - 1] = 0; // strncpy does not guarantee a null-terminated string
foundCoreName = true;
}
+ if (foundCPUImplementer) {
+ const int implementer = strtol(position, NULL, 0);
+ if (processor >= NR_CPUS) {
+ logg->logMessage("Too many processors, please increase NR_CPUS");
+ } else if (processor >= 0) {
+ setImplementer(mCpuIds[processor], implementer);
+ } else {
+ setImplementer(mMaxCpuId, implementer);
+ }
+ }
+
if (foundCPUPart) {
const int cpuId = strtol(position, NULL, 0);
- // If this does not have the full topology in /proc/cpuinfo, mCpuIds[0] may not have the 1 CPU part emitted - this guarantees it's in mMaxCpuId
- if (cpuId > mMaxCpuId) {
- mMaxCpuId = cpuId;
- }
if (processor >= NR_CPUS) {
logg->logMessage("Too many processors, please increase NR_CPUS");
} else if (processor >= 0) {
- mCpuIds[processor] = cpuId;
+ setPart(mCpuIds[processor], cpuId);
+ } else {
+ setPart(mMaxCpuId, cpuId);
}
}
@@ -203,6 +227,13 @@ void SessionData::readCpuInfo() {
}
}
+ // If this does not have the full topology in /proc/cpuinfo, mCpuIds[0] may not have the 1 CPU part emitted - this guarantees it's in mMaxCpuId
+ for (int i = 0; i < NR_CPUS; ++i) {
+ if (mCpuIds[i] > mMaxCpuId) {
+ mMaxCpuId = mCpuIds[i];
+ }
+ }
+
if (!foundCoreName) {
logg->logMessage("Could not determine core name from /proc/cpuinfo\n"
"The core name in the captured xml file will be 'unknown'.");
@@ -213,7 +244,7 @@ void SessionData::readCpuInfo() {
uint64_t getTime() {
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) {
- logg->logError(__FILE__, __LINE__, "Failed to get uptime");
+ logg->logError("Failed to get uptime");
handleException();
}
return (NS_PER_S*ts.tv_sec + ts.tv_nsec);
diff --git a/daemon/SessionData.h b/daemon/SessionData.h
index ed282af..d0c8900 100644
--- a/daemon/SessionData.h
+++ b/daemon/SessionData.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -11,7 +11,6 @@
#include <stdint.h>
-#include "AnnotateListener.h"
#include "Config.h"
#include "Counter.h"
#include "FtraceDriver.h"
@@ -19,7 +18,7 @@
#include "MaliVideoDriver.h"
#include "PerfDriver.h"
-#define PROTOCOL_VERSION 20
+#define PROTOCOL_VERSION 21
// Differentiates development versions (timestamp) from release versions
#define PROTOCOL_DEV 1000
@@ -43,18 +42,18 @@ public:
void readModel();
void readCpuInfo();
- PolledDriver *usDrivers[6];
+ PolledDriver *usDrivers[5];
KMod kmod;
PerfDriver perf;
MaliVideoDriver maliVideo;
FtraceDriver ftraceDriver;
- AnnotateListener annotateListener;
char mCoreName[MAX_STRING_LEN];
struct ImageLinkList *mImages;
char *mConfigurationXMLPath;
char *mSessionXMLPath;
char *mEventsXMLPath;
+ char *mEventsXMLAppend;
char *mTargetPath;
char *mAPCDir;
char *mCaptureWorkingDir;
@@ -81,6 +80,7 @@ public:
int mPageSize;
int *mCpuIds;
int mMaxCpuId;
+ int mAnnotateStart;
// PMU Counters
int mCounterOverflow;
@@ -93,6 +93,7 @@ private:
};
extern SessionData* gSessionData;
+extern const char *const gSrcMd5;
uint64_t getTime();
int getEventKey();
diff --git a/daemon/SessionXML.cpp b/daemon/SessionXML.cpp
index dea4c8f..c638dea 100644
--- a/daemon/SessionXML.cpp
+++ b/daemon/SessionXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -36,7 +36,7 @@ SessionXML::SessionXML(const char *str) {
parameters.call_stack_unwinding = false;
parameters.live_rate = 0;
mSessionXML = str;
- logg->logMessage(mSessionXML);
+ logg->logMessage("%s", mSessionXML);
}
SessionXML::~SessionXML() {
@@ -55,7 +55,7 @@ void SessionXML::parse() {
return;
}
- logg->logError(__FILE__, __LINE__, "No session tag found in the session.xml file");
+ logg->logError("No session tag found in the session.xml file");
handleException();
}
@@ -63,7 +63,7 @@ void SessionXML::sessionTag(mxml_node_t *tree, mxml_node_t *node) {
int version = 0;
if (mxmlElementGetAttr(node, ATTR_VERSION)) version = strtol(mxmlElementGetAttr(node, ATTR_VERSION), NULL, 10);
if (version != 1) {
- logg->logError(__FILE__, __LINE__, "Invalid session.xml version: %d", version);
+ logg->logError("Invalid session.xml version: %d", version);
handleException();
}
diff --git a/daemon/SessionXML.h b/daemon/SessionXML.h
index 5396574..2ba276a 100644
--- a/daemon/SessionXML.h
+++ b/daemon/SessionXML.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/Setup.cpp b/daemon/Setup.cpp
index d4ce032..7dd83ce 100644
--- a/daemon/Setup.cpp
+++ b/daemon/Setup.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,7 +15,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mount.h>
#include <sys/stat.h>
+#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/wait.h>
@@ -24,12 +26,17 @@
#include "Config.h"
#include "DynBuf.h"
#include "Logging.h"
+#include "SessionData.h"
+
+#define GATOR_MSG "gator: "
+#define GATOR_ERROR "gator: error: "
+#define GATOR_CONFIRM "gator: confirm: "
bool getLinuxVersion(int version[3]) {
// Check the kernel version
struct utsname utsname;
if (uname(&utsname) != 0) {
- logg->logMessage("%s(%s:%i): uname failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("uname failed");
return false;
}
@@ -57,7 +64,7 @@ static int pgrep_gator(DynBuf *const printb) {
DIR *proc = opendir("/proc");
if (proc == NULL) {
- logg->logError(__FILE__, __LINE__, "gator: error: opendir failed");
+ logg->logError(GATOR_ERROR "opendir failed");
handleException();
}
@@ -73,7 +80,7 @@ static int pgrep_gator(DynBuf *const printb) {
}
if (!printb->printf("/proc/%i/stat", pid)) {
- logg->logError(__FILE__, __LINE__, "gator: error: DynBuf::printf failed");
+ logg->logError(GATOR_ERROR "DynBuf::printf failed");
handleException();
}
@@ -84,21 +91,35 @@ static int pgrep_gator(DynBuf *const printb) {
char *comm = strchr(b.getBuf(), '(');
if (comm == NULL) {
- logg->logError(__FILE__, __LINE__, "gator: error: parsing stat begin failed");
+ logg->logError(GATOR_ERROR "parsing stat comm begin failed");
handleException();
}
++comm;
char *const str = strrchr(comm, ')');
if (str == NULL) {
- logg->logError(__FILE__, __LINE__, "gator: error: parsing stat end failed");
+ logg->logError(GATOR_ERROR "parsing stat comm end failed");
handleException();
}
*str = '\0';
- if (strncmp(comm, "gator", 5) == 0) {
- // Assume there is only one gator process
- return pid;
+ if (strncmp(comm, "gator", 5) != 0) {
+ continue;
+ }
+
+ char state;
+ const int count = sscanf(str + 2, " %c ", &state);
+ if (count != 1) {
+ logg->logError(GATOR_ERROR "parsing stat state failed");
+ handleException();
+ }
+
+ if (state == 'Z') {
+ // This gator is a zombie, ignore
+ continue;
}
+
+ // Assume there is only one gator process
+ return pid;
}
closedir(proc);
@@ -106,73 +127,106 @@ static int pgrep_gator(DynBuf *const printb) {
return -1;
}
-int update(const char *const gatorPath) {
- printf("gator: starting\n");
+static bool confirm(const char *const message) {
+ char buf[1<<10];
+
+ printf(GATOR_CONFIRM "%s\n", message);
+ while (fgets(buf, sizeof(buf), stdin) != NULL) {
+ if (strcmp(buf, "y\n") == 0) {
+ return true;
+ }
+ if (strcmp(buf, "n\n") == 0) {
+ return false;
+ }
+ // Ignore unrecognized input
+ }
+
+ return false;
+}
+
+void update(const char *const gatorPath) {
+ printf(GATOR_MSG "starting\n");
int version[3];
if (!getLinuxVersion(version)) {
- logg->logError(__FILE__, __LINE__, "gator: error: getLinuxVersion failed");
+ logg->logError(GATOR_ERROR "getLinuxVersion failed");
handleException();
}
if (KERNEL_VERSION(version[0], version[1], version[2]) < KERNEL_VERSION(2, 6, 32)) {
- logg->logError(__FILE__, __LINE__, "gator: error: Streamline can't automatically setup gator as this kernel version is not supported. Please upgrade the kernel on your device.");
+ logg->logError(GATOR_ERROR "Streamline can't automatically setup gator as this kernel version is not supported. Please upgrade the kernel on your device.");
handleException();
}
if (KERNEL_VERSION(version[0], version[1], version[2]) < KERNEL_VERSION(3, 4, 0)) {
- logg->logError(__FILE__, __LINE__, "gator: error: Streamline can't automatically setup gator as gator.ko is required for this version of Linux. Please build gator.ko and gatord and install them on your device.");
- handleException();
- }
-
- if (access("/sys/module/gator", F_OK) == 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: Streamline has detected that the gator kernel module is loaded on your device. Please build an updated version of gator.ko and gatord and install them on your device.");
+ logg->logError(GATOR_ERROR "Streamline can't automatically setup gator as gator.ko is required for this version of Linux. Please build gator.ko and gatord and install them on your device.");
handleException();
}
if (geteuid() != 0) {
- printf("gator: trying sudo\n");
+ printf(GATOR_MSG "trying sudo\n");
execlp("sudo", "sudo", gatorPath, "-u", NULL);
// Streamline will provide the password if needed
- printf("gator: trying su\n");
+ printf(GATOR_MSG "trying su\n");
char buf[1<<10];
- snprintf(buf, sizeof(buf), "%s -u", gatorPath);
- execlp("su", "su", "-", "-c", buf, NULL);
+ /*
+ * Different versions of su handle additional -c command line options differently and expect the
+ * arguments in different ways. Try both ways wrapped in a shell.
+ *
+ * Then invoke another shell after su as it avoids odd failures on some Android systems
+ */
+ snprintf(buf, sizeof(buf), "su -c \"sh -c '%s -u'\" || su -c sh -c '%s -u'", gatorPath, gatorPath);
+ execlp("sh", "sh", "-c", buf, NULL);
// Streamline will provide the password if needed
- logg->logError(__FILE__, __LINE__, "gator: error: Streamline was unable to sudo to root on your device. Please double check passwords, ensure sudo or su work with this user or try a different username.");
+ logg->logError(GATOR_ERROR "Streamline was unable to sudo to root on your device. Please double check passwords, ensure sudo or su work with this user or try a different username.");
handleException();
}
- printf("gator: now root\n");
+ printf(GATOR_MSG "now root\n");
+
+ if (access("/sys/module/gator", F_OK) == 0) {
+ if (!confirm("Streamline has detected that the gator kernel module is loaded on your device. Click yes to switch to user space gator, click no to abort the install.")) {
+ printf("gator: cancel\n");
+ exit(-1);
+ }
+ }
// setenforce 0 not needed for userspace gator
// Kill existing gator
- DynBuf gatorStatPath;
- int gator_main = pgrep_gator(&gatorStatPath);
+ DynBuf printb;
+ int gator_main = pgrep_gator(&printb);
if (gator_main > 0) {
if (kill(gator_main, SIGTERM) != 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: kill SIGTERM failed");
+ logg->logError(GATOR_ERROR "kill SIGTERM failed");
+ handleException();
+ }
+ if (!printb.printf("/proc/%i/exe", gator_main)) {
+ logg->logError(GATOR_ERROR "DynBuf::printf failed");
handleException();
}
for (int i = 0; ; ++i) {
- if (access(gatorStatPath.getBuf(), F_OK) != 0) {
+ // /proc/<pid>/exe exists but will not be accessible for zombies
+ if (access(printb.getBuf(), F_OK) != 0) {
break;
}
if (i == 5) {
if (kill(gator_main, SIGKILL) != 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: kill SIGKILL failed");
+ logg->logError(GATOR_ERROR "kill SIGKILL failed");
handleException();
}
} else if (i >= 10) {
- logg->logError(__FILE__, __LINE__, "gator: error: unable to kill running gator");
+ logg->logError(GATOR_ERROR "unable to kill running gator");
handleException();
}
sleep(1);
}
}
- printf("gator: no gatord running\n");
+ printf(GATOR_MSG "no gatord running\n");
+
+ umount("/dev/gator");
+ syscall(__NR_delete_module, "gator", O_NONBLOCK);
rename("gatord", "gatord.old");
rename("gator.ko", "gator.ko.old");
@@ -183,50 +237,88 @@ int update(const char *const gatorPath) {
if (dot != NULL) {
*dot = '\0';
if (rename(gatorPath, newGatorPath) != 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: rename failed");
+ logg->logError(GATOR_ERROR "rename failed");
handleException();
}
}
- // Fork and start gatord (redirect stdout and stderr)
+ char buf[128];
+ int pipefd[2];
+ if (pipe_cloexec(pipefd) != 0) {
+ logg->logError(GATOR_ERROR "pipe failed");
+ handleException();
+ }
+
+ // Fork and start gatord (redirect stdin, stdout and stderr so shell can close)
int child = fork();
if (child < 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: fork failed");
+ logg->logError(GATOR_ERROR "fork failed");
handleException();
} else if (child == 0) {
- int inFd = open("/dev/null", O_RDONLY | O_CLOEXEC);
+ int inFd;
+ int outFd;
+ int errFd;
+ int result = -1;
+
+ buf[0] = '\0';
+ close(pipefd[0]);
+
+ inFd = open("/dev/null", O_RDONLY | O_CLOEXEC);
if (inFd < 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: open of /dev/null failed");
- handleException();
+ snprintf(buf, sizeof(buf), GATOR_ERROR "open of /dev/null failed");
+ goto fail_exit;
}
- int outFd = open("gatord.out", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0600);
+ outFd = open("gatord.out", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
if (outFd < 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: open of gatord.out failed");
- handleException();
+ snprintf(buf, sizeof(buf), GATOR_ERROR "open of gatord.out failed");
+ goto fail_exit;
}
- int errFd = open("gatord.err", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0600);
+ errFd = open("gatord.err", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
if (errFd < 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: open of gatord.err failed");
- handleException();
+ snprintf(buf, sizeof(buf), GATOR_ERROR "open of gatord.err failed");
+ goto fail_exit;
}
if (dup2(inFd, STDIN_FILENO) < 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: dup2 for stdin failed");
- handleException();
+ snprintf(buf, sizeof(buf), GATOR_ERROR "dup2 for stdin failed");
+ goto fail_exit;
}
+ fflush(stdout);
if (dup2(outFd, STDOUT_FILENO) < 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: dup2 for stdout failed");
- handleException();
+ snprintf(buf, sizeof(buf), GATOR_ERROR "dup2 for stdout failed");
+ goto fail_exit;
}
+ fflush(stderr);
if (dup2(errFd, STDERR_FILENO) < 0) {
- logg->logError(__FILE__, __LINE__, "gator: error: dup2 for stderr failed");
- handleException();
+ snprintf(buf, sizeof(buf), GATOR_ERROR "dup2 for stderr failed");
+ goto fail_exit;
}
- execlp(newGatorPath, newGatorPath, "-a", NULL);
- logg->logError(__FILE__, __LINE__, "gator: error: execlp failed");
- handleException();
+
+ snprintf(buf, sizeof(buf), GATOR_MSG "done");
+ result = 0;
+
+ fail_exit:
+ if (buf[0] != '\0') {
+ const ssize_t bytes = write(pipefd[1], buf, sizeof(buf));
+ // Can't do anything if this fails
+ (void)bytes;
+ }
+ close(pipefd[1]);
+
+ if (result == 0) {
+ // Continue to execute gator normally
+ return;
+ }
+ exit(-1);
}
- printf("gator: done\n");
+ close(pipefd[1]);
+ const ssize_t bytes = read(pipefd[0], buf, sizeof(buf));
+ if (bytes > 0) {
+ logg->logError("%s", buf);
+ handleException();
+ }
+ close(pipefd[0]);
- return 0;
+ // Exit so parent shell can move on
+ exit(0);
}
diff --git a/daemon/Setup.h b/daemon/Setup.h
index 280d611..427e717 100644
--- a/daemon/Setup.h
+++ b/daemon/Setup.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,6 +13,6 @@
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
bool getLinuxVersion(int version[3]);
-int update(const char *const gatorPath);
+void update(const char *const gatorPath);
#endif // SETUP_H
diff --git a/daemon/Source.cpp b/daemon/Source.cpp
index 60cf704..64d6206 100644
--- a/daemon/Source.cpp
+++ b/daemon/Source.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -18,7 +18,7 @@ Source::~Source() {
void Source::start() {
if (pthread_create(&mThreadID, NULL, runStatic, this)) {
- logg->logError(__FILE__, __LINE__, "Failed to create source thread");
+ logg->logError("Failed to create source thread");
handleException();
}
}
diff --git a/daemon/Source.h b/daemon/Source.h
index 56ac3d6..b9369be 100644
--- a/daemon/Source.h
+++ b/daemon/Source.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/StreamlineSetup.cpp b/daemon/StreamlineSetup.cpp
index 2b61eae..e37f271 100644
--- a/daemon/StreamlineSetup.cpp
+++ b/daemon/StreamlineSetup.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2011-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -68,7 +68,7 @@ StreamlineSetup::StreamlineSetup(OlySocket* s) {
sendData(NULL, 0, RESPONSE_ACK);
break;
default:
- logg->logError(__FILE__, __LINE__, "Target error: Unknown command type, %d", type);
+ logg->logError("Target error: Unknown command type, %d", type);
handleException();
}
@@ -76,7 +76,7 @@ StreamlineSetup::StreamlineSetup(OlySocket* s) {
}
if (gSessionData->mCounterOverflow > 0) {
- logg->logError(__FILE__, __LINE__, "Only %i performance counters are permitted, %i are selected", MAX_PERFORMANCE_COUNTERS, gSessionData->mCounterOverflow);
+ logg->logError("Only %i performance counters are permitted, %i are selected", MAX_PERFORMANCE_COUNTERS, gSessionData->mCounterOverflow);
handleException();
}
}
@@ -96,7 +96,7 @@ char* StreamlineSetup::readCommand(int* command) {
gSessionData->mWaitingOnCommand = false;
if (response < 0) {
- logg->logError(__FILE__, __LINE__, "Target error: Unexpected socket disconnect");
+ logg->logError("Target error: Unexpected socket disconnect");
handleException();
}
@@ -105,21 +105,21 @@ char* StreamlineSetup::readCommand(int* command) {
// add artificial limit
if ((length < 0) || length > 1024 * 1024) {
- logg->logError(__FILE__, __LINE__, "Target error: Invalid length received, %d", length);
+ logg->logError("Target error: Invalid length received, %d", length);
handleException();
}
// allocate memory to contain the xml file, size of zero returns a zero size object
data = (char*)calloc(length + 1, 1);
if (data == NULL) {
- logg->logError(__FILE__, __LINE__, "Unable to allocate memory for xml");
+ logg->logError("Unable to allocate memory for xml");
handleException();
}
// receive data
response = mSocket->receiveNBytes(data, length);
if (response < 0) {
- logg->logError(__FILE__, __LINE__, "Target error: Unexpected socket disconnect");
+ logg->logError("Target error: Unexpected socket disconnect");
handleException();
}
@@ -222,7 +222,7 @@ void StreamlineSetup::sendDefaults() {
// Artificial size restriction
if (size > 1024*1024) {
- logg->logError(__FILE__, __LINE__, "Corrupt default configuration file");
+ logg->logError("Corrupt default configuration file");
handleException();
}
@@ -241,7 +241,7 @@ void StreamlineSetup::sendCounters() {
}
if (count == 0) {
- logg->logError(__FILE__, __LINE__, "No counters found, this could be because /dev/gator/events can not be read or because perf is not working correctly");
+ logg->logError("No counters found, this could be because /dev/gator/events can not be read or because perf is not working correctly");
handleException();
}
@@ -258,7 +258,7 @@ void StreamlineSetup::writeConfiguration(char* xml) {
ConfigurationXML::getPath(path);
if (util->writeToDisk(path, xml) < 0) {
- logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify write permissions to this path.", path);
+ logg->logError("Error writing %s\nPlease verify write permissions to this path.", path);
handleException();
}
@@ -266,7 +266,7 @@ void StreamlineSetup::writeConfiguration(char* xml) {
{ ConfigurationXML configuration; }
if (gSessionData->mCounterOverflow > 0) {
- logg->logError(__FILE__, __LINE__, "Only %i performance counters are permitted, %i are selected", MAX_PERFORMANCE_COUNTERS, gSessionData->mCounterOverflow);
+ logg->logError("Only %i performance counters are permitted, %i are selected", MAX_PERFORMANCE_COUNTERS, gSessionData->mCounterOverflow);
handleException();
}
}
diff --git a/daemon/StreamlineSetup.h b/daemon/StreamlineSetup.h
index 623e14f..d8b1626 100644
--- a/daemon/StreamlineSetup.h
+++ b/daemon/StreamlineSetup.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/UEvent.cpp b/daemon/UEvent.cpp
index f94a995..6a69f5a 100644
--- a/daemon/UEvent.cpp
+++ b/daemon/UEvent.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,7 +34,7 @@ UEvent::~UEvent() {
bool UEvent::init() {
mFd = socket_cloexec(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if (mFd < 0) {
- logg->logMessage("%s(%s:%i): socket failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("socket failed");
return false;
}
@@ -44,7 +44,7 @@ bool UEvent::init() {
sockaddr.nl_groups = 1; // bitmask: (1 << 0) == kernel events, (1 << 1) == udev events
sockaddr.nl_pid = 0;
if (bind(mFd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != 0) {
- logg->logMessage("%s(%s:%i): bind failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("bind failed");
return false;
}
@@ -54,7 +54,7 @@ bool UEvent::init() {
bool UEvent::read(UEventResult *const result) {
ssize_t bytes = recv(mFd, result->mBuf, sizeof(result->mBuf), 0);
if (bytes <= 0) {
- logg->logMessage("%s(%s:%i): recv failed", __FUNCTION__, __FILE__, __LINE__);
+ logg->logMessage("recv failed");
return false;
}
@@ -64,6 +64,7 @@ bool UEvent::read(UEventResult *const result) {
for (int pos = 0; pos < bytes; pos += strlen(result->mBuf + pos) + 1) {
char *const str = result->mBuf + pos;
+ logg->logMessage("uevent + %i: %s", pos, str);
if (strncmp(str, ACTION, sizeof(ACTION) - 1) == 0) {
result->mAction = str + sizeof(ACTION) - 1;
} else if (strncmp(str, DEVPATH, sizeof(DEVPATH) - 1) == 0) {
diff --git a/daemon/UEvent.h b/daemon/UEvent.h
index 2f7ef2c..4c00f6c 100644
--- a/daemon/UEvent.h
+++ b/daemon/UEvent.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/UserSpaceSource.cpp b/daemon/UserSpaceSource.cpp
index 4a9b22f..f58f828 100644
--- a/daemon/UserSpaceSource.cpp
+++ b/daemon/UserSpaceSource.cpp
@@ -1,13 +1,16 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#define __STDC_FORMAT_MACROS
+
#include "UserSpaceSource.h"
+#include <inttypes.h>
#include <sys/prctl.h>
#include <unistd.h>
@@ -35,45 +38,45 @@ void UserSpaceSource::run() {
gSessionData->usDrivers[i]->start();
}
- int64_t monotonic_started = 0;
- while (monotonic_started <= 0) {
+ int64_t monotonicStarted = 0;
+ while (monotonicStarted <= 0 && gSessionData->mSessionIsActive) {
usleep(10);
if (gSessionData->perf.isSetup()) {
- monotonic_started = gSessionData->mMonotonicStarted;
+ monotonicStarted = gSessionData->mMonotonicStarted;
} else {
- if (DriverSource::readInt64Driver("/dev/gator/started", &monotonic_started) == -1) {
- logg->logError(__FILE__, __LINE__, "Error reading gator driver start time");
+ if (DriverSource::readInt64Driver("/dev/gator/started", &monotonicStarted) == -1) {
+ logg->logError("Error reading gator driver start time");
handleException();
}
- gSessionData->mMonotonicStarted = monotonic_started;
+ gSessionData->mMonotonicStarted = monotonicStarted;
}
}
- uint64_t next_time = 0;
+ uint64_t nextTime = 0;
while (gSessionData->mSessionIsActive) {
- const uint64_t curr_time = getTime() - monotonic_started;
+ const uint64_t currTime = getTime() - monotonicStarted;
// Sample ten times a second ignoring gSessionData->mSampleRate
- next_time += NS_PER_S/10;//gSessionData->mSampleRate;
- if (next_time < curr_time) {
- logg->logMessage("Too slow, curr_time: %lli next_time: %lli", curr_time, next_time);
- next_time = curr_time;
+ nextTime += NS_PER_S/10;//gSessionData->mSampleRate;
+ if (nextTime < currTime) {
+ logg->logMessage("Too slow, currTime: %" PRIi64 " nextTime: %" PRIi64, currTime, nextTime);
+ nextTime = currTime;
}
- if (mBuffer.eventHeader(curr_time)) {
+ if (mBuffer.eventHeader(currTime)) {
for (int i = 0; i < ARRAY_LENGTH(gSessionData->usDrivers); ++i) {
gSessionData->usDrivers[i]->read(&mBuffer);
}
// Only check after writing all counters so that time and corresponding counters appear in the same frame
- mBuffer.check(curr_time);
+ mBuffer.check(currTime);
}
- if (mBuffer.bytesAvailable() <= 0) {
+ if (gSessionData->mOneShot && gSessionData->mSessionIsActive && (mBuffer.bytesAvailable() <= 0)) {
logg->logMessage("One shot (counters)");
child->endSession();
}
- usleep((next_time - curr_time)/NS_PER_US);
+ usleep((nextTime - currTime)/NS_PER_US);
}
mBuffer.setDone();
diff --git a/daemon/UserSpaceSource.h b/daemon/UserSpaceSource.h
index 9b36660..0038dcb 100644
--- a/daemon/UserSpaceSource.h
+++ b/daemon/UserSpaceSource.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/c++.cpp b/daemon/c++.cpp
index 6041e5e..caf6f1e 100644
--- a/daemon/c++.cpp
+++ b/daemon/c++.cpp
@@ -1,7 +1,7 @@
/**
* Minimal set of C++ functions so that libstdc++ is not required
*
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/common.mk b/daemon/common.mk
index 769a92e..0d5a0a8 100644
--- a/daemon/common.mk
+++ b/daemon/common.mk
@@ -6,7 +6,7 @@
# -std=c++0x is the planned new c++ standard
# -std=c++98 is the 1998 c++ standard
CPPFLAGS += -O3 -Wall -fno-exceptions -pthread -MMD -DETCDIR=\"/etc\" -Ilibsensors
-CXXFLAGS += -fno-rtti -Wextra # -Weffc++
+CXXFLAGS += -fno-rtti -Wextra -Wshadow # -Weffc++
ifeq ($(WERROR),1)
CPPFLAGS += -Werror
endif
@@ -41,7 +41,10 @@ libsensors/conf-parse.c: ;
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
-$(TARGET): $(CXX_SRC:%.cpp=%.o) $(C_SRC:%.c=%.o)
+SrcMd5.cpp: $(wildcard *.cpp *.h mxml/*.c mxml/*.h libsensors/*.c libsensors/*.h)
+ echo 'extern const char *const gSrcMd5 = "'`ls $^ | grep -Ev '^(.*_xml\.h|$@)$$' | LC_ALL=C sort | xargs cat | md5sum | cut -b 1-32`'";' > $@
+
+$(TARGET): $(CXX_SRC:%.cpp=%.o) $(C_SRC:%.c=%.o) SrcMd5.o
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
# Intentionally ignore CC as a native binary is required
@@ -49,4 +52,4 @@ escape: escape.c
gcc $^ -o $@
clean:
- rm -f *.d *.o mxml/*.d mxml/*.o libsensors/*.d libsensors/*.o $(TARGET) escape events.xml events_xml.h defaults_xml.h
+ rm -f *.d *.o mxml/*.d mxml/*.o libsensors/*.d libsensors/*.o $(TARGET) escape events.xml events_xml.h defaults_xml.h SrcMd5.cpp
diff --git a/daemon/defaults.xml b/daemon/defaults.xml
index bdd907e..31b127c 100644
--- a/daemon/defaults.xml
+++ b/daemon/defaults.xml
@@ -69,21 +69,5 @@
<configuration counter="ARM_Mali-Midgard_fragment" cores="1"/>
<configuration counter="ARM_Mali-Midgard_vertex" cores="1"/>
<configuration counter="ARM_Mali-Midgard_opencl" cores="1"/>
- <configuration counter="ARM_Mali-T60x_GPU_ACTIVE"/>
- <configuration counter="ARM_Mali-T60x_JS0_ACTIVE"/>
- <configuration counter="ARM_Mali-T60x_JS1_ACTIVE"/>
- <configuration counter="ARM_Mali-T60x_JS2_ACTIVE"/>
- <configuration counter="ARM_Mali-T62x_GPU_ACTIVE"/>
- <configuration counter="ARM_Mali-T62x_JS0_ACTIVE"/>
- <configuration counter="ARM_Mali-T62x_JS1_ACTIVE"/>
- <configuration counter="ARM_Mali-T62x_JS2_ACTIVE"/>
- <configuration counter="ARM_Mali-T72x_GPU_ACTIVE"/>
- <configuration counter="ARM_Mali-T72x_JS0_ACTIVE"/>
- <configuration counter="ARM_Mali-T72x_JS1_ACTIVE"/>
- <configuration counter="ARM_Mali-T72x_JS2_ACTIVE"/>
- <configuration counter="ARM_Mali-T76x_GPU_ACTIVE"/>
- <configuration counter="ARM_Mali-T76x_JS0_ACTIVE"/>
- <configuration counter="ARM_Mali-T76x_JS1_ACTIVE"/>
- <configuration counter="ARM_Mali-T76x_JS2_ACTIVE"/>
<configuration counter="L2C-310_cnt0" event="0x1"/>
</configurations>
diff --git a/daemon/escape.c b/daemon/escape.c
index 2b0863a..99f4348 100644
--- a/daemon/escape.c
+++ b/daemon/escape.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/daemon/events-ARM11.xml b/daemon/events-ARM11.xml
index 57e3235..e481267 100644
--- a/daemon/events-ARM11.xml
+++ b/daemon/events-ARM11.xml
@@ -16,7 +16,7 @@
<event event="0x0d" title="Program Counter" name="SW change" description="Software changed the PC"/>
<event event="0x0f" title="Cache " name="TLB miss" description="Main TLB miss (unused on ARM1156)"/>
<event event="0x10" title="External" name="Access" description="Explicit external data or peripheral access"/>
- <event event="0x11" title="Cache" name="Data miss" description="Stall because of Load Store Unit request queue being full"/>
+ <event event="0x11" title="Cache" name="Stall" description="Stall because of Load Store Unit request queue being full"/>
<event event="0x12" title="Write Buffer" name="Drains" description="The number of times the Write Buffer was drained because of a Data Synchronization Barrier command or Strongly Ordered operation"/>
<event event="0x13" title="Disable Interrupts" name="FIQ" description="The number of cycles which FIQ interrupts are disabled (ARM1156 only)"/>
<event event="0x14" title="Disable Interrupts" name="IRQ" description="The number of cycles which IRQ interrupts are disabled (ARM1156 only)"/>
diff --git a/daemon/events-CCI-400.xml b/daemon/events-CCI-400.xml
index 20002ef..40d91e5 100644
--- a/daemon/events-CCI-400.xml
+++ b/daemon/events-CCI-400.xml
@@ -1,5 +1,5 @@
<counter_set name="CCI_400_cnt" count="4"/>
- <category name="CCI-400" counter_set="CCI_400_cnt" per_cpu="no" supports_event_based_sampling="yes">
+ <category name="CCI-400" counter_set="CCI_400_cnt" per_cpu="no">
<event counter="CCI_400_ccnt" event="0xff" title="CCI-400 Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<option_set name="Slave">
<option event_delta="0x00" name="S0" description="Slave interface 0"/>
@@ -42,7 +42,7 @@
<event event="0x1a" option_set="Master" title="CCI-400" name="Write stall: tracker full" description="Write request stall cycle because the transaction tracker is full. Increase MIx_W_MAX to avoid this stall. See the CoreLink CCI-400 Cache Coherent Interconnect Integration Manual"/>
</category>
<counter_set name="CCI_400-r1_cnt" count="4"/>
- <category name="CCI-400" counter_set="CCI_400-r1_cnt" per_cpu="no" supports_event_based_sampling="yes">
+ <category name="CCI-400" counter_set="CCI_400-r1_cnt" per_cpu="no">
<event counter="CCI_400-r1_ccnt" event="0xff" title="CCI-400 Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<option_set name="Slave">
<option event_delta="0x00" name="S0" description="Slave interface 0"/>
diff --git a/daemon/events-CCI-500.xml b/daemon/events-CCI-500.xml
new file mode 100644
index 0000000..e7cadc4
--- /dev/null
+++ b/daemon/events-CCI-500.xml
@@ -0,0 +1,75 @@
+ <counter_set name="CCI_500_cnt" count="8"/>
+ <category name="CCI-500" counter_set="CCI_500_cnt" per_cpu="no">
+ <option_set name="Slave">
+ <option event_delta="0x00" name="S0" description="Slave interface 0"/>
+ <option event_delta="0x20" name="S1" description="Slave interface 1"/>
+ <option event_delta="0x40" name="S2" description="Slave interface 2"/>
+ <option event_delta="0x60" name="S3" description="Slave interface 3"/>
+ <option event_delta="0x80" name="S4" description="Slave interface 4"/>
+ <option event_delta="0xa0" name="S5" description="Slave interface 5"/>
+ <option event_delta="0xc0" name="S6" description="Slave interface 6"/>
+ </option_set>
+ <event event="0x00" option_set="Slave" title="CCI-500" name="Read ARVALID" description="Read request handshake: any ARVALID, ARREADY HIGH"/>
+ <event event="0x01" option_set="Slave" title="CCI-500" name="Read device" description="Read request: device"/>
+ <event event="0x02" option_set="Slave" title="CCI-500" name="Read non-shareable" description="Read request handshake: normal, non-shareable"/>
+ <event event="0x03" option_set="Slave" title="CCI-500" name="Read non-allocating" description="Read request handshake: normal, shareable, non-allocating, for example ReadOnce"/>
+ <event event="0x04" option_set="Slave" title="CCI-500" name="Read other" description="Read request handshake: normal, shareable allocating, for example ReadClean, ReadShared, ReadNotSharedDirty, ReadUnique"/>
+ <event event="0x05" option_set="Slave" title="CCI-500" name="Read invalidation" description="Read request handshake: invalidation, for example MakeUnique, CleanUnique"/>
+ <event event="0x06" option_set="Slave" title="CCI-500" name="Read maintenance" description="Read request handshake: cache maintenance operation, for example CleanInvalid, MakeInvalid, CleanShared"/>
+ <event event="0x07" option_set="Slave" title="CCI-500" name="Read DVM" description="Read request handshake: DVM message, any"/>
+ <event event="0x08" option_set="Slave" title="CCI-500" name="Read RVALID" description="Read data handshake: any RVALID, RREADY HIGH"/>
+ <event event="0x09" option_set="Slave" title="CCI-500" name="Read RLAST" description="Read data handshake with RLAST set, for a snoop hit"/>
+ <event event="0x0a" option_set="Slave" title="CCI-500" name="Write AWVALID" description="Write request: any AWVALID, AWREADY HIGH"/>
+ <event event="0x0b" option_set="Slave" title="CCI-500" name="Write device" description="Write request: device"/>
+ <event event="0x0c" option_set="Slave" title="CCI-500" name="Write non-shareable" description="Write request: non-shareable"/>
+ <event event="0x0d" option_set="Slave" title="CCI-500" name="Write shareable a" description="Write request handshake: shareable, for example WriteBack, WriteClean"/>
+ <event event="0x0e" option_set="Slave" title="CCI-500" name="Write shareable b" description="Write request handshake: shareable, for example WriteLineUnique"/>
+ <event event="0x0f" option_set="Slave" title="CCI-500" name="Write shareable c" description="Write request handshake: shareable, for example WriteUnique"/>
+ <event event="0x10" option_set="Slave" title="CCI-500" name="Write evict" description="Write request handshake, for example Evict"/>
+ <!--event event="0x11" option_set="Slave" title="CCI-500" name="Write evict ?" description="Write request handshake, for example WriteEvict. WriteEvict is not supported in the CCI-500, so does not fire."/-->
+ <event event="0x12" option_set="Slave" title="CCI-500" name="Write WVALID" description="Write data beat: any WVALID, WREADY HIGH"/>
+ <event event="0x13" option_set="Slave" title="CCI-500" name="Snoop ACVLID" description="Snoop request: any ACVALID, ACREADY HIGH"/>
+ <event event="0x14" option_set="Slave" title="CCI-500" name="Snoop read" description="Snoop request: read, for example ReadOnce, ReadClean, ReadNotSharedDirty, ReadShared, ReadUnique"/>
+ <event event="0x15" option_set="Slave" title="CCI-500" name="Snoop invalidate" description="Snoop request: clean or invalidate, for example MakeInvalid, CleanInvalid, CleanShared"/>
+ <event event="0x16" option_set="Slave" title="CCI-500" name="Snoop CRRESP" description="Snoop request: Data Transfer bit CRRESP[0] LOW"/>
+ <event event="0x17" option_set="Slave" title="CCI-500" name="Read request stall" description="Read request stall: ARVALID HIGH ARREADY LOW"/>
+ <event event="0x18" option_set="Slave" title="CCI-500" name="Read data stall" description="Read data stall: RVALID HIGH RREADY LOW"/>
+ <event event="0x19" option_set="Slave" title="CCI-500" name="Write request stall" description="Write request stall: AWVALID HIGH AWREADY LOW"/>
+ <event event="0x1a" option_set="Slave" title="CCI-500" name="Write data stall" description="Write data stall: WVALID HIGH WREADY LOW"/>
+ <event event="0x1b" option_set="Slave" title="CCI-500" name="Write response stall" description="Write response stall: BVALID HIGH BREADY LOW"/>
+ <event event="0x1c" option_set="Slave" title="CCI-500" name="Snoop request stall" description="Snoop request stall: ACVALID HIGH ACREADY LOW"/>
+ <event event="0x1d" option_set="Slave" title="CCI-500" name="Snoop data stall" description="Snoop data stall: CDVALID HIGH CDREADY LOW"/>
+ <event event="0x1e" option_set="Slave" title="CCI-500" name="Request stall" description="Request stall cycle because of OT transaction limit"/>
+ <event event="0x1f" option_set="Slave" title="CCI-500" name="Read stall" description="Read stall because of arbitration"/>
+ <option_set name="Master">
+ <option event_delta="0x100" name="M0" description="Master interface 0"/>
+ <option event_delta="0x120" name="M1" description="Master interface 1"/>
+ <option event_delta="0x140" name="M2" description="Master interface 2"/>
+ <option event_delta="0x160" name="M3" description="Master interface 3"/>
+ <option event_delta="0x180" name="M4" description="Master interface 4"/>
+ <option event_delta="0x1a0" name="M5" description="Master interface 5"/>
+ </option_set>
+ <event event="0x00" option_set="Master" title="CCI-500" name="Read data beat" description="Read data beat: any"/>
+ <event event="0x01" option_set="Master" title="CCI-500" name="Write data beat" description="Write data beat: any"/>
+ <event event="0x02" option_set="Master" title="CCI-500" name="Read request stall" description="Read request stall: ARVALID HIGH ARREADY LOW"/>
+ <event event="0x03" option_set="Master" title="CCI-500" name="Read data stall" description="Read data stall: RVALID HIGH RREADY LOW"/>
+ <event event="0x04" option_set="Master" title="CCI-500" name="Write request stall" description="Write request stall: AWVALID HIGH AWREADY LOW"/>
+ <event event="0x05" option_set="Master" title="CCI-500" name="Write data stall" description="Write data stall: WVALID HIGH WREADY LOW"/>
+ <event event="0x06" option_set="Master" title="CCI-500" name="Write response stall" description="Write response stall: BVALID HIGH BREADY LOW"/>
+ <event event="0x1e0" title="CCI-500" name="Snoop response 0/1" description="Access to snoop filter bank 0 or 1, any response"/>
+ <event event="0x1e1" title="CCI-500" name="Snoop response 2/3" description="Access to snoop filter bank 2 or 3, any response"/>
+ <event event="0x1e2" title="CCI-500" name="Snoop response 3/4" description="Access to snoop filter bank 4 or 5, any response"/>
+ <event event="0x1e3" title="CCI-500" name="Snoop response 6/7" description="Access to snoop filter bank 6 or 7, any response"/>
+ <event event="0x1e4" title="CCI-500" name="Snoop miss 0/1" description="Access to snoop filter bank 0 or 1, miss response"/>
+ <event event="0x1e5" title="CCI-500" name="Snoop miss 2/3" description="Access to snoop filter bank 2 or 3, miss response"/>
+ <event event="0x1e6" title="CCI-500" name="Snoop miss 4/5" description="Access to snoop filter bank 4 or 5, miss response"/>
+ <event event="0x1e7" title="CCI-500" name="Snoop miss 6/7" description="Access to snoop filter bank 6 or 7, miss response"/>
+ <event event="0x1e8" title="CCI-500" name="Snoop invalidation" description="Back invalidation from snoop filter"/>
+ <event event="0x1e9" title="CCI-500" name="Snoop small" description="Requests that allocate into a snoop filter bank might be stalled because all ways are used. The snoop filter RAM might be too small."/>
+ <event event="0x1ea" title="CCI-500" name="TT stall" description="Stall because TT full, increase TT_DEPTH parameter to avoid performance degradation"/>
+ <event event="0x1eb" title="CCI-500" name="Write request" description="CCI-generated write request"/>
+ <event event="0x1ec" title="CCI-500" name="Snoop handshake" description="CD handshake in snoop network, use this to measure snoop data bandwidth. Each event corresponds to 16 bytes of snoop data."/>
+ <event event="0x1ed" title="CCI-500" name="Address hazard" description="Request stall because of address hazard"/>
+ <event event="0x1ee" title="CCI-500" name="TT full" description="Snoop request stall because of snoop TT being full"/>
+ <event event="0x1ef" title="CCI-500" name="Snoop override" description="Snoop request type override for TZMP1 protection"/>
+ </category>
diff --git a/daemon/events-Cortex-A15.xml b/daemon/events-Cortex-A15.xml
index f50e55d..c0ccc8a 100644
--- a/daemon/events-Cortex-A15.xml
+++ b/daemon/events-Cortex-A15.xml
@@ -1,68 +1,70 @@
<counter_set name="ARMv7_Cortex_A15_cnt" count="6"/>
<category name="Cortex-A15" counter_set="ARMv7_Cortex_A15_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARMv7_Cortex_A15_ccnt" event="0xff" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
- <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/>
+ <event event="0x00" title="Software" name="Increment" description="Instruction architecturally executed, condition code check pass, software increment"/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
<event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
<event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
<event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
<event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
<event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
- <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
- <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
- <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
- <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken"/>
+ <event event="0x0a" title="Exception" name="Return" description="Instruction architecturally executed, condition code check pass, exception return"/>
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction architecturally executed, condition code check pass, write to CONTEXTIDR"/>
+ <event event="0x10" title="Branch" name="Mispredicted" description="Mispredicted or not predicted branch speculatively executed"/>
<event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
<event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
- <event event="0x14" title="Cache" name="L1 inst access" description="Instruction cache access"/>
- <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache Write-Back"/>
+ <event event="0x14" title="Cache" name="L1 inst access" description="Level 1 instruction cache access"/>
+ <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache write-back"/>
<event event="0x16" title="Cache" name="L2 data access" description="Level 2 data cache access"/>
<event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/>
- <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache Write-Back"/>
- <event event="0x19" title="Bus" name="Access" description="Bus - Access"/>
+ <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache write-back"/>
+ <event event="0x19" title="Bus" name="Access" description="Bus access"/>
<event event="0x1a" title="Memory" name="Error" description="Local memory error"/>
<event event="0x1b" title="Instruction" name="Speculative" description="Instruction speculatively executed"/>
- <event event="0x1c" title="Memory" name="Translation table" description="Write to translation table base architecturally executed"/>
- <event event="0x1d" title="Bus" name="Cycle" description="Bus - Cycle"/>
- <event event="0x40" title="Cache" name="L1 data read" description="Level 1 data cache access - Read"/>
- <event event="0x41" title="Cache" name="L1 data access write" description="Level 1 data cache access - Write"/>
- <event event="0x42" title="Cache" name="L1 data refill read" description="Level 1 data cache refill - Read"/>
- <event event="0x43" title="Cache" name="L1 data refill write" description="Level 1 data cache refill - Write"/>
- <event event="0x46" title="Cache" name="L1 data victim" description="Level 1 data cache Write-Back - Victim"/>
- <event event="0x47" title="Cache" name="L1 data clean" description="Level 1 data cache Write-Back - Cleaning and coherency"/>
+ <event event="0x1c" title="Memory" name="Translation table" description="Instruction architecturally executed, condition code check pass, write to TTBR"/>
+ <event event="0x1d" title="Bus" name="Cycle" description="Bus cycle"/>
+ <event event="0x40" title="Cache" name="L1 data read" description="Level 1 data cache access, read"/>
+ <event event="0x41" title="Cache" name="L1 data access write" description="Level 1 data cache access, write"/>
+ <event event="0x42" title="Cache" name="L1 data refill read" description="Level 1 data cache refill, read"/>
+ <event event="0x43" title="Cache" name="L1 data refill write" description="Level 1 data cache refill, write"/>
+ <event event="0x46" title="Cache" name="L1 data victim" description="Level 1 data cache write-back, victim"/>
+ <event event="0x47" title="Cache" name="L1 data clean" description="Level 1 data cache write-back, cleaning and coherency"/>
<event event="0x48" title="Cache" name="L1 data invalidate" description="Level 1 data cache invalidate"/>
- <event event="0x4c" title="TLB" name="L1 data refill read" description="Level 1 data TLB refill - Read"/>
- <event event="0x4d" title="TLB" name="L1 data refill write" description="Level 1 data TLB refill - Write"/>
- <event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access - Read"/>
- <event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access - Write"/>
- <event event="0x52" title="Cache" name="L2 data refill read" description="Level 2 data cache refill - Read"/>
- <event event="0x53" title="Cache" name="L2 data refill write" description="Level 2 data cache refill - Write"/>
- <event event="0x56" title="Cache" name="L2 data victim" description="Level 2 data cache Write-Back - Victim"/>
- <event event="0x57" title="Cache" name="L2 data clean" description="Level 2 data cache Write-Back - Cleaning and coherency"/>
+ <event event="0x4c" title="Cache" name="L1 TLB refill read" description="Level 1 data TLB refill, read"/>
+ <event event="0x4d" title="Cache" name="L1 TLB refill write" description="Level 1 data TLB refill, write"/>
+ <event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access, read"/>
+ <event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access, write"/>
+ <event event="0x52" title="Cache" name="L2 data refill read" description="Level 2 data cache refill, read"/>
+ <event event="0x53" title="Cache" name="L2 data refill write" description="Level 2 data cache refill, write"/>
+ <event event="0x56" title="Cache" name="L2 data victim" description="Level 2 data cache write-back, victim"/>
+ <event event="0x57" title="Cache" name="L2 data clean" description="Level 2 data cache write-back, cleaning and coherency"/>
<event event="0x58" title="Cache" name="L2 data invalidate" description="Level 2 data cache invalidate"/>
- <event event="0x60" title="Bus" name="Read" description="Bus access - Read"/>
- <event event="0x61" title="Bus" name="Write" description="Bus access - Write"/>
- <event event="0x64" title="Bus" name="Access normal" description="Bus access - Normal"/>
- <event event="0x65" title="Bus" name="Peripheral" description="Bus access - Peripheral"/>
- <event event="0x66" title="Memory" name="Read" description="Data memory access - Read"/>
- <event event="0x67" title="Memory" name="Write" description="Data memory access - Write"/>
- <event event="0x68" title="Memory" name="Unaligned Read" description="Unaligned access - Read"/>
- <event event="0x69" title="Memory" name="Unaligned Write" description="Unaligned access - Write"/>
+ <event event="0x60" title="Bus" name="Read" description="Bus access, read"/>
+ <event event="0x61" title="Bus" name="Write" description="Bus access, write"/>
+ <event event="0x62" title="Bus" name="Cacheable normal" description="Bus access, Normal, Cacheable, Shareable"/>
+ <event event="0x63" title="Bus" name="Not normal" description="Bus access, not Normal, Cacheable, Shareable"/>
+ <event event="0x64" title="Bus" name="Access normal" description="Bus access, normal"/>
+ <event event="0x65" title="Bus" name="Peripheral" description="Bus access, peripheral"/>
+ <event event="0x66" title="Memory" name="Read" description="Data memory access, read"/>
+ <event event="0x67" title="Memory" name="Write" description="Data memory access, write"/>
+ <event event="0x68" title="Memory" name="Unaligned Read" description="Unaligned access, read"/>
+ <event event="0x69" title="Memory" name="Unaligned Write" description="Unaligned access, write"/>
<event event="0x6a" title="Memory" name="Unaligned" description="Unaligned access"/>
- <event event="0x6c" title="Intrinsic" name="LDREX" description="Exclusive instruction speculatively executed - LDREX"/>
- <event event="0x6d" title="Intrinsic" name="STREX pass" description="Exclusive instruction speculatively executed - STREX pass"/>
- <event event="0x6e" title="Intrinsic" name="STREX fail" description="Exclusive instruction speculatively executed - STREX fail"/>
- <event event="0x70" title="Instruction" name="Load" description="Instruction speculatively executed - Load"/>
- <event event="0x71" title="Instruction" name="Store" description="Instruction speculatively executed - Store"/>
- <event event="0x72" title="Instruction" name="Load/Store" description="Instruction speculatively executed - Load or store"/>
- <event event="0x73" title="Instruction" name="Integer" description="Instruction speculatively executed - Integer data processing"/>
- <event event="0x74" title="Instruction" name="Advanced SIMD" description="Instruction speculatively executed - Advanced SIMD"/>
- <event event="0x75" title="Instruction" name="VFP" description="Instruction speculatively executed - VFP"/>
- <event event="0x76" title="Instruction" name="Software change" description="Instruction speculatively executed - Software change of the PC"/>
- <event event="0x78" title="Instruction" name="Immediate branch" description="Branch speculatively executed - Immediate branch"/>
- <event event="0x79" title="Instruction" name="Procedure return" description="Branch speculatively executed - Procedure return"/>
- <event event="0x7a" title="Instruction" name="Indirect branch" description="Branch speculatively executed - Indirect branch"/>
- <event event="0x7c" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
- <event event="0x7d" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
- <event event="0x7e" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
+ <event event="0x6c" title="Intrinsic" name="LDREX" description="Exclusive instruction speculatively executed, LDREX"/>
+ <event event="0x6d" title="Intrinsic" name="STREX pass" description="Exclusive instruction speculatively executed, STREX pass"/>
+ <event event="0x6e" title="Intrinsic" name="STREX fail" description="Exclusive instruction speculatively executed, STREX fail"/>
+ <event event="0x70" title="Instruction" name="Load" description="Instruction speculatively executed, load"/>
+ <event event="0x71" title="Instruction" name="Store" description="Instruction speculatively executed, store"/>
+ <event event="0x72" title="Instruction" name="Load/Store" description="Instruction speculatively executed, load or store"/>
+ <event event="0x73" title="Instruction" name="Integer" description="Instruction speculatively executed, integer data processing"/>
+ <event event="0x74" title="Instruction" name="Advanced SIMD" description="Instruction speculatively executed, Advanced SIMD Extension"/>
+ <event event="0x75" title="Instruction" name="VFP" description="Instruction speculatively executed, Floating-point Extension"/>
+ <event event="0x76" title="Instruction" name="Software change" description="Instruction speculatively executed, software change of the PC"/>
+ <event event="0x78" title="Branch" name="Immediate" description="Branch speculatively executed, immediate branch"/>
+ <event event="0x79" title="Procedure" name="Return" description="Branch speculatively executed, procedure return"/>
+ <event event="0x7a" title="Branch" name="Indirect" description="Branch speculatively executed, indirect branch"/>
+ <event event="0x7c" title="Instruction" name="ISB" description="Barrier speculatively executed, ISB"/>
+ <event event="0x7d" title="Instruction" name="DSB" description="Barrier speculatively executed, DSB"/>
+ <event event="0x7e" title="Instruction" name="DMB" description="Barrier speculatively executed, DMB"/>
</category>
diff --git a/daemon/events-Cortex-A17.xml b/daemon/events-Cortex-A17.xml
index 4dd08c1..ce1b781 100644
--- a/daemon/events-Cortex-A17.xml
+++ b/daemon/events-Cortex-A17.xml
@@ -1,37 +1,36 @@
<counter_set name="ARMv7_Cortex_A17_cnt" count="6"/>
<category name="Cortex-A17" counter_set="ARMv7_Cortex_A17_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARMv7_Cortex_A17_ccnt" event="0xff" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
- <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
- <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
- <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
- <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
- <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
+ <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill at (at least) the lowest level of instruction or unified cache. Includes the speculative linefills in the count."/>
+ <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill at (at least) the lowest level of TLB. Includes the speculative requests in the count."/>
+ <event event="0x03" title="Cache" name="Data refill" description="Data read or write operation that causes a refill at (at least) the lowest level of data or unified cache. Counts the number of allocations performed in the Data Cache because of a read or a write."/>
+ <event event="0x04" title="Cache" name="Data access" description="Data read or write operation that causes a cache access at (at least) the lowest level of data or unified cache. This includes speculative reads."/>
+ <event event="0x05" title="Cache" name="Data TLB refill" description="Data read or write operation that causes a TLB refill at (at least) the lowest level of TLB. This does not include micro TLB misses because of PLD, PLI, CP15 Cache operation by MVA and CP15 VA to PA operations."/>
<event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
- <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken. Counts the number of exceptions architecturally taken."/>
<event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
- <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
- <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
- <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
- <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
- <event event="0x14" title="Cache" name="L1 inst access" description="Instruction cache access"/>
- <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache Write-Back"/>
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Change to ContextID retired. Counts the number of instructions architecturally executed writing into the ContextID register."/>
+ <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted. Counts the number of mispredicted or not-predicted branches executed. This includes the branches which are flushed because of a previous load/store which aborts late."/>
+ <event event="0x12" title="Branch" name="Potential prediction" description="Branches or other change in program flow that could have been predicted by the branch prediction resources of the processor. This includes the branches which are flushed because of a previous load/store which aborts late."/>
+ <event event="0x13" title="Memory" name="Memory access" description="Level 1 data memory access"/>
+ <event event="0x14" title="Cache" name="L1 inst access" description="Level 1 instruction cache access"/>
+ <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache eviction"/>
<event event="0x16" title="Cache" name="L2 data access" description="Level 2 data cache access"/>
<event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/>
- <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache Write-Back"/>
- <event event="0x19" title="Bus" name="Access" description="Bus - Access"/>
- <event event="0x1b" title="Instruction" name="Speculative" description="Instruction speculatively executed"/>
- <event event="0x1c" title="Memory" name="Translation table" description="Write to translation table base architecturally executed"/>
- <event event="0x1d" title="Bus" name="Cycle" description="Bus - Cycle"/>
+ <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache write-back. Data transfers made as a result of a coherency request from the Level 2 caches to outside of the Level 1 and Level 2 caches are not counted. Write-backs made as a result of CP15 cache maintenance operations are counted."/>
+ <event event="0x19" title="Bus" name="Access" description="Bus accesses. Single transfer bus accesses on either of the ACE read or write channels might increment twice in one cycle if both the read and write channels are active simultaneously.Operations that utilise the bus that do not explicitly transfer data, such as barrier or coherency operations are counted as bus accesses."/>
+ <event event="0x1b" title="Instruction" name="Speculative" description="Instructions speculatively executed"/>
+ <event event="0x1c" title="Memory" name="Translation table" description="Write to translation table register (TTBR0 or TTBR1)"/>
+ <event event="0x1d" title="Bus" name="Cycle" description="Bus cycle"/>
<event event="0x40" title="Cache" name="L1 data read" description="Level 1 data cache access - Read"/>
<event event="0x41" title="Cache" name="L1 data access write" description="Level 1 data cache access - Write"/>
<event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access - Read"/>
<event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access - Write"/>
- <event event="0x56" title="Cache" name="L2 data victim" description="Level 2 data cache Write-Back - Victim"/>
- <event event="0x57" title="Cache" name="L2 data clean" description="Level 2 data cache Write-Back - Cleaning and coherency"/>
+ <event event="0x56" title="Cache" name="L2 data victim" description="Level 2 data cache write-back - Victim"/>
+ <event event="0x57" title="Cache" name="L2 data clean" description="Level 2 data cache write-back - Cleaning and coherency"/>
<event event="0x58" title="Cache" name="L2 data invalidate" description="Level 2 data cache invalidate"/>
- <event event="0x60" title="Bus" name="Read" description="Bus access - Read"/>
- <event event="0x62" title="Bus" name="Access shared" description="Bus access - Normal"/>
- <event event="0x63" title="Bus" name="Access not shared" description="Bus access - Not normal"/>
+ <event event="0x62" title="Bus" name="Access shared" description="Bus access - Normal Cacheable"/>
+ <event event="0x63" title="Bus" name="Access not shared" description="Bus access - Not Cacheable"/>
<event event="0x64" title="Bus" name="Access normal" description="Bus access - Normal"/>
<event event="0x65" title="Bus" name="Peripheral" description="Bus access - Peripheral"/>
<event event="0x66" title="Memory" name="Read" description="Data memory access - Read"/>
@@ -42,27 +41,27 @@
<event event="0x6c" title="Intrinsic" name="LDREX" description="Exclusive instruction speculatively executed - LDREX"/>
<event event="0x6e" title="Intrinsic" name="STREX fail" description="Exclusive instruction speculatively executed - STREX fail"/>
<event event="0x6f" title="Intrinsic" name="STREX" description="Exclusive instruction speculatively executed - STREX"/>
- <event event="0x70" title="Instruction" name="Load" description="Instruction speculatively executed - Load"/>
- <event event="0x71" title="Instruction" name="Store" description="Instruction speculatively executed - Store"/>
+ <event event="0x70" title="Instruction" name="Load" description="Load instruction speculatively executed"/>
+ <event event="0x71" title="Instruction" name="Store" description="Store instruction speculatively executed"/>
<event event="0x72" title="Instruction" name="Load/Store" description="Instruction speculatively executed - Load or store"/>
- <event event="0x73" title="Instruction" name="Integer" description="Instruction speculatively executed - Integer data processing"/>
+ <event event="0x73" title="Instruction" name="Integer" description="Instruction speculatively executed - Data processing"/>
<event event="0x74" title="Instruction" name="Advanced SIMD" description="Instruction speculatively executed - Advanced SIMD"/>
<event event="0x75" title="Instruction" name="VFP" description="Instruction speculatively executed - VFP"/>
<event event="0x76" title="Instruction" name="Software change" description="Instruction speculatively executed - Software change of the PC"/>
- <event event="0x78" title="Instruction" name="Immediate branch" description="Branch speculatively executed - Immediate branch"/>
- <event event="0x79" title="Instruction" name="Procedure return" description="Branch speculatively executed - Procedure return"/>
- <event event="0x7a" title="Instruction" name="Indirect branch" description="Branch speculatively executed - Indirect branch"/>
+ <event event="0x78" title="Branch" name="Immediate" description="Branch speculatively executed - Immediate branch"/>
+ <event event="0x79" title="Procedure" name="Return" description="Branch speculatively executed - Procedure return"/>
+ <event event="0x7a" title="Branch" name="Indirect" description="Branch speculatively executed - Indirect branch"/>
<event event="0x7c" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
<event event="0x7d" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
<event event="0x7e" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
- <event event="0x81" title="Exception" name="Undefined" description="Exception taken, other synchronous"/>
- <event event="0x8a" title="Exception" name="Hypervisor call" description="Exception taken, Hypervisor Call"/>
- <event event="0xc0" title="Instruction" name="Stalled Linefill" description="Instruction side stalled due to a Linefill"/>
- <event event="0xc1" title="Instruction" name="Stalled Page Table Walk" description="Instruction Side stalled due to a Page Table Walk"/>
+ <event event="0x81" title="Exception" name="Undefined" description="Exception taken - Undefined Instruction"/>
+ <event event="0x8a" title="Exception" name="Hypervisor call" description="Exception taken - Hypervisor Call"/>
+ <event event="0xc0" title="Instruction" name="Stalled Linefill" description="Instruction side stalled due to a linefill"/>
+ <event event="0xc1" title="Instruction" name="Stalled Page Table Walk" description="Instruction side stalled due to a translation table walk"/>
<event event="0xc2" title="Cache" name="4 Ways Read" description="Number of set of 4 ways read in the instruction cache - Tag RAM"/>
<event event="0xc3" title="Cache" name="Ways Read" description="Number of ways read in the instruction cache - Data RAM"/>
<event event="0xc4" title="Cache" name="BATC Read" description="Number of ways read in the instruction BTAC RAM"/>
- <event event="0xca" title="Memory" name="Snoop" description="Data snooped from other processor. This event counts memory-read operations that read data from another processor within the local Cortex-A17 cluster, rather than accessing the L2 cache or issuing an external read. It increments on each transaction, rather than on each beat of data"/>
+ <event event="0xca" title="Memory" name="Snoop" description="Data snooped from other processor. This event counts memory-read operations that read data from another processor within the local Cortex-A17 cluster, rather than accessing the L2 cache or issuing an external read. It increments on each transaction, rather than on each beat of data."/>
<event event="0xd3" title="Slots" name="Load-Store Unit" description="Duration during which all slots in the Load-Store Unit are busy"/>
<event event="0xd8" title="Slots" name="Load-Store Issue Queue" description="Duration during which all slots in the Load-Store Issue queue are busy"/>
<event event="0xd9" title="Slots" name="Data Processing Issue Queue" description="Duration during which all slots in the Data Processing issue queue are busy"/>
@@ -71,13 +70,13 @@
<event event="0xdc" title="Hypervisor" name="Traps" description="Number of Trap to hypervisor"/>
<event event="0xde" title="PTM" name="EXTOUT 0" description="PTM EXTOUT 0"/>
<event event="0xdf" title="PTM" name="EXTOUT 1" description="PTM EXTOUT 1"/>
- <event event="0xe0" title="MMU" name="Table Walk" description="Duration during which the MMU handle a Page table walk"/>
- <event event="0xe1" title="MMU" name="Stage1 Table Walk" description="Duration during which the MMU handle a Stage1 Page table walk"/>
- <event event="0xe2" title="MMU" name="Stage2 Table Walk" description="Duration during which the MMU handle a Stage2 Page table walk"/>
- <event event="0xe3" title="MMU" name="LSU Table Walk" description="Duration during which the MMU handle a Page table walk requested by the Load Store Unit"/>
- <event event="0xe4" title="MMU" name="Instruction Table Walk" description="Duration during which the MMU handle a Page table walk requested by the Instruction side"/>
- <event event="0xe5" title="MMU" name="Preload Table Walk" description="Duration during which the MMU handle a Page table walk requested by a Preload instruction or Prefetch request"/>
- <event event="0xe6" title="MMU" name="cp15 Table Walk" description="Duration during which the MMU handle a Page table walk requested by a cp15 operation (maintenance by MVA and VA-to-PA operation)"/>
+ <event event="0xe0" title="MMU" name="Table Walk" description="Duration during which the MMU handle a translation table walk"/>
+ <event event="0xe1" title="MMU" name="Stage1 Table Walk" description="Duration during which the MMU handle a Stage1 translation table walk"/>
+ <event event="0xe2" title="MMU" name="Stage2 Table Walk" description="Duration during which the MMU handle a Stage2 translation table walk"/>
+ <event event="0xe3" title="MMU" name="LSU Table Walk" description="Duration during which the MMU handle a translation table walk requested by the Load Store Unit"/>
+ <event event="0xe4" title="MMU" name="Instruction Table Walk" description="Duration during which the MMU handle a translation table walk requested by the Instruction side"/>
+ <event event="0xe5" title="MMU" name="Preload Table Walk" description="Duration during which the MMU handle a translation table walk requested by a Preload instruction or Prefetch request"/>
+ <event event="0xe6" title="MMU" name="cp15 Table Walk" description="Duration during which the MMU handle a translation table walk requested by a CP15 operation (maintenance by MVA and VA-to-PA operation)"/>
<event event="0xe7" title="Cache" name="L1 PLD TLB refill" description="Level 1 PLD TLB refill"/>
<event event="0xe8" title="Cache" name="L1 CP15 TLB refill" description="Level 1 CP15 TLB refill"/>
<event event="0xe9" title="Cache" name="L1 TLB flush" description="Level 1 TLB flush"/>
diff --git a/daemon/events-Cortex-A5.xml b/daemon/events-Cortex-A5.xml
index d67581d..9fd48ab 100644
--- a/daemon/events-Cortex-A5.xml
+++ b/daemon/events-Cortex-A5.xml
@@ -1,36 +1,36 @@
<counter_set name="ARMv7_Cortex_A5_cnt" count="2"/>
<category name="Cortex-A5" counter_set="ARMv7_Cortex_A5_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARMv7_Cortex_A5_ccnt" event="0xff" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
- <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
- <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
- <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
- <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
- <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
- <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
- <event event="0x06" title="Instruction" name="Memory read" description="Memory-reading instruction architecturally executed"/>
- <event event="0x07" title="Instruction" name="Memory write" description="Memory-writing instruction architecturally executed"/>
+ <event event="0x00" title="Software" name="Increment" description="Software increment. The register is incremented only on writes to the Software Increment Register."/>
+ <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill at (at least) the lowest level of instruction or unified cache. Includes the speculative linefills in the count."/>
+ <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill at (at least) the lowest level of TLB. Includes the speculative requests in the count."/>
+ <event event="0x03" title="Cache" name="Data refill" description="Data read or write operation that causes a refill at (at least) the lowest level of data or unified cache. Counts the number of allocations performed in the Data Cache because of a read or a write."/>
+ <event event="0x04" title="Cache" name="Data access" description="Data read or write operation that causes a cache access at (at least) the lowest level of data or unified cache. This includes speculative reads."/>
+ <event event="0x05" title="Cache" name="Data TLB refill" description="Data read or write operation that causes a TLB refill at (at least) the lowest level of TLB. This does not include micro TLB misses because of PLD, PLI, CP15 Cache operation by MVA and CP15 VA to PA operations."/>
+ <event event="0x06" title="Instruction" name="Memory read" description="Data read architecturally executed. Counts the number of data read instructions accepted by the Load Store Unit. This includes counting the speculative and aborted LDR/LDM, and the reads because of the SWP instructions."/>
+ <event event="0x07" title="Instruction" name="Memory write" description="Data write architecturally executed. Counts the number of data write instructions accepted by the Load Store Unit. This includes counting the speculative and aborted STR/STM, and the writes because of the SWP instructions."/>
<event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
- <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken. Counts the number of exceptions architecturally taken."/>
<event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
- <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
- <event event="0x0c" title="Branch" name="PC change" description="Software change of the Program Counter, except by an exception, architecturally executed"/>
- <event event="0x0d" title="Branch" name="Immediate" description="Immediate branch architecturally executed"/>
- <event event="0x0e" title="Procedure" name="Return" description="Procedure return, other than exception return, architecturally executed"/>
- <event event="0x0f" title="Memory" name="Unaligned access" description="Unaligned access architecturally executed"/>
- <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
- <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Change to ContextID retired. Counts the number of instructions architecturally executed writing into the ContextID Register."/>
+ <event event="0x0c" title="Branch" name="PC change" description="Software change of PC"/>
+ <event event="0x0d" title="Branch" name="Immediate" description="Immediate branch architecturally executed (taken or not taken). This includes the branches which are flushed due to a previous load/store which aborts late."/>
+ <event event="0x0e" title="Procedure" name="Return" description="Procedure return (other than exception returns) architecturally executed"/>
+ <event event="0x0f" title="Memory" name="Unaligned access" description="Unaligned load-store"/>
+ <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted/not predicted. Counts the number of mispredicted or not-predicted branches executed. This includes the branches which are flushed because of a previous load/store which aborts late."/>
+ <event event="0x12" title="Branch" name="Potential prediction" description="Branches or other change in program flow that could have been predicted by the branch prediction resources of the processor. This includes the branches which are flushed because of a previous load/store which aborts late."/>
<event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
- <event event="0x14" title="Cache" name="Instruction access" description="Instruction cache access"/>
+ <event event="0x14" title="Cache" name="Instruction access" description="Instruction Cache access"/>
<event event="0x15" title="Cache" name="Data eviction" description="Data cache eviction"/>
<event event="0x86" title="Interrupts" name="IRQ" description="IRQ exception taken"/>
<event event="0x87" title="Interrupts" name="FIQ" description="FIQ exception taken"/>
- <event event="0xC0" title="Memory" name="External request" description="External memory request"/>
- <event event="0xC1" title="Memory" name="Non-cacheable ext req" description="Non-cacheable external memory request"/>
- <event event="0xC2" title="Cache" name="Linefill" description="Linefill because of prefetch"/>
- <event event="0xC3" title="Cache" name="Linefill dropped" description="Prefetch linefill dropped"/>
- <event event="0xC4" title="Cache" name="Allocate mode enter" description="Entering read allocate mode"/>
- <event event="0xC5" title="Cache" name="Allocate mode" description="Read allocate mode"/>
- <event event="0xC7" title="ETM" name="ETM Ext Out[0]" description="ETM - ETM Ext Out[0]"/>
- <event event="0xC8" title="ETM" name="ETM Ext Out[1]" description="ETM - ETM Ext Out[1]"/>
- <event event="0xC9" title="Instruction" name="Pipeline stall" description="Data Write operation that stalls the pipeline because the store buffer is full"/>
+ <event event="0xc0" title="Memory" name="External request" description="External memory request"/>
+ <event event="0xc1" title="Memory" name="Non-cacheable ext req" description="Non-cacheable external memory request"/>
+ <event event="0xc2" title="Cache" name="Linefill" description="Linefill because of prefetch"/>
+ <event event="0xc3" title="Cache" name="Linefill dropped" description="Prefetch linefill dropped"/>
+ <event event="0xc4" title="Cache" name="Allocate mode enter" description="Entering read allocate mode"/>
+ <event event="0xc5" title="Cache" name="Allocate mode" description="Read allocate mode"/>
+ <event event="0xc7" title="ETM" name="ETM Ext Out[0]" description="ETM Ext Out[0]"/>
+ <event event="0xc8" title="ETM" name="ETM Ext Out[1]" description="ETM Ext Out[1]"/>
+ <event event="0xc9" title="Instruction" name="Pipeline stall" description="Data Write operation that stalls the pipeline because the store buffer is full"/>
</category>
diff --git a/daemon/events-Cortex-A53.xml b/daemon/events-Cortex-A53.xml
index 5ba1790..acdfe4e 100644
--- a/daemon/events-Cortex-A53.xml
+++ b/daemon/events-Cortex-A53.xml
@@ -1,87 +1,64 @@
<counter_set name="ARM_Cortex-A53_cnt" count="6"/>
<category name="Cortex-A53" counter_set="ARM_Cortex-A53_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARM_Cortex-A53_ccnt" event="0x11" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
- <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
+ <event event="0x00" title="Software" name="Increment" description="Software increment. The register is incremented only on writes to the Software Increment Register."/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
<event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
<event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
<event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
<event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
+ <event event="0x06" title="Instruction" name="Data Read" description="Instruction architecturally executed, condition check pass - load"/>
+ <event event="0x07" title="Instruction" name="Memory write" description="Instruction architecturally executed, condition check pass - store"/>
<event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
- <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
- <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
- <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
- <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken"/>
+ <event event="0x0a" title="Exception" name="Return" description="Exception return"/>
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Change to Context ID retired"/>
+ <event event="0x0c" title="Branch" name="PC change" description="Instruction architecturally executed, condition check pass, software change of the PC"/>
+ <event event="0x0d" title="Branch" name="Immediate" description="Instruction architecturally executed, immediate branch"/>
+ <event event="0x0e" title="Procedure" name="Return" description="Instruction architecturally executed, condition code check pass, procedure return"/>
+ <event event="0x0f" title="Memory" name="Unaligned access" description="Instruction architecturally executed, condition check pass, unaligned load or store"/>
+ <event event="0x10" title="Branch" name="Mispredicted" description="Mispredicted or not predicted branch speculatively executed"/>
<event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
<event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
- <event event="0x14" title="Cache" name="L1 inst access" description="Level 1 instruction cache access"/>
- <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache Write-Back"/>
- <event event="0x16" title="Cache" name="L2 data access" description="Level 2 data cache access"/>
- <event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/>
- <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache Write-Back"/>
+ <event event="0x14" title="Cache" name="L1 inst access" description="L1 Instruction cache access"/>
+ <event event="0x15" title="Cache" name="L1 data write" description="L1 Data cache Write-Back"/>
+ <event event="0x16" title="Cache" name="L2 data access" description="L2 Data cache access"/>
+ <event event="0x17" title="Cache" name="L2 data refill" description="L2 Data cache refill"/>
+ <event event="0x18" title="Cache" name="L2 data write" description="L2 Data cache Write-Back"/>
<event event="0x19" title="Bus" name="Access" description="Bus access"/>
- <event event="0x1A" title="Memory" name="Error" description="Local memory error"/>
- <event event="0x1B" title="Instruction" name="Speculative" description="Operation speculatively executed"/>
- <event event="0x1C" title="Memory" name="Translation table" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/>
- <event event="0x1D" title="Bus" name="Cycle" description="Bus cycle"/>
- <event event="0x1E" title="Counter chain" name="Odd Performance" description="Odd performance counter chain mode"/>
- <event event="0x40" title="Cache" name="L1 data read" description="Level 1 data cache access - Read"/>
- <event event="0x41" title="Cache" name="L1 data access write" description="Level 1 data cache access - Write"/>
- <event event="0x42" title="Cache" name="L1 data refill read" description="Level 1 data cache refill - Read"/>
- <event event="0x43" title="Cache" name="L1 data refill write" description="Level 1 data cache refill - Write"/>
- <event event="0x46" title="Cache" name="L1 data victim" description="Level 1 data cache Write-back - Victim"/>
- <event event="0x47" title="Cache" name="L1 data clean" description="Level 1 data cache Write-back - Cleaning and coherency"/>
- <event event="0x48" title="Cache" name="L1 data invalidate" description="Level 1 data cache invalidate"/>
- <event event="0x4C" title="Cache" name="L1 data refill read" description="Level 1 data TLB refill - Read"/>
- <event event="0x4D" title="Cache" name="L1 data refill write" description="Level 1 data TLB refill - Write"/>
- <event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access - Read"/>
- <event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access - Write"/>
- <event event="0x52" title="Cache" name="L2 data refill read" description="Level 2 data cache refill - Read"/>
- <event event="0x53" title="Cache" name="L2 data refill write" description="Level 2 data cache refill - Write"/>
- <event event="0x56" title="Cache" name="L2 data victim" description="Level 2 data cache Write-back - Victim"/>
- <event event="0x57" title="Cache" name="L2 data clean" description="Level 2 data cache Write-back - Cleaning and coherency"/>
- <event event="0x58" title="Cache" name="L2 data invalidate" description="Level 2 data cache invalidate"/>
+ <event event="0x1a" title="Memory" name="Error" description="Local memory error"/>
+ <event event="0x1d" title="Bus" name="Cycle" description="Bus cycle"/>
+ <event event="0x1e" title="Counter chain" name="Odd Performance" description="Odd performance counter chain mode"/>
<event event="0x60" title="Bus" name="Read" description="Bus access - Read"/>
<event event="0x61" title="Bus" name="Write" description="Bus access - Write"/>
- <event event="0x62" title="Bus" name="Access shared" description="Bus access - Normal"/>
- <event event="0x63" title="Bus" name="Access not shared" description="Bus access - Not normal"/>
- <event event="0x64" title="Bus" name="Access normal" description="Bus access - Normal"/>
- <event event="0x65" title="Bus" name="Peripheral" description="Bus access - Peripheral"/>
- <event event="0x66" title="Memory" name="Read" description="Data memory access - Read"/>
- <event event="0x67" title="Memory" name="Write" description="Data memory access - Write"/>
- <event event="0x68" title="Memory" name="Unaligned Read" description="Unaligned access - Read"/>
- <event event="0x69" title="Memory" name="Unaligned Write" description="Unaligned access - Write"/>
- <event event="0x6A" title="Memory" name="Unaligned" description="Unaligned access"/>
- <event event="0x6C" title="Intrinsic" name="LDREX" description="Exclusive operation speculatively executed - LDREX"/>
- <event event="0x6D" title="Intrinsic" name="STREX pass" description="Exclusive instruction speculatively executed - STREX pass"/>
- <event event="0x6E" title="Intrinsic" name="STREX fail" description="Exclusive operation speculatively executed - STREX fail"/>
- <event event="0x70" title="Instruction" name="Load" description="Operation speculatively executed - Load"/>
- <event event="0x71" title="Instruction" name="Store" description="Operation speculatively executed - Store"/>
- <event event="0x72" title="Instruction" name="Load/Store" description="Operation speculatively executed - Load or store"/>
- <event event="0x73" title="Instruction" name="Integer" description="Operation speculatively executed - Integer data processing"/>
- <event event="0x74" title="Instruction" name="Advanced SIMD" description="Operation speculatively executed - Advanced SIMD"/>
- <event event="0x75" title="Instruction" name="VFP" description="Operation speculatively executed - VFP"/>
- <event event="0x76" title="Instruction" name="Software change" description="Operation speculatively executed - Software change of the PC"/>
- <event event="0x77" title="Instruction" name="Crypto" description="Operation speculatively executed, crypto data processing"/>
- <event event="0x78" title="Instruction" name="Immediate branch" description="Branch speculatively executed - Immediate branch"/>
- <event event="0x79" title="Instruction" name="Procedure return" description="Branch speculatively executed - Procedure return"/>
- <event event="0x7A" title="Instruction" name="Indirect branch" description="Branch speculatively executed - Indirect branch"/>
- <event event="0x7C" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
- <event event="0x7D" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
- <event event="0x7E" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
- <event event="0x81" title="Exception" name="Undefined" description="Exception taken, other synchronous"/>
- <event event="0x82" title="Exception" name="Supervisor" description="Exception taken, Supervisor Call"/>
- <event event="0x83" title="Exception" name="Instruction abort" description="Exception taken, Instruction Abort"/>
- <event event="0x84" title="Exception" name="Data abort" description="Exception taken, Data Abort or SError"/>
+ <event event="0x7a" title="Branch" name="Indirect" description="Branch speculatively executed - Indirect branch"/>
<event event="0x86" title="Interrupts" name="IRQ" description="Exception taken, IRQ"/>
<event event="0x87" title="Interrupts" name="FIQ" description="Exception taken, FIQ"/>
- <event event="0x88" title="Exception" name="Secure monitor call" description="Exception taken, Secure Monitor Call"/>
- <event event="0x8A" title="Exception" name="Hypervisor call" description="Exception taken, Hypervisor Call"/>
- <event event="0x8B" title="Exception" name="Instruction abort non-local" description="Exception taken, Instruction Abort not taken locally"/>
- <event event="0x8C" title="Exception" name="Data abort non-local" description="Exception taken, Data Abort or SError not taken locally"/>
- <event event="0x8D" title="Exception" name="Other non-local" description="Exception taken - Other traps not taken locally"/>
- <event event="0x8E" title="Exception" name="IRQ non-local" description="Exception taken, IRQ not taken locally"/>
- <event event="0x8F" title="Exception" name="FIQ non-local" description="Exception taken, FIQ not taken locally"/>
- <event event="0x90" title="Release Consistency" name="Load" description="Release consistency instruction speculatively executed - Load Acquire"/>
- <event event="0x91" title="Release Consistency" name="Store" description="Release consistency instruction speculatively executed - Store Release"/>
+ <event event="0xc0" title="Memory" name="External request" description="External memory request"/>
+ <event event="0xc1" title="Memory" name="Non-cacheable ext req" description="Non-cacheable external memory request"/>
+ <event event="0xc2" title="Cache" name="Linefill" description="Linefill because of prefetch"/>
+ <event event="0xc3" title="Cache" name="Throttle" description="Instruction Cache Throttle occurred"/>
+ <event event="0xc4" title="Cache" name="Allocate mode enter" description="Entering read allocate mode"/>
+ <event event="0xc5" title="Cache" name="Allocate mode" description="Read allocate mode"/>
+ <event event="0xc6" title="Pre-decode" name="error" description="Pre-decode error"/>
+ <event event="0xc7" title="Memory" name="Write stall" description="Data Write operation that stalls the pipeline because the store buffer is full"/>
+ <event event="0xc8" title="Memory" name="Snoop" description="SCU Snooped data from another CPU for this CPU"/>
+ <event event="0xc9" title="Branch" name="Taken" description="Conditional branch executed"/>
+ <!--
+ <event event="0xca" title="Branch" name="Mispredicted a" description="Indirect branch mispredicted"/>
+ <event event="0xcb" title="Branch" name="Mispredicted b" description="Indirect branch mispredicted because of address miscompare"/>
+ <event event="0xcc" title="Branch" name="Mispredicted c" description="Conditional branch mispredicted"/>
+ -->
+ <event event="0xd0" title="Cache" name="L1 inst error" description="L1 Instruction Cache (data or tag) memory error"/>
+ <event event="0xd1" title="Cache" name="L1 data error" description="L1 Data Cache (data, tag or dirty) memory error, correctable or non-correctable"/>
+ <event event="0xd2" title="Cache" name="TLB error" description="TLB memory error"/>
+ <event event="0xe0" title="Stall" name="DPU IP empty" description="Attributable Performance Impact Event. Counts every cycle that the DPU IQ is empty and that is not because of a recent micro-TLB miss, instruction cache miss or pre-decode error."/>
+ <event event="0xe1" title="Stall" name="Cache miss" description="Attributable Performance Impact Event. Counts every cycle the DPU IQ is empty and there is an instruction cache miss being processed."/>
+ <event event="0xe2" title="Stall" name="TLB miss" description="Attributable Performance Impact Event. Counts every cycle the DPU IQ is empty and there is an instruction micro-TLB miss being processed."/>
+ <event event="0xe3" title="Stall" name="Pre-decode error" description="Attributable Performance Impact Event. Counts every cycle the DPU IQ is empty and there is a pre-decode error being processed."/>
+ <event event="0xe4" title="Stall" name="Interlock other" description="Attributable Performance Impact Event. Counts every cycle there is an interlock that is not because of an Advanced SIMD or Floating-point instruction, and not because of a load/store instruction waiting for data to calculate the address in the AGU. Stall cycles because of a stall in Wr, typically awaiting load data, are excluded."/>
+ <event event="0xe5" title="Stall" name="Interlock address" description="Attributable Performance Impact Event. Counts every cycle there is an interlock that is because of a load/store instruction waiting for data to calculate the address in the AGU. Stall cycles because of a stall in Wr, typically awaiting load data, are excluded."/>
+ <event event="0xe6" title="Stall" name="Interlock SIMD/FPU" description="Attributable Performance Impact Event. Counts every cycle there is an interlock that is because of an Advanced SIMD or Floating-point instruction. Stall cycles because of a stall in the Wr stage, typically awaiting load data, are excluded."/>
+ <event event="0xe7" title="Stall" name="Load miss" description="Attributable Performance Impact Event. Counts every cycle there is a stall in the Wr stage because of a load miss"/>
+ <event event="0xe8" title="Stall" name="Store" description="Attributable Performance Impact Event. Counts every cycle there is a stall in the Wr stage because of a store."/>
</category>
diff --git a/daemon/events-Cortex-A57.xml b/daemon/events-Cortex-A57.xml
index fbe96c2..1da23e7 100644
--- a/daemon/events-Cortex-A57.xml
+++ b/daemon/events-Cortex-A57.xml
@@ -8,10 +8,10 @@
<event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
<event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
<event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
- <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
- <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
- <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
- <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken"/>
+ <event event="0x0a" title="Exception" name="Return" description="Instruction architecturally executed (condition check pass) - Exception return"/>
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction architecturally executed (condition check pass) - Write to CONTEXTIDR"/>
+ <event event="0x10" title="Branch" name="Mispredicted" description="Mispredicted or not predicted branch speculatively executed"/>
<event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
<event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
<event event="0x14" title="Cache" name="L1 inst access" description="Level 1 instruction cache access"/>
@@ -20,11 +20,11 @@
<event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/>
<event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache Write-Back"/>
<event event="0x19" title="Bus" name="Access" description="Bus access"/>
- <event event="0x1A" title="Memory" name="Error" description="Local memory error"/>
- <event event="0x1B" title="Instruction" name="Speculative" description="Operation speculatively executed"/>
- <event event="0x1C" title="Memory" name="Translation table" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/>
- <event event="0x1D" title="Bus" name="Cycle" description="Bus cycle"/>
- <event event="0x1E" title="Counter chain" name="Odd Performance" description="Odd performance counter chain mode"/>
+ <event event="0x1a" title="Memory" name="Error" description="Local memory error"/>
+ <event event="0x1b" title="Instruction" name="Speculative" description="Operation speculatively executed"/>
+ <event event="0x1c" title="Memory" name="Translation table" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/>
+ <event event="0x1d" title="Bus" name="Cycle" description="Bus cycle"/>
+ <event event="0x1e" title="Counter chain" name="Odd Performance" description="Odd performance counter chain mode"/>
<event event="0x40" title="Cache" name="L1 data read" description="Level 1 data cache access - Read"/>
<event event="0x41" title="Cache" name="L1 data access write" description="Level 1 data cache access - Write"/>
<event event="0x42" title="Cache" name="L1 data refill read" description="Level 1 data cache refill - Read"/>
@@ -32,8 +32,8 @@
<event event="0x46" title="Cache" name="L1 data victim" description="Level 1 data cache Write-back - Victim"/>
<event event="0x47" title="Cache" name="L1 data clean" description="Level 1 data cache Write-back - Cleaning and coherency"/>
<event event="0x48" title="Cache" name="L1 data invalidate" description="Level 1 data cache invalidate"/>
- <event event="0x4C" title="Cache" name="L1 data refill read" description="Level 1 data TLB refill - Read"/>
- <event event="0x4D" title="Cache" name="L1 data refill write" description="Level 1 data TLB refill - Write"/>
+ <event event="0x4c" title="Cache" name="L1 TLB refill read" description="Level 1 data TLB refill - Read"/>
+ <event event="0x4d" title="Cache" name="L1 TLB refill write" description="Level 1 data TLB refill - Write"/>
<event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access - Read"/>
<event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access - Write"/>
<event event="0x52" title="Cache" name="L2 data refill read" description="Level 2 data cache refill - Read"/>
@@ -51,10 +51,10 @@
<event event="0x67" title="Memory" name="Write" description="Data memory access - Write"/>
<event event="0x68" title="Memory" name="Unaligned Read" description="Unaligned access - Read"/>
<event event="0x69" title="Memory" name="Unaligned Write" description="Unaligned access - Write"/>
- <event event="0x6A" title="Memory" name="Unaligned" description="Unaligned access"/>
- <event event="0x6C" title="Intrinsic" name="LDREX" description="Exclusive operation speculatively executed - LDREX"/>
- <event event="0x6D" title="Intrinsic" name="STREX pass" description="Exclusive instruction speculatively executed - STREX pass"/>
- <event event="0x6E" title="Intrinsic" name="STREX fail" description="Exclusive operation speculatively executed - STREX fail"/>
+ <event event="0x6a" title="Memory" name="Unaligned" description="Unaligned access"/>
+ <event event="0x6c" title="Intrinsic" name="LDREX" description="Exclusive operation speculatively executed - LDREX"/>
+ <event event="0x6d" title="Intrinsic" name="STREX pass" description="Exclusive instruction speculatively executed - STREX pass"/>
+ <event event="0x6e" title="Intrinsic" name="STREX fail" description="Exclusive operation speculatively executed - STREX fail"/>
<event event="0x70" title="Instruction" name="Load" description="Operation speculatively executed - Load"/>
<event event="0x71" title="Instruction" name="Store" description="Operation speculatively executed - Store"/>
<event event="0x72" title="Instruction" name="Load/Store" description="Operation speculatively executed - Load or store"/>
@@ -63,12 +63,12 @@
<event event="0x75" title="Instruction" name="VFP" description="Operation speculatively executed - VFP"/>
<event event="0x76" title="Instruction" name="Software change" description="Operation speculatively executed - Software change of the PC"/>
<event event="0x77" title="Instruction" name="Crypto" description="Operation speculatively executed, crypto data processing"/>
- <event event="0x78" title="Instruction" name="Immediate branch" description="Branch speculatively executed - Immediate branch"/>
- <event event="0x79" title="Instruction" name="Procedure return" description="Branch speculatively executed - Procedure return"/>
- <event event="0x7A" title="Instruction" name="Indirect branch" description="Branch speculatively executed - Indirect branch"/>
- <event event="0x7C" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
- <event event="0x7D" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
- <event event="0x7E" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
+ <event event="0x78" title="Branch" name="Immediate" description="Branch speculatively executed - Immediate branch"/>
+ <event event="0x79" title="Procedure" name="Return" description="Branch speculatively executed - Procedure return"/>
+ <event event="0x7a" title="Branch" name="Indirect" description="Branch speculatively executed - Indirect branch"/>
+ <event event="0x7c" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
+ <event event="0x7d" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
+ <event event="0x7e" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
<event event="0x81" title="Exception" name="Undefined" description="Exception taken, other synchronous"/>
<event event="0x82" title="Exception" name="Supervisor" description="Exception taken, Supervisor Call"/>
<event event="0x83" title="Exception" name="Instruction abort" description="Exception taken, Instruction Abort"/>
@@ -76,12 +76,12 @@
<event event="0x86" title="Interrupts" name="IRQ" description="Exception taken, IRQ"/>
<event event="0x87" title="Interrupts" name="FIQ" description="Exception taken, FIQ"/>
<event event="0x88" title="Exception" name="Secure monitor call" description="Exception taken, Secure Monitor Call"/>
- <event event="0x8A" title="Exception" name="Hypervisor call" description="Exception taken, Hypervisor Call"/>
- <event event="0x8B" title="Exception" name="Instruction abort non-local" description="Exception taken, Instruction Abort not taken locally"/>
- <event event="0x8C" title="Exception" name="Data abort non-local" description="Exception taken, Data Abort or SError not taken locally"/>
- <event event="0x8D" title="Exception" name="Other non-local" description="Exception taken - Other traps not taken locally"/>
- <event event="0x8E" title="Exception" name="IRQ non-local" description="Exception taken, IRQ not taken locally"/>
- <event event="0x8F" title="Exception" name="FIQ non-local" description="Exception taken, FIQ not taken locally"/>
- <event event="0x90" title="Release Consistency" name="Load" description="Release consistency instruction speculatively executed - Load Acquire"/>
- <event event="0x91" title="Release Consistency" name="Store" description="Release consistency instruction speculatively executed - Store Release"/>
+ <event event="0x8a" title="Exception" name="Hypervisor call" description="Exception taken, Hypervisor Call"/>
+ <event event="0x8b" title="Exception" name="Instruction abort non-local" description="Exception taken, Instruction Abort not taken locally"/>
+ <event event="0x8c" title="Exception" name="Data abort non-local" description="Exception taken, Data Abort, or SError not taken locally"/>
+ <event event="0x8d" title="Exception" name="Other non-local" description="Exception taken - Other traps not taken locally"/>
+ <event event="0x8e" title="Exception" name="IRQ non-local" description="Exception taken, IRQ not taken locally"/>
+ <event event="0x8f" title="Exception" name="FIQ non-local" description="Exception taken, FIQ not taken locally"/>
+ <event event="0x90" title="Release Consistency" name="Load" description="Release consistency instruction speculatively executed - Load-Acquire"/>
+ <event event="0x91" title="Release Consistency" name="Store" description="Release consistency instruction speculatively executed - Store-Release"/>
</category>
diff --git a/daemon/events-Cortex-A7.xml b/daemon/events-Cortex-A7.xml
index 6e078b3..22fa9b7 100644
--- a/daemon/events-Cortex-A7.xml
+++ b/daemon/events-Cortex-A7.xml
@@ -1,43 +1,44 @@
<counter_set name="ARMv7_Cortex_A7_cnt" count="4"/>
<category name="Cortex-A7" counter_set="ARMv7_Cortex_A7_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARMv7_Cortex_A7_ccnt" event="0xff" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
- <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/>
- <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
- <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
- <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
- <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
- <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
- <event event="0x06" title="Memory" name="Data Read" description="Data read architecturally executed"/>
- <event event="0x07" title="Memory" name="Data Write" description="Data write architecturally executed"/>
+ <event event="0x00" title="Software" name="Increment" description="Software increment. The register is incremented only on writes to the Software Increment Register."/>
+ <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill at (at least) the lowest level of instruction or unified cache. Includes the speculative linefills in the count."/>
+ <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill at (at least) the lowest level of TLB. Includes the speculative requests in the count."/>
+ <event event="0x03" title="Cache" name="Data refill" description="Data read or write operation that causes a refill at (at least) the lowest level of data or unified cache. Counts the number of allocations performed in the Data Cache because of a read or a write."/>
+ <event event="0x04" title="Cache" name="Data access" description="Data read or write operation that causes a cache access at (at least) the lowest level of data or unified cache. This includes speculative reads."/>
+ <event event="0x05" title="Cache" name="Data TLB refill" description="Data read or write operation that causes a TLB refill at (at least) the lowest level of TLB. This does not include micro TLB misses because of PLD, PLI, CP15 Cache operation by MVA and CP15 VA to PA operations."/>
+ <event event="0x06" title="Instruction" name="Memory Read" description="Data read architecturally executed. Counts the number of data read instructions accepted by the Load Store Unit. This includes counting the speculative and aborted LDR/LDM, and the reads because of the SWP instructions."/>
+ <event event="0x07" title="Instruction" name="Memory write" description="Data write architecturally executed. Counts the number of data write instructions accepted by the Load Store Unit. This includes counting the speculative and aborted STR/STM, and the writes because of the SWP instructions."/>
<event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
- <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken. Counts the number of exceptions architecturally taken."/>
<event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
- <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
- <event event="0x0c" title="Branch" name="PC change" description="Software change of the Program Counter, except by an exception, architecturally executed"/>
- <event event="0x0d" title="Branch" name="Immediate" description="Immediate branch architecturally executed"/>
- <event event="0x0f" title="Memory" name="Unaligned access" description="Unaligned access architecturally executed"/>
- <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
- <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Change to ContextID retired. Counts the number of instructions architecturally executed writing into the ContextID Register."/>
+ <event event="0x0c" title="Branch" name="PC change" description="Software change of PC"/>
+ <event event="0x0d" title="Branch" name="Immediate" description="Immediate branch architecturally executed (taken or not taken). This includes the branches which are flushed due to a previous load/store which aborts late."/>
+ <event event="0x0e" title="Procedure" name="Return" description="Procedure return (other than exception returns) architecturally executed"/>
+ <event event="0x0f" title="Memory" name="Unaligned access" description="Unaligned load-store"/>
+ <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted/not predicted. Counts the number of mispredicted or not-predicted branches executed. This includes the branches which are flushed because of a previous load/store which aborts late."/>
+ <event event="0x12" title="Branch" name="Potential prediction" description="Branches or other change in program flow that could have been predicted by the branch prediction resources of the processor. This includes the branches which are flushed because of a previous load/store which aborts late."/>
<event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
- <event event="0x14" title="Cache" name="L1 inst access" description="Instruction cache access"/>
- <event event="0x15" title="Cache" name="L1 data eviction" description="Level 1 data cache eviction"/>
+ <event event="0x14" title="Cache" name="L1 inst access" description="Instruction Cache access"/>
+ <event event="0x15" title="Cache" name="L1 data eviction" description="Data cache eviction"/>
<event event="0x16" title="Cache" name="L2 data access" description="Level 2 data cache access"/>
<event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/>
- <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache Write-Back"/>
- <event event="0x19" title="Bus" name="Access" description="Bus - Access"/>
- <event event="0x1d" title="Bus" name="Cycle" description="Bus - Cycle"/>
- <event event="0x60" title="Bus" name="Read" description="Bus access - Read"/>
- <event event="0x61" title="Bus" name="Write" description="Bus access - Write"/>
+ <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache write-back. Data transfers made as a result of a coherency request from the Level 2 caches to outside of the Level 1 and Level 2 caches are not counted. Write-backs made as a result of CP15 cache maintenance operations are counted."/>
+ <event event="0x19" title="Bus" name="Access" description="Bus accesses. Single transfer bus accesses on either of the ACE read or write channels might increment twice in one cycle if both the read and write channels are active simultaneously. Operations that utilise the bus that do not explicitly transfer data, such as barrier or coherency operations are counted as bus accesses."/>
+ <event event="0x1d" title="Bus" name="Cycle" description="Bus cycle"/>
+ <event event="0x60" title="Bus" name="Read" description="Bus access, read"/>
+ <event event="0x61" title="Bus" name="Write" description="Bus access, write"/>
<event event="0x86" title="Exception" name="IRQ" description="IRQ exception taken"/>
<event event="0x87" title="Exception" name="FIQ" description="FIQ exception taken"/>
- <event event="0xC0" title="Memory" name="External request" description="External memory request"/>
- <event event="0xC1" title="Memory" name="Non-cacheable ext req" description="Non-cacheable external memory request"/>
- <event event="0xC2" title="Cache" name="Linefill" description="Linefill because of prefetch"/>
- <event event="0xC3" title="Cache" name="Linefill dropped" description="Prefetch linefill dropped"/>
- <event event="0xC4" title="Cache" name="Allocate mode enter" description="Entering read allocate mode"/>
- <event event="0xC5" title="Cache" name="Allocate mode" description="Read allocate mode"/>
- <event event="0xC7" title="ETM" name="ETM Ext Out[0]" description="ETM - ETM Ext Out[0]"/>
- <event event="0xC8" title="ETM" name="ETM Ext Out[1]" description="ETM - ETM Ext Out[1]"/>
- <event event="0xC9" title="Instruction" name="Pipeline stall" description="Data Write operation that stalls the pipeline because the store buffer is full"/>
- <event event="0xCA" title="Memory" name="Snoop" description="Data snooped from other processor. This event counts memory-read operations that read data from another processor within the local cluster, rather than accessing the L2 cache or issuing an external read."/>
+ <event event="0xc0" title="Memory" name="External request" description="External memory request"/>
+ <event event="0xc1" title="Memory" name="Non-cacheable ext req" description="Non-cacheable external memory request"/>
+ <event event="0xc2" title="Cache" name="Linefill" description="Linefill because of prefetch"/>
+ <event event="0xc3" title="Cache" name="Linefill dropped" description="Prefetch linefill dropped"/>
+ <event event="0xc4" title="Cache" name="Allocate mode enter" description="Entering read allocate mode"/>
+ <event event="0xc5" title="Cache" name="Allocate mode" description="Read allocate mode"/>
+ <event event="0xc7" title="ETM" name="ETM Ext Out[0]" description="ETM Ext Out[0]"/>
+ <event event="0xc8" title="ETM" name="ETM Ext Out[1]" description="ETM Ext Out[1]"/>
+ <event event="0xc9" title="Instruction" name="Pipeline stall" description="Data Write operation that stalls the pipeline because the store buffer is full"/>
+ <event event="0xca" title="Memory" name="Snoop" description="Data snooped from other processor. This event counts memory-read operations that read data from another processor within the local Cortex-A7 cluster, rather than accessing the L2 cache or issuing an external read. It increments on each transaction, rather than on each beat of data."/>
</category>
diff --git a/daemon/events-Cortex-A72.xml b/daemon/events-Cortex-A72.xml
index cdbc753..31c9cf3 100644
--- a/daemon/events-Cortex-A72.xml
+++ b/daemon/events-Cortex-A72.xml
@@ -32,8 +32,8 @@
<event event="0x46" title="Cache" name="L1 data victim" description="Level 1 data cache Write-back - Victim"/>
<event event="0x47" title="Cache" name="L1 data clean" description="Level 1 data cache Write-back - Cleaning and coherency"/>
<event event="0x48" title="Cache" name="L1 data invalidate" description="Level 1 data cache invalidate"/>
- <event event="0x4C" title="Cache" name="L1 data refill read" description="Level 1 data TLB refill - Read"/>
- <event event="0x4D" title="Cache" name="L1 data refill write" description="Level 1 data TLB refill - Write"/>
+ <event event="0x4C" title="Cache" name="L1 TLB refill read" description="Level 1 data TLB refill - Read"/>
+ <event event="0x4D" title="Cache" name="L1 TLB refill write" description="Level 1 data TLB refill - Write"/>
<event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access - Read"/>
<event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access - Write"/>
<event event="0x52" title="Cache" name="L2 data refill read" description="Level 2 data cache refill - Read"/>
@@ -63,9 +63,9 @@
<event event="0x75" title="Instruction" name="VFP" description="Operation speculatively executed - VFP"/>
<event event="0x76" title="Instruction" name="Software change" description="Operation speculatively executed - Software change of the PC"/>
<event event="0x77" title="Instruction" name="Crypto" description="Operation speculatively executed, crypto data processing"/>
- <event event="0x78" title="Instruction" name="Immediate branch" description="Branch speculatively executed - Immediate branch"/>
- <event event="0x79" title="Instruction" name="Procedure return" description="Branch speculatively executed - Procedure return"/>
- <event event="0x7A" title="Instruction" name="Indirect branch" description="Branch speculatively executed - Indirect branch"/>
+ <event event="0x78" title="Branch" name="Immediate" description="Branch speculatively executed - Immediate branch"/>
+ <event event="0x79" title="Procedure" name="Return" description="Branch speculatively executed - Procedure return"/>
+ <event event="0x7A" title="Branch" name="Indirect" description="Branch speculatively executed - Indirect branch"/>
<event event="0x7C" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
<event event="0x7D" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
<event event="0x7E" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
diff --git a/daemon/events-Cortex-A8.xml b/daemon/events-Cortex-A8.xml
index a69e25a..7056efd 100644
--- a/daemon/events-Cortex-A8.xml
+++ b/daemon/events-Cortex-A8.xml
@@ -2,23 +2,23 @@
<category name="Cortex-A8" counter_set="ARMv7_Cortex_A8_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARMv7_Cortex_A8_ccnt" event="0xff" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
- <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
- <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
- <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
- <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
- <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
- <event event="0x06" title="Instruction" name="Memory read" description="Memory-reading instruction architecturally executed"/>
- <event event="0x07" title="Instruction" name="Memory write" description="Memory-writing instruction architecturally executed"/>
- <event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
- <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
- <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
- <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
- <event event="0x0c" title="Branch" name="PC change" description="Software change of the Program Counter, except by an exception, architecturally executed"/>
- <event event="0x0d" title="Branch" name="Immediate" description="Immediate branch architecturally executed"/>
- <event event="0x0e" title="Procedure" name="Return" description="Procedure return, other than exception return, architecturally executed"/>
- <event event="0x0f" title="Memory" name="Unaligned access" description="Unaligned access architecturally executed"/>
- <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
- <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
+ <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill at the lowest level of instruction or unified cache. Each instruction fetch from normal cacheable memory that causes a refill from outside of the cache is counted. Accesses that do not cause a new cache refill, but are satisfied from refilling data of a previous miss are not counted. Where instruction fetches consist of multiple instructions, these accesses count as single events. CP15 cache maintenance operations do not count as events. This counter increments for speculative instruction fetches and for fetches of instructions that reach execution."/>
+ <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill at the lowest level of TLB. Each instruction fetch that causes a translation table walk or an access to another level of TLB caching is counted. CP15 TLB maintenance operations do not count as events. This counter increments for speculative instruction fetches and for fetches of instructions that reach execution."/>
+ <event event="0x03" title="Cache" name="Data refill" description="Data read or write operation that causes a refill at the lowest level of data or unified cache. Each data read from or write to normal cacheable memory that causes a refill from outside of the cache is counted. Accesses that do not cause a new cache refill, but are satisfied from refilling data of a previous miss are not counted. Each access to a cache line to normal cacheable memory that causes a new linefill is counted, including the multiple transaction of instructions such as LDM or STM, PUSH and POP. Write-through writes that hit in the cache do not cause a linefill and so are not counted. CP15 cache maintenance operations do not count as events. This counter increments for speculative data accesses and for data accesses that are explicitly made by instructions."/>
+ <event event="0x04" title="Cache" name="Data access" description="Data read or write operation that causes a cache access at the lowest level of data or unified cache. Each access to a cache line to normal cacheable memory is counted including the multiple transaction of instructions such as LDM or STM. CP15 cache maintenance operations do not count as events. This counter increments for speculative data accesses and for data accesses that are explicitly made by instructions."/>
+ <event event="0x05" title="Cache" name="Data TLB refill" description="Data read or write operation that causes a TLB refill at the lowest level of TLB. Each data read or write operation that causes a translation table walk or an access to another level of TLB caching is counted. CP15 TLB maintenance operations do not count as events. This counter increments for speculative data accesses and for data accesses that are explicitly made by instructions."/>
+ <event event="0x06" title="Instruction" name="Memory read" description="Data read architecturally executed. This counter increments for every instruction that explicitly read data, including SWP. This counter only increments for instructions that are unconditional or that pass their condition codes."/>
+ <event event="0x07" title="Instruction" name="Memory write" description="Data write architecturally executed. The counter increments for every instruction that explicitly wrote data, including SWP. This counter only increments for instructions that are unconditional or that pass their condition codes."/>
+ <event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed. This counter counts for all instructions, including conditional instructions that fail their condition codes."/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken. This counts for each exception taken."/>
+ <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed. This counter only increments for instructions that are unconditional or that pass their condition codes."/>
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the Context ID Register architecturally executed. This counter only increments for instructions that are unconditional or that pass their condition codes."/>
+ <event event="0x0c" title="Branch" name="PC change" description="Software change of PC, except by an exception, architecturally executed. This counter only increments for instructions that are unconditional or that pass their condition codes."/>
+ <event event="0x0d" title="Branch" name="Immediate" description="Immediate branch architecturally executed, taken or not taken. This includes B{L}, BLX, CB{N}Z, HB{L}, and HBLP. This counter counts for all immediate branch instructions that are architecturally executed, including conditional instructions that fail their condition codes."/>
+ <event event="0x0e" title="Procedure" name="Return" description="Procedure return, other than exception returns, architecturally executed. This counter only increments for instructions that are unconditional or that pass their condition codes."/>
+ <event event="0x0f" title="Memory" name="Unaligned access" description="Unaligned access architecturally executed. This counts each instruction that is an access to an unaligned address. This counter only increments for instructions that are unconditional or that pass their condition codes."/>
+ <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted. This counts for every pipeline flush because of a misprediction from the program flow prediction resources."/>
+ <event event="0x12" title="Branch" name="Potential prediction" description="Branches or other change in the program flow that could have been predicted by the branch prediction resources of the processor"/>
<event event="0x40" title="Cache" name="Write buffer full" description="Any write buffer full cycle"/>
<event event="0x41" title="Cache" name="L2 store" description="Any store that is merged in the L2 memory system"/>
<event event="0x42" title="Cache" name="Bufferable transaction" description="Any bufferable store transaction from load/store to L2 cache, excluding eviction or cast out data"/>
@@ -28,21 +28,21 @@
<event event="0x46" title="AXI" name="Write" description="The number of AXI write data transfers"/>
<event event="0x47" title="Memory" name="Replay event" description="Any replay event in the memory system"/>
<event event="0x48" title="Memory" name="Unaligned access replay" description="Any unaligned memory access that results in a replay"/>
- <event event="0x49" title="Cache" name="L1 data hash miss" description="Any L1 data memory access that misses in the cache as a result of the hashing algorithm"/>
- <event event="0x4a" title="Cache" name="L1 inst hash miss" description="Any L1 instruction memory access that misses in the cache as a result of the hashing algorithm"/>
- <event event="0x4b" title="Cache" name="L1 page coloring" description="Any L1 data memory access in which a page coloring alias occurs"/>
+ <event event="0x49" title="Cache" name="L1 data hash miss" description="Any L1 data memory access that misses in the cache as a result of the hashing algorithm. The cases covered are: hash hit and physical address miss, hash hit and physical address hit in another way and hash miss and physical address hit."/>
+ <event event="0x4a" title="Cache" name="L1 inst hash miss" description="Any L1 instruction memory access that misses in the cache as a result of the hashing algorithm. The cases covered are: hash hit and physical address miss, hash hit and physical address hit in another way and hash miss and physical address hit."/>
+ <event event="0x4b" title="Cache" name="L1 page coloring" description="Any L1 data memory access in which a page coloring alias occurs. alias = virtual address [12] ! = physical address [12]. This behavior results in a data memory eviction or cast out."/>
<event event="0x4c" title="NEON" name="L1 cache hit" description="Any NEON access that hits in the L1 data cache"/>
<event event="0x4d" title="NEON" name="L1 cache access" description="Any NEON cacheable data accesses for L1 data cache"/>
<event event="0x4e" title="NEON" name="L2 cache access" description="Any L2 cache accesses as a result of a NEON memory access"/>
<event event="0x4f" title="NEON" name="L2 cache hit" description="Any NEON hit in the L2 cache"/>
<event event="0x50" title="Cache" name="L1 inst access" description="Any L1 instruction cache access, excluding CP15 cache accesses"/>
<event event="0x51" title="Branch" name="Return stack misprediction" description="Any return stack misprediction because of incorrect target address for a taken return stack pop"/>
- <event event="0x52" title="Branch" name="Direction misprediction" description="Branch direction misprediction"/>
+ <event event="0x52" title="Branch" name="Direction misprediction" description="Two forms of branch direction misprediction: branch predicted taken, but was not taken and branch predicted not taken, but was taken"/>
<event event="0x53" title="Branch" name="Taken prediction" description="Any predictable branch that is predicted to be taken"/>
<event event="0x54" title="Branch" name="Executed and taken prediction" description="Any predictable branch that is executed and taken"/>
<event event="0x55" title="Core" name="Operations issued" description="Number of operations issued, where an operation is either: an instruction or one operation in a sequence of operations that make up a multi-cycle instruction"/>
<event event="0x56" title="Core" name="No issue cycles" description="Increment for every cycle that no instructions are available for issue"/>
- <event event="0x57" title="Core" name="Issue cycles" description="For every cycle, this event counts the number of instructions issued in that cycle. Multi-cycle instructions are only counted once"/>
+ <event event="0x57" title="Core" name="Issue cycles" description="For every cycle, this event counts the number of instructions issued in that cycle. Multi-cycle instructions are only counted once."/>
<event event="0x58" title="NEON" name="MRC data wait" description="Number of cycles the processor stalls waiting on MRC data from NEON"/>
<event event="0x59" title="NEON" name="Full queue" description="Number of cycles that the processor stalls as a result of a full NEON instruction queue or NEON load queue"/>
<event event="0x5a" title="NEON" name="Idle" description="Number of cycles that NEON and integer processors are both not idle"/>
diff --git a/daemon/events-Cortex-A9.xml b/daemon/events-Cortex-A9.xml
index 3e7f828..e17c03d 100644
--- a/daemon/events-Cortex-A9.xml
+++ b/daemon/events-Cortex-A9.xml
@@ -9,7 +9,7 @@
<event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
<event event="0x06" title="Instruction" name="Memory read" description="Memory-reading instruction architecturally executed"/>
<event event="0x07" title="Instruction" name="Memory write" description="Memory-writing instruction architecturally executed"/>
- <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken"/>
<event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
<event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
<event event="0x0c" title="Branch" name="PC change" description="Software change of the Program Counter, except by an exception, architecturally executed"/>
@@ -18,48 +18,48 @@
<event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
<event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
<event event="0x40" title="Java" name="Bytecode execute" description="Counts the number of Java bytecodes being decoded, including speculative ones"/>
- <event event="0x41" title="Java" name="SW bytecode execute" description="Counts the number of software java bytecodes being decoded, including speculative ones"/>
- <event event="0x42" title="Jazelle" name="Backward branch execute" description="Counts the number of Jazelle taken branches being executed"/>
- <event event="0x50" title="Cache" name="Coherency miss" description="Counts the number of coherent linefill requests performed by the Cortex-A9 processor which also miss in all the other Cortex-A9 processors, meaning that the request is sent to the external memory"/>
- <event event="0x51" title="Cache" name="Coherency hit" description="Counts the number of coherent linefill requests performed by the Cortex-A9 processor which hit in another Cortex-A9 processor, meaning that the linefill data is fetched directly from the relevant Cortex-A9 cache"/>
- <event event="0x60" title="Cache" name="Inst dependent stall" description="Counts the number of cycles where the processor is ready to accept new instructions, but does not receive any because of the instruction side not being able to provide any and the instruction cache is currently performing at least one linefill"/>
- <event event="0x61" title="Cache" name="Data dependent stall" description="Counts the number of cycles where the core has some instructions that it cannot issue to any pipeline, and the Load Store unit has at least one pending linefill request, and no pending TLB requests"/>
- <event event="0x62" title="Cache" name="TLB stall" description="Counts the number of cycles where the processor is stalled waiting for the completion of translation table walks from the main TLB"/>
+ <event event="0x41" title="Java" name="SW bytecode execute" description="Counts the number of software Java bytecodes being decoded, including speculative ones"/>
+ <event event="0x42" title="Jazelle" name="Backward branch execute" description="Counts the number of Jazelle taken branches being executed. This includes the branches that are flushed because of a previous load/store that aborts late."/>
+ <event event="0x50" title="Cache" name="Coherency miss" description="Counts the number of coherent linefill requests performed by the Cortex-A9 processor that also miss in all the other Cortex-A9 processors. This means that the request is sent to the external memory."/>
+ <event event="0x51" title="Cache" name="Coherency hit" description="Counts the number of coherent linefill requests performed by the Cortex-A9 processor that hit in another Cortex-A9 processor. This means that the linefill data is fetched directly from the relevant Cortex-A9 cache."/>
+ <event event="0x60" title="Cache" name="Inst dependent stall" description="Counts the number of cycles where the processor: is ready to accept new instructions, does not receive a new instruction, because: the instruction side is unable to provide one or the instruction cache is performing at least one linefill"/>
+ <event event="0x61" title="Cache" name="Data dependent stall" description="Counts the number of cycles where the processor has some instructions that it cannot issue to any pipeline, and the Load Store unit has at least one pending linefill request, and no pending TLB requests"/>
+ <event event="0x62" title="Cache" name="TLB stall" description="Counts the number of cycles where the processor is stalled waiting for the completion of translation table walks from the main TLB. The processor stalls because the instruction side is not able to provide the instructions, or the data side is not able to provide the necessary data."/>
<event event="0x63" title="Intrinsic" name="STREX pass" description="Counts the number of STREX instructions architecturally executed and passed"/>
<event event="0x64" title="Intrinsic" name="STREX fail" description="Counts the number of STREX instructions architecturally executed and failed"/>
<event event="0x65" title="Cache" name="Data eviction" description="Counts the number of eviction requests because of a linefill in the data cache"/>
<event event="0x66" title="Pipeline" name="Issue stage no dispatch" description="Counts the number of cycles where the issue stage does not dispatch any instruction because it is empty or cannot dispatch any instructions"/>
<event event="0x67" title="Pipeline" name="Issue stage empty" description="Counts the number of cycles where the issue stage is empty"/>
- <event event="0x68" title="Instruction" name="Executed" description="Counts the number of instructions going through the Register Renaming stage. This number is an approximate number of the total number of instructions speculatively executed, and even more approximate of the total number of instructions architecturally executed"/>
- <event event="0x69" title="Cache" name="Data linefills" description="Counts the number of linefills performed on the external AXI bus"/>
- <event event="0x6A" title="Cache" name="Prefetch linefills" description="Counts the number of data linefills caused by prefetcher requests"/>
- <event event="0x6B" title="Cache" name="Prefetch hits" description="Counts the number of cache hits in a line that belongs to a stream followed by the prefetcher"/>
- <event event="0x6E" title="Core" name="Functions" description="Counts the number of procedure returns whose condition codes do not fail, excluding all returns from exception"/>
- <event event="0x70" title="Instruction" name="Main execution unit" description="Counts the number of instructions being executed in the main execution pipeline of the processor, the multiply pipeline and arithmetic logic unit pipeline"/>
- <event event="0x71" title="Instruction" name="Second execution unit" description="Counts the number of instructions being executed in the processor second execution pipeline (ALU)"/>
- <event event="0x72" title="Instruction" name="Load/Store" description="Counts the number of instructions being executed in the Load/Store unit"/>
- <event event="0x73" title="Instruction" name="Floating point" description="Counts the number of Floating-point instructions going through the Register Rename stage"/>
- <event event="0x74" title="Instruction" name="NEON" description="Counts the number of NEON instructions going through the Register Rename stage"/>
+ <event event="0x68" title="Instruction" name="Executed" description="Counts the number of instructions going through the Register Renaming stage. This number is an approximate number of the total number of instructions speculatively executed, and an even more approximate number of the total number of instructions architecturally executed. The approximation depends mainly on the branch misprediction rate."/>
+ <event event="0x69" title="Cache" name="Data linefills" description="Counts the number of linefills performed on the external AXI bus. This event counts all data linefill requests, caused by: loads, including speculative ones, stores, PLD, prefetch or page table walk."/>
+ <event event="0x6a" title="Cache" name="Prefetch linefills" description="Counts the number of data linefills caused by prefetcher requests"/>
+ <event event="0x6b" title="Cache" name="Prefetch hits" description="Counts the number of cache hits in a line that belongs to a stream followed by the prefetcher. This includes: lines that have been prefetched by the automatic data prefetcher and lines already present in the cache, before the prefetcher action."/>
+ <event event="0x6e" title="Procedure" name="Return" description="Counts the number of procedure returns whose condition codes do not fail, excluding all returns from exception. This count includes procedure returns that are flushed because of a previous load/store that aborts late."/>
+ <event event="0x70" title="Instruction" name="Main execution unit" description="Counts the number of instructions being executed in the main execution pipeline of the processor, the multiply pipeline and arithmetic logic unit pipeline. The counted instructions are still speculative."/>
+ <event event="0x71" title="Instruction" name="Second execution unit" description="Counts the number of instructions being executed in the processor second execution pipeline (ALU). The counted instructions are still speculative."/>
+ <event event="0x72" title="Instruction" name="Load/Store" description="Counts the number of instructions being executed in the Load/Store unit. The counted instructions are still speculative."/>
+ <event event="0x73" title="Instruction" name="Floating point" description="Counts the number of floating-point instructions going through the Register Rename stage. Instructions are still speculative in this stage."/>
+ <event event="0x74" title="Instruction" name="NEON" description="Counts the number of NEON instructions going through the Register Rename stage. Instructions are still speculative in this stage."/>
<event event="0x80" title="Stalls" name="PLD" description="Counts the number of cycles where the processor is stalled because PLD slots are all full"/>
- <event event="0x81" title="Stalls" name="Memory write" description="Counts the number of cycles when the processor is stalled and the data side is stalled too because it is full and executing writes to the external memory"/>
+ <event event="0x81" title="Stalls" name="Memory write" description="Counts the number of cycles when the processor is stalled. The data side is stalled also, because it is full and executes writes to the external memory."/>
<event event="0x82" title="Stalls" name="Inst main TLB miss" description="Counts the number of stall cycles because of main TLB misses on requests issued by the instruction side"/>
<event event="0x83" title="Stalls" name="Data main TLB miss" description="Counts the number of stall cycles because of main TLB misses on requests issued by the data side"/>
- <event event="0x84" title="Stalls" name="Inst micro TLB miss" description="Counts the number of stall cycles because of micro TLB misses on the instruction side"/>
- <event event="0x85" title="Stalls" name="Data micro TLB miss" description="Counts the number of stall cycles because of micro TLB misses on the data side"/>
- <event event="0x86" title="Stalls" name="DMB" description="Counts the number of stall cycles because of the execution of a DMB memory barrier"/>
- <event event="0x8A" title="Clock" name="Integer core" description="Counts the number of cycles during which the integer core clock is enabled"/>
- <event event="0x8B" title="Clock" name="Data engine" description="Counts the number of cycles during which the Data Engine clock is enabled"/>
- <event event="0x8C" title="Clock" name="NEON" description="Counts the number of cycles when the NEON SIMD clock is enabled"/>
- <event event="0x8D" title="Memory" name="TLB inst allocations" description="Counts the number of TLB allocations because of Instruction requests"/>
- <event event="0x8E" title="Memory" name="TLB data allocations" description="Counts the number of TLB allocations because of Data requests"/>
+ <event event="0x84" title="Stalls" name="Inst micro TLB miss" description="Counts the number of stall cycles because of micro TLB misses on the instruction side. This event does not include main TLB miss stall cycles that are already counted in the corresponding main TLB event."/>
+ <event event="0x85" title="Stalls" name="Data micro TLB miss" description="Counts the number of stall cycles because of micro TLB misses on the data side. This event does not include main TLB miss stall cycles that are already counted in the corresponding main TLB event."/>
+ <event event="0x86" title="Stalls" name="DMB" description="Counts the number of stall cycles because of the execution of a DMB. This includes all DMB instructions being executed, even speculatively."/>
+ <event event="0x8a" title="Clock" name="Integer core" description="Counts the number of cycles when the integer core clock is enabled"/>
+ <event event="0x8b" title="Clock" name="Data engine" description="Counts the number of cycles when the data engine clock is enabled"/>
+ <event event="0x8c" title="Clock" name="NEON" description="Counts the number of cycles when the NEON SIMD clock is enabled"/>
+ <event event="0x8d" title="Memory" name="TLB inst allocations" description="Counts the number of TLB allocations because of Instruction requests"/>
+ <event event="0x8e" title="Memory" name="TLB data allocations" description="Counts the number of TLB allocations because of Data requests"/>
<event event="0x90" title="Instruction" name="ISB" description="Counts the number of ISB instructions architecturally executed"/>
<event event="0x91" title="Instruction" name="DSB" description="Counts the number of DSB instructions architecturally executed"/>
<event event="0x92" title="Instruction" name="DMB" description="Counts the number of DMB instructions speculatively executed"/>
<event event="0x93" title="External" name="Interrupts" description="Counts the number of external interrupts executed by the processor"/>
- <event event="0xA0" title="PLE" name="Cache line rq completed" description="Counts the number of PLE cache line requests completed"/>
- <event event="0xA1" title="PLE" name="Cache line rq skipped" description="Counts the number of PLE cache line requests skipped"/>
- <event event="0xA2" title="PLE" name="FIFO flush" description="Counts the number of PLE FIFO flush requests"/>
- <event event="0xA3" title="PLE" name="Request completed" description="Counts the number of PLE FIFO flush completed"/>
- <event event="0xA4" title="PLE" name="FIFO overflow" description="Counts the number of PLE FIFO flush overflowed"/>
- <event event="0xA5" title="PLE" name="Request programmed" description="Counts the number of PLE FIFO flush program requests"/>
+ <event event="0xa0" title="PLE" name="Cache line rq completed" description="Counts the number of PLE cache line requests completed"/>
+ <event event="0xa1" title="PLE" name="Cache line rq skipped" description="Counts the number of PLE cache line requests skipped"/>
+ <event event="0xa2" title="PLE" name="FIFO flush" description="Counts the number of PLE FIFO flush requests"/>
+ <event event="0xa3" title="PLE" name="Request completed" description="Counts the number of PLE FIFO flush completed"/>
+ <event event="0xa4" title="PLE" name="FIFO overflow" description="Counts the number of PLE FIFO flush overflowed"/>
+ <event event="0xa5" title="PLE" name="Request programmed" description="Counts the number of PLE FIFO flush program requests"/>
</category>
diff --git a/daemon/events-Filesystem.xml b/daemon/events-Filesystem.xml
index 9ef61dd..1fa3b3b 100644
--- a/daemon/events-Filesystem.xml
+++ b/daemon/events-Filesystem.xml
@@ -1,8 +1,7 @@
<category name="Filesystem">
<!-- counter attribute must start with filesystem_ and be unique -->
- <!-- regex item in () is the value shown -->
+ <!-- regex item in () is the value shown or, if the parentheses are missing, the number of times the regex matches is counted -->
<!--
- <event counter="filesystem_cpu1_online" path="/sys/devices/system/cpu/cpu1/online" title="online" name="cpu 1" class="absolute" description="If cpu 1 is online"/>
<event counter="filesystem_loginuid" path="/proc/self/loginuid" title="loginuid" name="loginuid" class="absolute" description="loginuid"/>
<event counter="filesystem_gatord_rss" path="/proc/self/stat" title="stat" name="rss" class="absolute" regex="-?[0-9]+ \(.*\) . -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ (-?[0-9]+)" units="pages" description="resident set size"/>
<event counter="filesystem_processes" path="/proc/stat" title="proc-stat" name="processes" class="absolute" regex="processes ([0-9]+)" description="Number of processes and threads created"/>
diff --git a/daemon/events-L2C-310.xml b/daemon/events-L2C-310.xml
index 923fb90..055847c 100644
--- a/daemon/events-L2C-310.xml
+++ b/daemon/events-L2C-310.xml
@@ -10,8 +10,8 @@
<event event="0x8" title="L2 Cache" name="Instruction Read Request" description="Instruction read lookup to the L2 cache. Subsequently results in a hit or miss"/>
<event event="0x9" title="L2 Cache" name="Write Allocate Miss" description="Allocation into the L2 cache caused by a write, with Write-Allocate attribute, miss"/>
<event event="0xa" title="L2 Cache" name="Internal Prefetch Allocate" description="Allocation of a prefetch generated by L2C-310 into the L2 cache"/>
- <event event="0xb" title="L2 Cache" name="Prefitch Hit" description="Prefetch hint hits in the L2 cache"/>
- <event event="0xc" title="L2 Cache" name="Prefitch Allocate" description="Prefetch hint allocated into the L2 cache"/>
+ <event event="0xb" title="L2 Cache" name="Prefetch Hit" description="Prefetch hint hits in the L2 cache"/>
+ <event event="0xc" title="L2 Cache" name="Prefetch Allocate" description="Prefetch hint allocated into the L2 cache"/>
<event event="0xd" title="L2 Cache" name="Speculative Read Received" description="Speculative read received"/>
<event event="0xe" title="L2 Cache" name="Speculative Read Confirmed" description="Speculative read confirmed"/>
<event event="0xf" title="L2 Cache" name="Prefetch Hint Received" description="Prefetch hint received"/>
diff --git a/daemon/events-Linux.xml b/daemon/events-Linux.xml
index 62a7018..0350c0c 100644
--- a/daemon/events-Linux.xml
+++ b/daemon/events-Linux.xml
@@ -11,7 +11,7 @@
<event counter="Linux_meminfo_memfree" title="Memory" name="Free" class="absolute" display="minimum" units="B" description="Available memory size"/>
<event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" class="absolute" units="B" description="Memory used by OS disk buffers"/>
<event counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" class="absolute" units="Hz" series_composition="overlay" average_cores="yes" description="Frequency setting of the CPU"/>
- <event counter="Linux_cpu_wait_contention" title="CPU Contention" name="Wait" per_cpu="no" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" modifier="10000" color="0x003c96fb" description="One or more threads are runnable but waiting due to CPU contention"/>
- <event counter="Linux_cpu_wait_io" title="CPU I/O" name="Wait" per_cpu="no" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" modifier="10000" color="0x00b30000" description="One or more threads are blocked on an I/O resource"/>
+ <event counter="Linux_cpu_wait_contention" title="CPU Contention" name="Wait" per_cpu="no" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" multiplier="0.0001" color="0x003c96fb" description="One or more threads are runnable but waiting due to CPU contention"/>
+ <event counter="Linux_cpu_wait_io" title="CPU I/O" name="Wait" per_cpu="no" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" multiplier="0.0001" color="0x00b30000" description="One or more threads are blocked on an I/O resource"/>
<event counter="Linux_power_cpu" title="CPU Status" name="Activity" class="activity" activity1="Off" activity_color1="0x0000ff00" activity2="WFI" activity_color2="0x000000ff" rendering_type="bar" average_selection="yes" average_cores="yes" percentage="yes" description="CPU Status"/>
</category>
diff --git a/daemon/events-Mali-4xx.xml b/daemon/events-Mali-4xx.xml
index 0a95dfe..801dd28 100644
--- a/daemon/events-Mali-4xx.xml
+++ b/daemon/events-Mali-4xx.xml
@@ -200,9 +200,9 @@
<event counter="ARM_Mali-4xx_Voltage" title="Mali GPU Voltage" name="Voltage" class="absolute" display="average" average_selection="yes" units="mV" description="GPU core voltage."/>
</category>
<category name="ARM_Mali-4xx_Frequency" per_cpu="no">
- <event counter="ARM_Mali-4xx_Frequency" title="Mali GPU Frequency" name="Frequency" display="average" average_selection="yes" units="MHz" description="GPU core frequency."/>
+ <event counter="ARM_Mali-4xx_Frequency" title="Mali GPU Frequency" name="Frequency" class="absolute" display="average" average_selection="yes" units="MHz" description="GPU core frequency."/>
</category>
- <category name="Mali-4xx Activity" counter_set="ARM_Mali-4xx_Activity_cnt">
+ <category name="Mali-4xx Activity" counter_set="ARM_Mali-4xx_Activity_cnt" per_cpu="yes">
<event counter="ARM_Mali-4xx_fragment" title="GPU Fragment" name="Activity" class="activity" activity1="Activity" activity_color1="0x00006fcc" rendering_type="bar" average_selection="yes" average_cores="yes" percentage="yes" description="GPU Fragment Activity"/>
<event counter="ARM_Mali-4xx_vertex" title="GPU Vertex" name="Activity" class="activity" activity1="Activity" activity_color1="0x00eda000" rendering_type="bar" average_selection="yes" percentage="yes" description="GPU Vertex Activity"/>
</category>
diff --git a/daemon/events-Mali-Midgard.xml b/daemon/events-Mali-Midgard.xml
index b6ab4b8..33c1a40 100644
--- a/daemon/events-Mali-Midgard.xml
+++ b/daemon/events-Mali-Midgard.xml
@@ -1,6 +1,8 @@
<category name="Mali-Midgard Software Counters" per_cpu="no">
<event counter="ARM_Mali-Midgard_TOTAL_ALLOC_PAGES" title="Mali Total Alloc Pages" name="Total number of allocated pages" description="Mali total number of allocated pages."/>
</category>
+<!--
+power management is disabled during profiling so these counters are not useful as they always return zero
<category name="Mali-Midgard PM Shader" per_cpu="no">
<event counter="ARM_Mali-Midgard_PM_SHADER_0" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 0" description="Mali PM Shader: PM Shader Core 0."/>
<event counter="ARM_Mali-Midgard_PM_SHADER_1" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 1" description="Mali PM Shader: PM Shader Core 1."/>
@@ -12,17 +14,18 @@
<event counter="ARM_Mali-Midgard_PM_SHADER_7" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 7" description="Mali PM Shader: PM Shader Core 7."/>
</category>
<category name="Mali-Midgard PM Tiler" per_cpu="no">
- <event counter="ARM_Mali-Midgard_PM_TILER_0" display="average" average_selection="yes" percentage="yes" title="Mali PM Tiler" name="PM Tiler Core 0" description="Mali PM Tiler: PM Tiler Core 0."/>
+ <event counter="ARM_Mali-Midgard_PM_TILER_0" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Tiler" name="PM Tiler Core 0" description="Mali PM Tiler: PM Tiler Core 0."/>
</category>
<category name="Mali-Midgard PM L2" per_cpu="no">
- <event counter="ARM_Mali-Midgard_PM_L2_0" display="average" average_selection="yes" percentage="yes" title="Mali PM L2" name="PM L2 Core 0" description="Mali PM L2: PM L2 Core 0."/>
- <event counter="ARM_Mali-Midgard_PM_L2_1" display="average" average_selection="yes" percentage="yes" title="Mali PM L2" name="PM L2 Core 1" description="Mali PM L2: PM L2 Core 1."/>
+ <event counter="ARM_Mali-Midgard_PM_L2_0" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM L2" name="PM L2 Core 0" description="Mali PM L2: PM L2 Core 0."/>
+ <event counter="ARM_Mali-Midgard_PM_L2_1" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM L2" name="PM L2 Core 1" description="Mali PM L2: PM L2 Core 1."/>
</category>
+-->
<category name="Mali-Midgard MMU Address Space" per_cpu="no">
- <event counter="ARM_Mali-Midgard_MMU_AS_0" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 0" description="Mali MMU Address Space 0 usage."/>
- <event counter="ARM_Mali-Midgard_MMU_AS_1" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 1" description="Mali MMU Address Space 1 usage."/>
- <event counter="ARM_Mali-Midgard_MMU_AS_2" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 2" description="Mali MMU Address Space 2 usage."/>
- <event counter="ARM_Mali-Midgard_MMU_AS_3" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 3" description="Mali MMU Address Space 3 usage."/>
+ <event counter="ARM_Mali-Midgard_MMU_AS_0" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 0" description="Mali MMU Address Space 0 usage."/>
+ <event counter="ARM_Mali-Midgard_MMU_AS_1" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 1" description="Mali MMU Address Space 1 usage."/>
+ <event counter="ARM_Mali-Midgard_MMU_AS_2" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 2" description="Mali MMU Address Space 2 usage."/>
+ <event counter="ARM_Mali-Midgard_MMU_AS_3" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 3" description="Mali MMU Address Space 3 usage."/>
</category>
<category name="Mali-Midgard MMU Page Fault" per_cpu="no">
<event counter="ARM_Mali-Midgard_MMU_PAGE_FAULT_0" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 0" description="Reports the number of newly allocated pages after a MMU page fault in address space 0."/>
diff --git a/daemon/events-Mali-Midgard_hw.xml b/daemon/events-Mali-Midgard_hw.xml
index 4f3323f..e8f0cb0 100644
--- a/daemon/events-Mali-Midgard_hw.xml
+++ b/daemon/events-Mali-Midgard_hw.xml
@@ -1,15 +1,18 @@
+<!-- this file is valid for Midgard r4p0 and earlier and replaced with the core-specific files in r5p0 -->
<category name="Mali-Midgard Job Manager" per_cpu="no">
<event counter="ARM_Mali-Midgard_GPU_ACTIVE" title="Mali Job Manager Cycles" name="GPU cycles" description="Number of cycles the GPU was active"/>
<event counter="ARM_Mali-Midgard_IRQ_ACTIVE" title="Mali Job Manager Cycles" name="IRQ cycles" description="Number of cycles the GPU had a pending interrupt"/>
<event counter="ARM_Mali-Midgard_JS0_ACTIVE" title="Mali Job Manager Cycles" name="JS0 cycles" description="Number of cycles JS0 (fragment) was active"/>
<event counter="ARM_Mali-Midgard_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) was active"/>
<event counter="ARM_Mali-Midgard_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) was active"/>
- <event counter="ARM_Mali-Midgard_JS0_JOBS" title="Mali Job Manager Work" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
- <event counter="ARM_Mali-Midgard_JS0_TASKS" title="Mali Job Manager Work" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
- <event counter="ARM_Mali-Midgard_JS1_JOBS" title="Mali Job Manager Work" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
- <event counter="ARM_Mali-Midgard_JS1_TASKS" title="Mali Job Manager Work" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
- <event counter="ARM_Mali-Midgard_JS2_TASKS" title="Mali Job Manager Work" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
- <event counter="ARM_Mali-Midgard_JS2_JOBS" title="Mali Job Manager Work" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-Midgard_JS0_JOBS" title="Mali Job Manager Jobs" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
+ <event counter="ARM_Mali-Midgard_JS1_JOBS" title="Mali Job Manager Jobs" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
+ <event counter="ARM_Mali-Midgard_JS2_JOBS" title="Mali Job Manager Jobs" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-Midgard_JS0_TASKS" title="Mali Job Manager Tasks" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
+ <event counter="ARM_Mali-Midgard_JS1_TASKS" title="Mali Job Manager Tasks" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
+ <event counter="ARM_Mali-Midgard_JS2_TASKS" title="Mali Job Manager Tasks" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
</category>
<category name="Mali-Midgard Tiler" per_cpu="no">
<event counter="ARM_Mali-Midgard_POLYGONS" title="Mali Tiler Primitives" name="Polygons" description="Number of polygons processed"/>
@@ -17,11 +20,13 @@
<event counter="ARM_Mali-Midgard_TRIANGLES" title="Mali Tiler Primitives" name="Triangles" description="Number of triangles processed"/>
<event counter="ARM_Mali-Midgard_LINES" title="Mali Tiler Primitives" name="Lines" description="Number of lines processed"/>
<event counter="ARM_Mali-Midgard_POINTS" title="Mali Tiler Primitives" name="Points" description="Number of points processed"/>
+
<event counter="ARM_Mali-Midgard_FRONT_FACING" title="Mali Tiler Culling" name="Front facing prims" description="Number of front facing primitives"/>
<event counter="ARM_Mali-Midgard_BACK_FACING" title="Mali Tiler Culling" name="Back facing prims" description="Number of back facing primitives"/>
<event counter="ARM_Mali-Midgard_PRIM_VISIBLE" title="Mali Tiler Culling" name="Visible prims" description="Number of visible primitives"/>
<event counter="ARM_Mali-Midgard_PRIM_CULLED" title="Mali Tiler Culling" name="Culled prims" description="Number of culled primitives"/>
<event counter="ARM_Mali-Midgard_PRIM_CLIPPED" title="Mali Tiler Culling" name="Clipped prims" description="Number of clipped primitives"/>
+
<event counter="ARM_Mali-Midgard_LEVEL0" title="Mali Tiler Hierarchy" name="L0 prims" description="Number of primitives in hierarchy level 0"/>
<event counter="ARM_Mali-Midgard_LEVEL1" title="Mali Tiler Hierarchy" name="L1 prims" description="Number of primitives in hierarchy level 1"/>
<event counter="ARM_Mali-Midgard_LEVEL2" title="Mali Tiler Hierarchy" name="L2 prims" description="Number of primitives in hierarchy level 2"/>
@@ -30,62 +35,64 @@
<event counter="ARM_Mali-Midgard_LEVEL5" title="Mali Tiler Hierarchy" name="L5 prims" description="Number of primitives in hierarchy level 5"/>
<event counter="ARM_Mali-Midgard_LEVEL6" title="Mali Tiler Hierarchy" name="L6 prims" description="Number of primitives in hierarchy level 6"/>
<event counter="ARM_Mali-Midgard_LEVEL7" title="Mali Tiler Hierarchy" name="L7 prims" description="Number of primitives in hierarchy level 7"/>
- <event counter="ARM_Mali-Midgard_COMMAND_1" title="Mali Tiler Commands" name="Prims in 1 command" description="Number of primitives producing 1 command"/>
- <event counter="ARM_Mali-Midgard_COMMAND_2" title="Mali Tiler Commands" name="Prims in 2 command" description="Number of primitives producing 2 commands"/>
- <event counter="ARM_Mali-Midgard_COMMAND_3" title="Mali Tiler Commands" name="Prims in 3 command" description="Number of primitives producing 3 commands"/>
- <event counter="ARM_Mali-Midgard_COMMAND_4" title="Mali Tiler Commands" name="Prims in 4 command" description="Number of primitives producing 4 commands"/>
- <event counter="ARM_Mali-Midgard_COMMAND_4_7" title="Mali Tiler Commands" name="Prims in 4-7 commands" description="Number of primitives producing 4-7 commands"/>
- <event counter="ARM_Mali-Midgard_COMMAND_5_7" title="Mali Tiler Commands" name="Prims in 5-7 commands" description="Number of primitives producing 5-7 commands"/>
- <event counter="ARM_Mali-Midgard_COMMAND_8_15" title="Mali Tiler Commands" name="Prims in 8-15 commands" description="Number of primitives producing 8-15 commands"/>
- <event counter="ARM_Mali-Midgard_COMMAND_16_63" title="Mali Tiler Commands" name="Prims in 16-63 commands" description="Number of primitives producing 16-63 commands"/>
- <event counter="ARM_Mali-Midgard_COMMAND_64" title="Mali Tiler Commands" name="Prims in &gt;= 64 commands" description="Number of primitives producing &gt;= 64 commands"/>
</category>
<category name="Mali-Midgard Shader Core" per_cpu="no">
<event counter="ARM_Mali-Midgard_TRIPIPE_ACTIVE" title="Mali Core Cycles" name="Tripipe cycles" description="Number of cycles the Tripipe was active"/>
<event counter="ARM_Mali-Midgard_FRAG_ACTIVE" title="Mali Core Cycles" name="Fragment cycles" description="Number of cycles fragment processing was active"/>
<event counter="ARM_Mali-Midgard_COMPUTE_ACTIVE" title="Mali Core Cycles" name="Compute cycles" description="Number of cycles vertex\compute processing was active"/>
<event counter="ARM_Mali-Midgard_FRAG_CYCLE_NO_TILE" title="Mali Core Cycles" name="Fragment cycles waiting for tile" description="Number of cycles spent waiting for a physical tile buffer"/>
+
<event counter="ARM_Mali-Midgard_FRAG_THREADS" title="Mali Core Threads" name="Fragment threads" description="Number of fragment threads started"/>
<event counter="ARM_Mali-Midgard_FRAG_DUMMY_THREADS" title="Mali Core Threads" name="Dummy fragment threads" description="Number of dummy fragment threads started"/>
- <event counter="ARM_Mali-Midgard_FRAG_QUADS_LZS_TEST" title="Mali Core Threads" name="Frag threads doing late ZS" description="Number of threads doing late ZS test"/>
- <event counter="ARM_Mali-Midgard_FRAG_QUADS_LZS_KILLED" title="Mali Core Threads" name="Frag threads killed late ZS" description="Number of threads killed by late ZS test"/>
+ <event counter="ARM_Mali-Midgard_FRAG_QUADS_LZS_TEST" title="Mali Core Threads" name="Frag threads doing late ZS quads" description="Number of threads doing late ZS test"/>
+ <event counter="ARM_Mali-Midgard_FRAG_QUADS_LZS_KILLED" title="Mali Core Threads" name="Frag threads killed late ZS quads" description="Number of threads killed by late ZS test"/>
<event counter="ARM_Mali-Midgard_FRAG_THREADS_LZS_TEST" title="Mali Core Threads" name="Frag threads doing late ZS" description="Number of threads doing late ZS test"/>
<event counter="ARM_Mali-Midgard_FRAG_THREADS_LZS_KILLED" title="Mali Core Threads" name="Frag threads killed late ZS" description="Number of threads killed by late ZS test"/>
+
<event counter="ARM_Mali-Midgard_COMPUTE_TASKS" title="Mali Compute Threads" name="Compute tasks" description="Number of compute tasks"/>
<event counter="ARM_Mali-Midgard_COMPUTE_THREADS" title="Mali Compute Threads" name="Compute threads started" description="Number of compute threads started"/>
<event counter="ARM_Mali-Midgard_COMPUTE_CYCLES_DESC" title="Mali Compute Threads" name="Compute cycles awaiting descriptors" description="Number of compute cycles spent waiting for descriptors"/>
+
<event counter="ARM_Mali-Midgard_FRAG_PRIMATIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/>
<event counter="ARM_Mali-Midgard_FRAG_PRIMATIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/>
<event counter="ARM_Mali-Midgard_FRAG_PRIMITIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/>
<event counter="ARM_Mali-Midgard_FRAG_PRIMITIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/>
+
<event counter="ARM_Mali-Midgard_FRAG_QUADS_RAST" title="Mali Fragment Quads" name="Quads rasterized" description="Number of quads rasterized"/>
<event counter="ARM_Mali-Midgard_FRAG_QUADS_EZS_TEST" title="Mali Fragment Quads" name="Quads doing early ZS" description="Number of quads doing early ZS test"/>
<event counter="ARM_Mali-Midgard_FRAG_QUADS_EZS_KILLED" title="Mali Fragment Quads" name="Quads killed early Z" description="Number of quads killed by early ZS test"/>
+
<event counter="ARM_Mali-Midgard_FRAG_NUM_TILES" title="Mali Fragment Tasks" name="Tiles rendered" description="Number of tiles rendered"/>
<event counter="ARM_Mali-Midgard_FRAG_TRANS_ELIM" title="Mali Fragment Tasks" name="Tile writes killed by TE" description="Number of tile writes skipped by transaction elimination"/>
+
<event counter="ARM_Mali-Midgard_ARITH_WORDS" title="Mali Arithmetic Pipe" name="A instructions" description="Number of instructions completed by the the A-pipe (normalized per pipeline)"/>
+
<event counter="ARM_Mali-Midgard_LS_WORDS" title="Mali Load/Store Pipe" name="LS instructions" description="Number of instructions completed by the LS-pipe"/>
<event counter="ARM_Mali-Midgard_LS_ISSUES" title="Mali Load/Store Pipe" name="LS instruction issues" description="Number of instructions issued to the LS-pipe, including restarts"/>
+
<event counter="ARM_Mali-Midgard_TEX_WORDS" title="Mali Texture Pipe" name="T instructions" description="Number of instructions completed by the T-pipe"/>
<event counter="ARM_Mali-Midgard_TEX_THREADS" title="Mali Texture Pipe" name="T instruction issues" description="Number of instructions issused to the T-pipe, including restarts"/>
<event counter="ARM_Mali-Midgard_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/>
- <event counter="ARM_Mali-Midgard_LSC_READ_HITS" title="Mali Load/Store Cache" name="Read hits" description="Number of read hits in the Load/Store cache"/>
- <event counter="ARM_Mali-Midgard_LSC_READ_MISSES" title="Mali Load/Store Cache" name="Read misses" description="Number of read misses in the Load/Store cache"/>
- <event counter="ARM_Mali-Midgard_LSC_WRITE_HITS" title="Mali Load/Store Cache" name="Write hits" description="Number of write hits in the Load/Store cache"/>
- <event counter="ARM_Mali-Midgard_LSC_WRITE_MISSES" title="Mali Load/Store Cache" name="Write misses" description="Number of write misses in the Load/Store cache"/>
- <event counter="ARM_Mali-Midgard_LSC_ATOMIC_HITS" title="Mali Load/Store Cache" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
- <event counter="ARM_Mali-Midgard_LSC_ATOMIC_MISSES" title="Mali Load/Store Cache" name="Atomic misses" description="Number of atomic misses in the Load/Store cache"/>
- <event counter="ARM_Mali-Midgard_LSC_LINE_FETCHES" title="Mali Load/Store Cache" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
- <event counter="ARM_Mali-Midgard_LSC_DIRTY_LINE" title="Mali Load/Store Cache" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
- <event counter="ARM_Mali-Midgard_LSC_SNOOPS" title="Mali Load/Store Cache" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
+
+ <event counter="ARM_Mali-Midgard_LSC_READ_HITS" title="Mali Load/Store Cache Reads" name="Read hits" description="Number of read hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-Midgard_LSC_READ_MISSES" title="Mali Load/Store Cache Reads" name="Read misses" description="Number of read misses in the Load/Store cache"/>
+ <event counter="ARM_Mali-Midgard_LSC_WRITE_HITS" title="Mali Load/Store Cache Writes" name="Write hits" description="Number of write hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-Midgard_LSC_WRITE_MISSES" title="Mali Load/Store Cache Writes" name="Write misses" description="Number of write misses in the Load/Store cache"/>
+ <event counter="ARM_Mali-Midgard_LSC_ATOMIC_HITS" title="Mali Load/Store Cache Atomics" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-Midgard_LSC_ATOMIC_MISSES" title="Mali Load/Store Cache Atomics" name="Atomic misses" description="Number of atomic misses in the Load/Store cache"/>
+ <event counter="ARM_Mali-Midgard_LSC_LINE_FETCHES" title="Mali Load/Store Cache Bus" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
+ <event counter="ARM_Mali-Midgard_LSC_DIRTY_LINE" title="Mali Load/Store Cache Bus" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
+ <event counter="ARM_Mali-Midgard_LSC_SNOOPS" title="Mali Load/Store Cache Bus" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
</category>
<category name="Mali-Midgard L2 and MMU" per_cpu="no">
- <event counter="ARM_Mali-Midgard_L2_WRITE_BEATS" title="Mali L2 Cache" name="External write beats" description="Number of external bus write beats"/>
- <event counter="ARM_Mali-Midgard_L2_READ_BEATS" title="Mali L2 Cache" name="External read beats" description="Number of external bus read beats"/>
- <event counter="ARM_Mali-Midgard_L2_READ_SNOOP" title="Mali L2 Cache" name="Read snoops" description="Number of read transaction snoops"/>
- <event counter="ARM_Mali-Midgard_L2_READ_HIT" title="Mali L2 Cache" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
- <event counter="ARM_Mali-Midgard_L2_WRITE_SNOOP" title="Mali L2 Cache" name="Write snoops" description="Number of write transaction snoops"/>
- <event counter="ARM_Mali-Midgard_L2_WRITE_HIT" title="Mali L2 Cache" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
- <event counter="ARM_Mali-Midgard_L2_EXT_AR_STALL" title="Mali L2 Cache" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
- <event counter="ARM_Mali-Midgard_L2_EXT_W_STALL" title="Mali L2 Cache" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-Midgard_L2_WRITE_BEATS" title="Mali L2 Cache Ext Writes" name="External write beats" description="Number of external bus write beats"/>
+ <event counter="ARM_Mali-Midgard_L2_EXT_W_STALL" title="Mali L2 Cache Ext Writes" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
+
+ <event counter="ARM_Mali-Midgard_L2_READ_BEATS" title="Mali L2 Cache Ext Reads" name="External read beats" description="Number of external bus read beats"/>
+ <event counter="ARM_Mali-Midgard_L2_EXT_AR_STALL" title="Mali L2 Cache Ext Reads" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
+
+ <event counter="ARM_Mali-Midgard_L2_READ_SNOOP" title="Mali L2 Cache Reads" name="Read snoops" description="Number of read transaction snoops"/>
+ <event counter="ARM_Mali-Midgard_L2_READ_HIT" title="Mali L2 Cache Reads" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
+ <event counter="ARM_Mali-Midgard_L2_WRITE_SNOOP" title="Mali L2 Cache Writes" name="Write snoops" description="Number of write transaction snoops"/>
+ <event counter="ARM_Mali-Midgard_L2_WRITE_HIT" title="Mali L2 Cache Writes" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
</category>
diff --git a/daemon/events-Mali-T60x_hw.xml b/daemon/events-Mali-T60x_hw.xml
index 50797e6..c35bcd1 100644
--- a/daemon/events-Mali-T60x_hw.xml
+++ b/daemon/events-Mali-T60x_hw.xml
@@ -7,12 +7,13 @@
<event counter="ARM_Mali-T60x_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) active"/>
<event counter="ARM_Mali-T60x_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) active"/>
- <event counter="ARM_Mali-T60x_JS0_JOBS" title="Mali Job Manager Work" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
- <event counter="ARM_Mali-T60x_JS0_TASKS" title="Mali Job Manager Work" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
- <event counter="ARM_Mali-T60x_JS1_JOBS" title="Mali Job Manager Work" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
- <event counter="ARM_Mali-T60x_JS1_TASKS" title="Mali Job Manager Work" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
- <event counter="ARM_Mali-T60x_JS2_TASKS" title="Mali Job Manager Work" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
- <event counter="ARM_Mali-T60x_JS2_JOBS" title="Mali Job Manager Work" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+ <event counter="ARM_Mali-T60x_JS0_JOBS" title="Mali Job Manager Jobs" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
+ <event counter="ARM_Mali-T60x_JS1_JOBS" title="Mali Job Manager Jobs" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
+ <event counter="ARM_Mali-T60x_JS2_JOBS" title="Mali Job Manager Jobs" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-T60x_JS0_TASKS" title="Mali Job Manager Tasks" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
+ <event counter="ARM_Mali-T60x_JS1_TASKS" title="Mali Job Manager Tasks" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
+ <event counter="ARM_Mali-T60x_JS2_TASKS" title="Mali Job Manager Tasks" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
</category>
@@ -77,32 +78,39 @@
<event counter="ARM_Mali-T60x_TEX_ISSUES" title="Mali Texture Pipe" name="T instruction issues" description="Number of threads through loop 2 address calculation"/>
<event counter="ARM_Mali-T60x_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/>
- <event counter="ARM_Mali-T60x_LSC_READ_HITS" title="Mali Load/Store Cache" name="Read hits" description="Number of read hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T60x_LSC_READ_MISSES" title="Mali Load/Store Cache" name="Read misses" description="Number of read misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T60x_LSC_WRITE_HITS" title="Mali Load/Store Cache" name="Write hits" description="Number of write hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T60x_LSC_WRITE_MISSES" title="Mali Load/Store Cache" name="Write misses" description="Number of write misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T60x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T60x_LSC_ATOMIC_MISSES" title="Mali Load/Store Cache" name="Atomic misses" description="Number of atomic misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T60x_LSC_LINE_FETCHES" title="Mali Load/Store Cache" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
- <event counter="ARM_Mali-T60x_LSC_DIRTY_LINE" title="Mali Load/Store Cache" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
- <event counter="ARM_Mali-T60x_LSC_SNOOPS" title="Mali Load/Store Cache" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
+ <event counter="ARM_Mali-T60x_LSC_READ_HITS" title="Mali Load/Store Cache Reads" name="Read hits" description="Number of read hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-T60x_LSC_READ_MISSES" title="Mali Load/Store Cache Reads" name="Read misses" description="Number of read misses in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T60x_LSC_WRITE_HITS" title="Mali Load/Store Cache Writes" name="Write hits" description="Number of write hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-T60x_LSC_WRITE_MISSES" title="Mali Load/Store Cache Writes" name="Write misses" description="Number of write misses in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T60x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache Atomics" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-T60x_LSC_ATOMIC_MISSES" title="Mali Load/Store Cache Atomics" name="Atomic misses" description="Number of atomic misses in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T60x_LSC_LINE_FETCHES" title="Mali Load/Store Cache Bus" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
+ <event counter="ARM_Mali-T60x_LSC_DIRTY_LINE" title="Mali Load/Store Cache Bus" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T60x_LSC_SNOOPS" title="Mali Load/Store Cache Bus" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
</category>
<category name="Mali L2 Cache" per_cpu="no">
- <event counter="ARM_Mali-T60x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache" name="External write beats" description="Number of external bus write beats"/>
- <event counter="ARM_Mali-T60x_L2_EXT_READ_BEATS" title="Mali L2 Cache" name="External read beats" description="Number of external bus read beats"/>
- <event counter="ARM_Mali-T60x_L2_READ_SNOOP" title="Mali L2 Cache" name="Read snoops" description="Number of read transaction snoops"/>
- <event counter="ARM_Mali-T60x_L2_READ_HIT" title="Mali L2 Cache" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
- <event counter="ARM_Mali-T60x_L2_WRITE_SNOOP" title="Mali L2 Cache" name="Write snoops" description="Number of write transaction snoops"/>
- <event counter="ARM_Mali-T60x_L2_WRITE_HIT" title="Mali L2 Cache" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
- <event counter="ARM_Mali-T60x_L2_EXT_AR_STALL" title="Mali L2 Cache" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
- <event counter="ARM_Mali-T60x_L2_EXT_W_STALL" title="Mali L2 Cache" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
- <event counter="ARM_Mali-T60x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
- <event counter="ARM_Mali-T60x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
- <event counter="ARM_Mali-T60x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
- <event counter="ARM_Mali-T60x_L2_READ_LOOKUP" title="Mali L2 Cache" name="L2 read lookups" description="Number of reads into the L2 cache"/>
- <event counter="ARM_Mali-T60x_L2_WRITE_LOOKUP" title="Mali L2 Cache" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+ <event counter="ARM_Mali-T60x_L2_READ_LOOKUP" title="Mali L2 Cache Reads" name="L2 read lookups" description="Number of reads into the L2 cache"/>
+ <event counter="ARM_Mali-T60x_L2_READ_SNOOP" title="Mali L2 Cache Reads" name="Read snoops" description="Number of read transaction snoops"/>
+ <event counter="ARM_Mali-T60x_L2_READ_HIT" title="Mali L2 Cache Reads" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
- </category>
+ <event counter="ARM_Mali-T60x_L2_WRITE_SNOOP" title="Mali L2 Cache Writes" name="Write snoops" description="Number of write transaction snoops"/>
+ <event counter="ARM_Mali-T60x_L2_WRITE_HIT" title="Mali L2 Cache Writes" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
+ <event counter="ARM_Mali-T60x_L2_WRITE_LOOKUP" title="Mali L2 Cache Writes" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+
+ <event counter="ARM_Mali-T60x_L2_EXT_READ_BEATS" title="Mali L2 Cache Ext Reads" name="External read beats" description="Number of external bus read beats"/>
+ <event counter="ARM_Mali-T60x_L2_EXT_AR_STALL" title="Mali L2 Cache Ext Reads" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T60x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
+ <event counter="ARM_Mali-T60x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
+
+ <event counter="ARM_Mali-T60x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache Ext Writes" name="External write beats" description="Number of external bus write beats"/>
+ <event counter="ARM_Mali-T60x_L2_EXT_W_STALL" title="Mali L2 Cache Ext Writes" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T60x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache Ext Writes" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
+
+ </category> \ No newline at end of file
diff --git a/daemon/events-Mali-T62x_hw.xml b/daemon/events-Mali-T62x_hw.xml
index 6ecc53c..4bc9306 100644
--- a/daemon/events-Mali-T62x_hw.xml
+++ b/daemon/events-Mali-T62x_hw.xml
@@ -7,12 +7,13 @@
<event counter="ARM_Mali-T62x_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) active"/>
<event counter="ARM_Mali-T62x_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) active"/>
- <event counter="ARM_Mali-T62x_JS0_JOBS" title="Mali Job Manager Work" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
- <event counter="ARM_Mali-T62x_JS0_TASKS" title="Mali Job Manager Work" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
- <event counter="ARM_Mali-T62x_JS1_JOBS" title="Mali Job Manager Work" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
- <event counter="ARM_Mali-T62x_JS1_TASKS" title="Mali Job Manager Work" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
- <event counter="ARM_Mali-T62x_JS2_TASKS" title="Mali Job Manager Work" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
- <event counter="ARM_Mali-T62x_JS2_JOBS" title="Mali Job Manager Work" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+ <event counter="ARM_Mali-T62x_JS0_JOBS" title="Mali Job Manager Jobs" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
+ <event counter="ARM_Mali-T62x_JS1_JOBS" title="Mali Job Manager Jobs" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
+ <event counter="ARM_Mali-T62x_JS2_JOBS" title="Mali Job Manager Jobs" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-T62x_JS0_TASKS" title="Mali Job Manager Tasks" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
+ <event counter="ARM_Mali-T62x_JS1_TASKS" title="Mali Job Manager Tasks" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
+ <event counter="ARM_Mali-T62x_JS2_TASKS" title="Mali Job Manager Tasks" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
</category>
@@ -78,32 +79,38 @@
<event counter="ARM_Mali-T62x_TEX_ISSUES" title="Mali Texture Pipe" name="T instruction issues" description="Number of threads through loop 2 address calculation"/>
<event counter="ARM_Mali-T62x_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/>
- <event counter="ARM_Mali-T62x_LSC_READ_HITS" title="Mali Load/Store Cache" name="Read hits" description="Number of read hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T62x_LSC_READ_MISSES" title="Mali Load/Store Cache" name="Read misses" description="Number of read misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T62x_LSC_WRITE_HITS" title="Mali Load/Store Cache" name="Write hits" description="Number of write hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T62x_LSC_WRITE_MISSES" title="Mali Load/Store Cache" name="Write misses" description="Number of write misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T62x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T62x_LSC_ATOMIC_MISSES" title="Mali Load/Store Cache" name="Atomic misses" description="Number of atomic misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T62x_LSC_LINE_FETCHES" title="Mali Load/Store Cache" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
- <event counter="ARM_Mali-T62x_LSC_DIRTY_LINE" title="Mali Load/Store Cache" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
- <event counter="ARM_Mali-T62x_LSC_SNOOPS" title="Mali Load/Store Cache" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
+ <event counter="ARM_Mali-T62x_LSC_READ_HITS" title="Mali Load/Store Cache Reads" name="Read hits" description="Number of read hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-T62x_LSC_READ_MISSES" title="Mali Load/Store Cache Reads" name="Read misses" description="Number of read misses in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T62x_LSC_WRITE_HITS" title="Mali Load/Store Cache Writes" name="Write hits" description="Number of write hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-T62x_LSC_WRITE_MISSES" title="Mali Load/Store Cache Writes" name="Write misses" description="Number of write misses in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T62x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache Atomics" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-T62x_LSC_ATOMIC_MISSES" title="Mali Load/Store Cache Atomics" name="Atomic misses" description="Number of atomic misses in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T62x_LSC_LINE_FETCHES" title="Mali Load/Store Cache Bus" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
+ <event counter="ARM_Mali-T62x_LSC_DIRTY_LINE" title="Mali Load/Store Cache Bus" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
+ <event counter="ARM_Mali-T62x_LSC_SNOOPS" title="Mali Load/Store Cache Bus" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
</category>
<category name="Mali L2 Cache" per_cpu="no">
- <event counter="ARM_Mali-T62x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache" name="External write beats" description="Number of external bus write beats"/>
- <event counter="ARM_Mali-T62x_L2_EXT_READ_BEATS" title="Mali L2 Cache" name="External read beats" description="Number of external bus read beats"/>
- <event counter="ARM_Mali-T62x_L2_READ_SNOOP" title="Mali L2 Cache" name="Read snoops" description="Number of read transaction snoops"/>
- <event counter="ARM_Mali-T62x_L2_READ_HIT" title="Mali L2 Cache" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
- <event counter="ARM_Mali-T62x_L2_WRITE_SNOOP" title="Mali L2 Cache" name="Write snoops" description="Number of write transaction snoops"/>
- <event counter="ARM_Mali-T62x_L2_WRITE_HIT" title="Mali L2 Cache" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
- <event counter="ARM_Mali-T62x_L2_EXT_AR_STALL" title="Mali L2 Cache" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
- <event counter="ARM_Mali-T62x_L2_EXT_W_STALL" title="Mali L2 Cache" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
- <event counter="ARM_Mali-T62x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
- <event counter="ARM_Mali-T62x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
- <event counter="ARM_Mali-T62x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
- <event counter="ARM_Mali-T62x_L2_READ_LOOKUP" title="Mali L2 Cache" name="L2 read lookups" description="Number of reads into the L2 cache"/>
- <event counter="ARM_Mali-T62x_L2_WRITE_LOOKUP" title="Mali L2 Cache" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+ <event counter="ARM_Mali-T62x_L2_READ_LOOKUP" title="Mali L2 Cache Reads" name="L2 read lookups" description="Number of reads into the L2 cache"/>
+ <event counter="ARM_Mali-T62x_L2_READ_SNOOP" title="Mali L2 Cache Reads" name="Read snoops" description="Number of read transaction snoops"/>
+ <event counter="ARM_Mali-T62x_L2_READ_HIT" title="Mali L2 Cache Reads" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
- </category>
+ <event counter="ARM_Mali-T62x_L2_WRITE_SNOOP" title="Mali L2 Cache Writes" name="Write snoops" description="Number of write transaction snoops"/>
+ <event counter="ARM_Mali-T62x_L2_WRITE_HIT" title="Mali L2 Cache Writes" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
+ <event counter="ARM_Mali-T62x_L2_WRITE_LOOKUP" title="Mali L2 Cache Writes" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+
+ <event counter="ARM_Mali-T62x_L2_EXT_READ_BEATS" title="Mali L2 Cache Ext Reads" name="External read beats" description="Number of external bus read beats"/>
+ <event counter="ARM_Mali-T62x_L2_EXT_AR_STALL" title="Mali L2 Cache Ext Reads" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T62x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
+ <event counter="ARM_Mali-T62x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
+
+ <event counter="ARM_Mali-T62x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache Ext Writes" name="External write beats" description="Number of external bus write beats"/>
+ <event counter="ARM_Mali-T62x_L2_EXT_W_STALL" title="Mali L2 Cache Ext Writes" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T62x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache Ext Writes" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
+
+ </category> \ No newline at end of file
diff --git a/daemon/events-Mali-T72x_hw.xml b/daemon/events-Mali-T72x_hw.xml
index 5587534..fd9cb0f 100644
--- a/daemon/events-Mali-T72x_hw.xml
+++ b/daemon/events-Mali-T72x_hw.xml
@@ -7,12 +7,13 @@
<event counter="ARM_Mali-T72x_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) active"/>
<event counter="ARM_Mali-T72x_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) active"/>
- <event counter="ARM_Mali-T72x_JS0_JOBS" title="Mali Job Manager Work" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
- <event counter="ARM_Mali-T72x_JS0_TASKS" title="Mali Job Manager Work" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
- <event counter="ARM_Mali-T72x_JS1_JOBS" title="Mali Job Manager Work" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
- <event counter="ARM_Mali-T72x_JS1_TASKS" title="Mali Job Manager Work" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
- <event counter="ARM_Mali-T72x_JS2_TASKS" title="Mali Job Manager Work" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
- <event counter="ARM_Mali-T72x_JS2_JOBS" title="Mali Job Manager Work" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+ <event counter="ARM_Mali-T72x_JS0_JOBS" title="Mali Job Manager Jobs" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
+ <event counter="ARM_Mali-T72x_JS1_JOBS" title="Mali Job Manager Jobs" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
+ <event counter="ARM_Mali-T72x_JS2_JOBS" title="Mali Job Manager Jobs" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-T72x_JS0_TASKS" title="Mali Job Manager Tasks" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
+ <event counter="ARM_Mali-T72x_JS1_TASKS" title="Mali Job Manager Tasks" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
+ <event counter="ARM_Mali-T72x_JS2_TASKS" title="Mali Job Manager Tasks" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
</category>
@@ -67,29 +68,34 @@
<event counter="ARM_Mali-T72x_TEX_WORDS" title="Mali Texture Pipe" name="T instructions" description="Number of instructions completed by the T-pipe"/>
<event counter="ARM_Mali-T72x_TEX_ISSUES" title="Mali Texture Pipe" name="T instruction issues" description="Number of threads through loop 2 address calculation"/>
- <event counter="ARM_Mali-T72x_LSC_READ_HITS" title="Mali Load/Store Cache" name="Read hits" description="Number of read hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T72x_LSC_READ_MISSES" title="Mali Load/Store Cache" name="Read misses" description="Number of read misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T72x_LSC_WRITE_HITS" title="Mali Load/Store Cache" name="Write hits" description="Number of write hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T72x_LSC_WRITE_MISSES" title="Mali Load/Store Cache" name="Write misses" description="Number of write misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T72x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T72x_LSC_ATOMIC_MISSES" title="Mali Load/Store Cache" name="Atomic misses" description="Number of atomic misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T72x_LSC_LINE_FETCHES" title="Mali Load/Store Cache" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
- <event counter="ARM_Mali-T72x_LSC_DIRTY_LINE" title="Mali Load/Store Cache" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
- <event counter="ARM_Mali-T72x_LSC_SNOOPS" title="Mali Load/Store Cache" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T72x_LSC_READ_HITS" title="Mali Load/Store Cache Reads" name="Read hits" description="Number of read hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-T72x_LSC_READ_MISSES" title="Mali Load/Store Cache Reads" name="Read misses" description="Number of read misses in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T72x_LSC_WRITE_HITS" title="Mali Load/Store Cache Writes" name="Write hits" description="Number of write hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-T72x_LSC_WRITE_MISSES" title="Mali Load/Store Cache Writes" name="Write misses" description="Number of write misses in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T72x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache Atomics" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
+ <event counter="ARM_Mali-T72x_LSC_ATOMIC_MISSES" title="Mali Load/Store Cache Atomics" name="Atomic misses" description="Number of atomic misses in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T72x_LSC_LINE_FETCHES" title="Mali Load/Store Cache Bus" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
+ <event counter="ARM_Mali-T72x_LSC_DIRTY_LINE" title="Mali Load/Store Cache Bus" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
+ <event counter="ARM_Mali-T72x_LSC_SNOOPS" title="Mali Load/Store Cache Bus" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
</category>
<category name="Mali L2 Cache" per_cpu="no">
- <event counter="ARM_Mali-T72x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache" name="External write beats" description="Number of external bus write beats"/>
- <event counter="ARM_Mali-T72x_L2_EXT_READ_BEATS" title="Mali L2 Cache" name="External read beats" description="Number of external bus read beats"/>
- <event counter="ARM_Mali-T72x_L2_READ_SNOOP" title="Mali L2 Cache" name="Read snoops" description="Number of read transaction snoops"/>
- <event counter="ARM_Mali-T72x_L2_READ_HIT" title="Mali L2 Cache" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
- <event counter="ARM_Mali-T72x_L2_WRITE_SNOOP" title="Mali L2 Cache" name="Write snoops" description="Number of write transaction snoops"/>
- <event counter="ARM_Mali-T72x_L2_WRITE_HIT" title="Mali L2 Cache" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
- <event counter="ARM_Mali-T72x_L2_EXT_AR_STALL" title="Mali L2 Cache" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
- <event counter="ARM_Mali-T72x_L2_EXT_W_STALL" title="Mali L2 Cache" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
- <event counter="ARM_Mali-T72x_L2_READ_LOOKUP" title="Mali L2 Cache" name="L2 read lookups" description="Number of reads into the L2 cache"/>
- <event counter="ARM_Mali-T72x_L2_WRITE_LOOKUP" title="Mali L2 Cache" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+ <event counter="ARM_Mali-T72x_L2_READ_SNOOP" title="Mali L2 Cache Reads" name="Read snoops" description="Number of read transaction snoops"/>
+ <event counter="ARM_Mali-T72x_L2_READ_HIT" title="Mali L2 Cache Reads" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
+
+ <event counter="ARM_Mali-T72x_L2_WRITE_SNOOP" title="Mali L2 Cache Writes" name="Write snoops" description="Number of write transaction snoops"/>
+ <event counter="ARM_Mali-T72x_L2_WRITE_HIT" title="Mali L2 Cache Writes" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
+
+ <event counter="ARM_Mali-T72x_L2_EXT_READ_BEAT" title="Mali L2 Cache Ext Reads" name="External read beats" description="Number of external bus read beats"/>
+ <event counter="ARM_Mali-T72x_L2_EXT_AR_STALL" title="Mali L2 Cache Ext Reads" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
+
+ <event counter="ARM_Mali-T72x_L2_EXT_WRITE_BEAT" title="Mali L2 Cache Ext Writes" name="External write beats" description="Number of external bus write beats"/>
+ <event counter="ARM_Mali-T72x_L2_EXT_W_STALL" title="Mali L2 Cache Ext Writes" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
</category>
diff --git a/daemon/events-Mali-T76x_hw.xml b/daemon/events-Mali-T76x_hw.xml
index be74c5a..94d059f 100644
--- a/daemon/events-Mali-T76x_hw.xml
+++ b/daemon/events-Mali-T76x_hw.xml
@@ -7,12 +7,13 @@
<event counter="ARM_Mali-T76x_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) active"/>
<event counter="ARM_Mali-T76x_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) active"/>
- <event counter="ARM_Mali-T76x_JS0_JOBS" title="Mali Job Manager Work" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
- <event counter="ARM_Mali-T76x_JS0_TASKS" title="Mali Job Manager Work" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
- <event counter="ARM_Mali-T76x_JS1_JOBS" title="Mali Job Manager Work" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
- <event counter="ARM_Mali-T76x_JS1_TASKS" title="Mali Job Manager Work" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
- <event counter="ARM_Mali-T76x_JS2_TASKS" title="Mali Job Manager Work" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
- <event counter="ARM_Mali-T76x_JS2_JOBS" title="Mali Job Manager Work" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+ <event counter="ARM_Mali-T76x_JS0_JOBS" title="Mali Job Manager Jobs" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
+ <event counter="ARM_Mali-T76x_JS1_JOBS" title="Mali Job Manager Jobs" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
+ <event counter="ARM_Mali-T76x_JS2_JOBS" title="Mali Job Manager Jobs" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-T76x_JS0_TASKS" title="Mali Job Manager Tasks" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
+ <event counter="ARM_Mali-T76x_JS1_TASKS" title="Mali Job Manager Tasks" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
+ <event counter="ARM_Mali-T76x_JS2_TASKS" title="Mali Job Manager Tasks" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
</category>
@@ -78,31 +79,39 @@
<event counter="ARM_Mali-T76x_TEX_ISSUES" title="Mali Texture Pipe" name="T instruction issues" description="Number of threads through loop 2 address calculation"/>
<event counter="ARM_Mali-T76x_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/>
- <event counter="ARM_Mali-T76x_LSC_READ_HITS" title="Mali Load/Store Cache" name="Read hits" description="Number of read hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T76x_LSC_READ_MISSES" title="Mali Load/Store Cache" name="Read misses" description="Number of read misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T76x_LSC_WRITE_HITS" title="Mali Load/Store Cache" name="Write hits" description="Number of write hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T76x_LSC_WRITE_MISSES" title="Mali Load/Store Cache" name="Write misses" description="Number of write misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T76x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
- <event counter="ARM_Mali-T76x_LSC_ATOMIC_MISSES" title="Mali Load/Store Cache" name="Atomic misses" description="Number of atomic misses in the Load/Store cache"/>
- <event counter="ARM_Mali-T76x_LSC_LINE_FETCHES" title="Mali Load/Store Cache" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
- <event counter="ARM_Mali-T76x_LSC_DIRTY_LINE" title="Mali Load/Store Cache" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
- <event counter="ARM_Mali-T76x_LSC_SNOOPS" title="Mali Load/Store Cache" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
+ <event counter="ARM_Mali-T76x_LSC_READ_OP" title="Mali Load/Store Cache Reads" name="Read operations" description="Number of read operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T76x_LSC_READ_HITS" title="Mali Load/Store Cache Reads" name="Read hits" description="Number of read hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T76x_LSC_WRITE_OP" title="Mali Load/Store Cache Writes" name="Write operations" description="Number of write operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T76x_LSC_WRITE_HITS" title="Mali Load/Store Cache Writes" name="Write hits" description="Number of write hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T76x_LSC_ATOMIC_OP" title="Mali Load/Store Cache Atomics" name="Atomic operations" description="Number of atomic operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T76x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache Atomics" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T76x_LSC_LINE_FETCHES" title="Mali Load/Store Cache Bus" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
+ <event counter="ARM_Mali-T76x_LSC_DIRTY_LINE" title="Mali Load/Store Cache Bus" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T76x_LSC_SNOOPS" title="Mali Load/Store Cache Bus" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
</category>
<category name="Mali L2 Cache" per_cpu="no">
- <event counter="ARM_Mali-T76x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache" name="External write beats" description="Number of external bus write beats"/>
- <event counter="ARM_Mali-T76x_L2_EXT_READ_BEATS" title="Mali L2 Cache" name="External read beats" description="Number of external bus read beats"/>
- <event counter="ARM_Mali-T76x_L2_READ_SNOOP" title="Mali L2 Cache" name="Read snoops" description="Number of read transaction snoops"/>
- <event counter="ARM_Mali-T76x_L2_READ_HIT" title="Mali L2 Cache" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
- <event counter="ARM_Mali-T76x_L2_WRITE_SNOOP" title="Mali L2 Cache" name="Write snoops" description="Number of write transaction snoops"/>
- <event counter="ARM_Mali-T76x_L2_WRITE_HIT" title="Mali L2 Cache" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
- <event counter="ARM_Mali-T76x_L2_EXT_AR_STALL" title="Mali L2 Cache" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
- <event counter="ARM_Mali-T76x_L2_EXT_W_STALL" title="Mali L2 Cache" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
- <event counter="ARM_Mali-T76x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
- <event counter="ARM_Mali-T76x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
- <event counter="ARM_Mali-T76x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
- <event counter="ARM_Mali-T76x_L2_READ_LOOKUP" title="Mali L2 Cache" name="L2 read lookups" description="Number of reads into the L2 cache"/>
- <event counter="ARM_Mali-T76x_L2_WRITE_LOOKUP" title="Mali L2 Cache" name="L2 write lookups" description="Number of writes into the L2 cache"/>
- </category>
+ <event counter="ARM_Mali-T76x_L2_READ_LOOKUP" title="Mali L2 Cache Reads" name="L2 read lookups" description="Number of reads into the L2 cache"/>
+ <event counter="ARM_Mali-T76x_L2_READ_SNOOP" title="Mali L2 Cache Reads" name="Read snoops" description="Number of read transaction snoops"/>
+ <event counter="ARM_Mali-T76x_L2_READ_HIT" title="Mali L2 Cache Reads" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
+
+ <event counter="ARM_Mali-T76x_L2_WRITE_SNOOP" title="Mali L2 Cache Writes" name="Write snoops" description="Number of write transaction snoops"/>
+ <event counter="ARM_Mali-T76x_L2_WRITE_HIT" title="Mali L2 Cache Writes" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
+ <event counter="ARM_Mali-T76x_L2_WRITE_LOOKUP" title="Mali L2 Cache Writes" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+
+ <event counter="ARM_Mali-T76x_L2_EXT_READ_BEATS" title="Mali L2 Cache Ext Reads" name="External read beats" description="Number of external bus read beats"/>
+ <event counter="ARM_Mali-T76x_L2_EXT_AR_STALL" title="Mali L2 Cache Ext Reads" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T76x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
+ <event counter="ARM_Mali-T76x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
+
+ <event counter="ARM_Mali-T76x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache Ext Writes" name="External write beats" description="Number of external bus write beats"/>
+ <event counter="ARM_Mali-T76x_L2_EXT_W_STALL" title="Mali L2 Cache Ext Writes" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T76x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache Ext Writes" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
+
+ </category> \ No newline at end of file
diff --git a/daemon/events-Mali-T82x_hw.xml b/daemon/events-Mali-T82x_hw.xml
new file mode 100644
index 0000000..5caa464
--- /dev/null
+++ b/daemon/events-Mali-T82x_hw.xml
@@ -0,0 +1,108 @@
+
+ <category name="Mali Job Manager" per_cpu="no">
+
+ <event counter="ARM_Mali-T82x_GPU_ACTIVE" title="Mali Job Manager Cycles" name="GPU cycles" description="Number of cycles GPU active"/>
+ <event counter="ARM_Mali-T82x_IRQ_ACTIVE" title="Mali Job Manager Cycles" name="IRQ cycles" description="Number of cycles GPU interrupt pending"/>
+ <event counter="ARM_Mali-T82x_JS0_ACTIVE" title="Mali Job Manager Cycles" name="JS0 cycles" description="Number of cycles JS0 (fragment) active"/>
+ <event counter="ARM_Mali-T82x_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) active"/>
+ <event counter="ARM_Mali-T82x_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) active"/>
+
+ <event counter="ARM_Mali-T82x_JS0_JOBS" title="Mali Job Manager Jobs" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
+ <event counter="ARM_Mali-T82x_JS1_JOBS" title="Mali Job Manager Jobs" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
+ <event counter="ARM_Mali-T82x_JS2_JOBS" title="Mali Job Manager Jobs" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-T82x_JS0_TASKS" title="Mali Job Manager Tasks" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
+ <event counter="ARM_Mali-T82x_JS1_TASKS" title="Mali Job Manager Tasks" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
+ <event counter="ARM_Mali-T82x_JS2_TASKS" title="Mali Job Manager Tasks" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
+
+ </category>
+
+ <category name="Mali Tiler" per_cpu="no">
+
+ <event counter="ARM_Mali-T82x_TI_ACTIVE" title="Mali Tiler Cycles" name="Tiler cycles" description="Number of cycles Tiler active"/>
+
+ <event counter="ARM_Mali-T82x_TI_POLYGONS" title="Mali Tiler Primitives" name="Polygons" description="Number of polygons processed"/>
+ <event counter="ARM_Mali-T82x_TI_QUADS" title="Mali Tiler Primitives" name="Quads" description="Number of quads processed"/>
+ <event counter="ARM_Mali-T82x_TI_TRIANGLES" title="Mali Tiler Primitives" name="Triangles" description="Number of triangles processed"/>
+ <event counter="ARM_Mali-T82x_TI_LINES" title="Mali Tiler Primitives" name="Lines" description="Number of lines processed"/>
+ <event counter="ARM_Mali-T82x_TI_POINTS" title="Mali Tiler Primitives" name="Points" description="Number of points processed"/>
+
+ <event counter="ARM_Mali-T82x_TI_FRONT_FACING" title="Mali Tiler Culling" name="Front facing prims" description="Number of front facing primitives"/>
+ <event counter="ARM_Mali-T82x_TI_BACK_FACING" title="Mali Tiler Culling" name="Back facing prims" description="Number of back facing primitives"/>
+ <event counter="ARM_Mali-T82x_TI_PRIM_VISIBLE" title="Mali Tiler Culling" name="Visible prims" description="Number of visible primitives"/>
+ <event counter="ARM_Mali-T82x_TI_PRIM_CULLED" title="Mali Tiler Culling" name="Culled prims" description="Number of culled primitives"/>
+ <event counter="ARM_Mali-T82x_TI_PRIM_CLIPPED" title="Mali Tiler Culling" name="Clipped prims" description="Number of clipped primitives"/>
+
+ </category>
+
+ <category name="Mali Shader Core" per_cpu="no">
+
+ <event counter="ARM_Mali-T82x_TRIPIPE_ACTIVE" title="Mali Core Cycles" name="Tripipe cycles" description="Number of cycles tripipe was active"/>
+ <event counter="ARM_Mali-T82x_FRAG_ACTIVE" title="Mali Core Cycles" name="Fragment cycles" description="Number of cycles fragment processing was active"/>
+ <event counter="ARM_Mali-T82x_COMPUTE_ACTIVE" title="Mali Core Cycles" name="Compute cycles" description="Number of cycles vertex\compute processing was active"/>
+ <event counter="ARM_Mali-T82x_FRAG_CYCLES_NO_TILE" title="Mali Core Cycles" name="Fragment cycles waiting for tile" description="Number of cycles spent waiting for a physical tile buffer"/>
+ <event counter="ARM_Mali-T82x_FRAG_CYCLES_FPKQ_ACTIVE" title="Mali Core Cycles" name="Fragment cycles pre-pipe buffer not empty" description="Number of cycles the pre-pipe queue contains quads"/>
+
+ <event counter="ARM_Mali-T82x_FRAG_THREADS" title="Mali Fragment Threads" name="Fragment threads" description="Number of fragment threads started"/>
+ <event counter="ARM_Mali-T82x_FRAG_DUMMY_THREADS" title="Mali Fragment Threads" name="Dummy fragment threads" description="Number of dummy fragment threads started"/>
+ <event counter="ARM_Mali-T82x_FRAG_THREADS_LZS_TEST" title="Mali Fragment Threads" name="Fragment threads doing late ZS" description="Number of threads doing late ZS test"/>
+ <event counter="ARM_Mali-T82x_FRAG_THREADS_LZS_KILLED" title="Mali Fragment Threads" name="Fragment threads killed late ZS" description="Number of threads killed by late ZS test"/>
+
+ <event counter="ARM_Mali-T82x_COMPUTE_TASKS" title="Mali Compute Tasks" name="Compute tasks" description="Number of compute tasks"/>
+ <event counter="ARM_Mali-T82x_COMPUTE_THREADS" title="Mali Compute Threads" name="Compute threads" description="Number of compute threads started"/>
+
+ <event counter="ARM_Mali-T82x_FRAG_PRIMITIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/>
+ <event counter="ARM_Mali-T82x_FRAG_PRIMITIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/>
+
+ <event counter="ARM_Mali-T82x_FRAG_QUADS_RAST" title="Mali Fragment Quads" name="Quads rasterized" description="Number of quads rasterized"/>
+ <event counter="ARM_Mali-T82x_FRAG_QUADS_EZS_TEST" title="Mali Fragment Quads" name="Quads doing early ZS" description="Number of quads doing early ZS test"/>
+ <event counter="ARM_Mali-T82x_FRAG_QUADS_EZS_KILLED" title="Mali Fragment Quads" name="Quads killed early Z" description="Number of quads killed by early ZS test"/>
+
+ <event counter="ARM_Mali-T82x_FRAG_NUM_TILES" title="Mali Fragment Tasks" name="Tiles rendered" description="Number of tiles rendered"/>
+ <event counter="ARM_Mali-T82x_FRAG_TRANS_ELIM" title="Mali Fragment Tasks" name="Tile writes killed by TE" description="Number of tile writes skipped by transaction elimination"/>
+
+ <event counter="ARM_Mali-T82x_ARITH_WORDS" title="Mali Arithmetic Pipe" name="A instructions" description="Number of batched instructions executed by the A-pipe (normalized per pipe)"/>
+
+ <event counter="ARM_Mali-T82x_LS_WORDS" title="Mali Load/Store Pipe" name="LS instructions" description="Number of instructions completed by the LS-pipe"/>
+ <event counter="ARM_Mali-T82x_LS_ISSUES" title="Mali Load/Store Pipe" name="LS instruction issues" description="Number of instructions issued to the LS-pipe, including restarts"/>
+
+ <event counter="ARM_Mali-T82x_TEX_WORDS" title="Mali Texture Pipe" name="T instructions" description="Number of instructions completed by the T-pipe"/>
+ <event counter="ARM_Mali-T82x_TEX_ISSUES" title="Mali Texture Pipe" name="T instruction issues" description="Number of threads through loop 2 address calculation"/>
+ <event counter="ARM_Mali-T82x_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/>
+
+ <event counter="ARM_Mali-T82x_LSC_READ_OP" title="Mali Load/Store Cache Reads" name="Read operations" description="Number of read operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T82x_LSC_READ_HITS" title="Mali Load/Store Cache Reads" name="Read hits" description="Number of read hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T82x_LSC_WRITE_OP" title="Mali Load/Store Cache Writes" name="Write operations" description="Number of write operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T82x_LSC_WRITE_HITS" title="Mali Load/Store Cache Writes" name="Write hits" description="Number of write hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T82x_LSC_ATOMIC_OP" title="Mali Load/Store Cache Atomics" name="Atomic operations" description="Number of atomic operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T82x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache Atomics" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T82x_LSC_LINE_FETCHES" title="Mali Load/Store Cache Bus" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
+ <event counter="ARM_Mali-T82x_LSC_DIRTY_LINE" title="Mali Load/Store Cache Bus" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T82x_LSC_SNOOPS" title="Mali Load/Store Cache Bus" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
+
+ </category>
+
+ <category name="Mali L2 Cache" per_cpu="no">
+
+ <event counter="ARM_Mali-T82x_L2_READ_LOOKUP" title="Mali L2 Cache Reads" name="L2 read lookups" description="Number of reads into the L2 cache"/>
+ <event counter="ARM_Mali-T82x_L2_READ_SNOOP" title="Mali L2 Cache Reads" name="Read snoops" description="Number of read transaction snoops"/>
+ <event counter="ARM_Mali-T82x_L2_READ_HIT" title="Mali L2 Cache Reads" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
+
+ <event counter="ARM_Mali-T82x_L2_WRITE_SNOOP" title="Mali L2 Cache Writes" name="Write snoops" description="Number of write transaction snoops"/>
+ <event counter="ARM_Mali-T82x_L2_WRITE_HIT" title="Mali L2 Cache Writes" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
+ <event counter="ARM_Mali-T82x_L2_WRITE_LOOKUP" title="Mali L2 Cache Writes" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+
+ <event counter="ARM_Mali-T82x_L2_EXT_READ_BEATS" title="Mali L2 Cache Ext Reads" name="External read beats" description="Number of external bus read beats"/>
+ <event counter="ARM_Mali-T82x_L2_EXT_AR_STALL" title="Mali L2 Cache Ext Reads" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T82x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
+ <event counter="ARM_Mali-T82x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
+
+ <event counter="ARM_Mali-T82x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache Ext Writes" name="External write beats" description="Number of external bus write beats"/>
+ <event counter="ARM_Mali-T82x_L2_EXT_W_STALL" title="Mali L2 Cache Ext Writes" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T82x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache Ext Writes" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
+
+ </category>
diff --git a/daemon/events-Mali-T83x_hw.xml b/daemon/events-Mali-T83x_hw.xml
new file mode 100644
index 0000000..39f7acf
--- /dev/null
+++ b/daemon/events-Mali-T83x_hw.xml
@@ -0,0 +1,108 @@
+
+ <category name="Mali Job Manager" per_cpu="no">
+
+ <event counter="ARM_Mali-T83x_GPU_ACTIVE" title="Mali Job Manager Cycles" name="GPU cycles" description="Number of cycles GPU active"/>
+ <event counter="ARM_Mali-T83x_IRQ_ACTIVE" title="Mali Job Manager Cycles" name="IRQ cycles" description="Number of cycles GPU interrupt pending"/>
+ <event counter="ARM_Mali-T83x_JS0_ACTIVE" title="Mali Job Manager Cycles" name="JS0 cycles" description="Number of cycles JS0 (fragment) active"/>
+ <event counter="ARM_Mali-T83x_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) active"/>
+ <event counter="ARM_Mali-T83x_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) active"/>
+
+ <event counter="ARM_Mali-T83x_JS0_JOBS" title="Mali Job Manager Jobs" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
+ <event counter="ARM_Mali-T83x_JS1_JOBS" title="Mali Job Manager Jobs" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
+ <event counter="ARM_Mali-T83x_JS2_JOBS" title="Mali Job Manager Jobs" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-T83x_JS0_TASKS" title="Mali Job Manager Tasks" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
+ <event counter="ARM_Mali-T83x_JS1_TASKS" title="Mali Job Manager Tasks" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
+ <event counter="ARM_Mali-T83x_JS2_TASKS" title="Mali Job Manager Tasks" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
+
+ </category>
+
+ <category name="Mali Tiler" per_cpu="no">
+
+ <event counter="ARM_Mali-T83x_TI_ACTIVE" title="Mali Tiler Cycles" name="Tiler cycles" description="Number of cycles Tiler active"/>
+
+ <event counter="ARM_Mali-T83x_TI_POLYGONS" title="Mali Tiler Primitives" name="Polygons" description="Number of polygons processed"/>
+ <event counter="ARM_Mali-T83x_TI_QUADS" title="Mali Tiler Primitives" name="Quads" description="Number of quads processed"/>
+ <event counter="ARM_Mali-T83x_TI_TRIANGLES" title="Mali Tiler Primitives" name="Triangles" description="Number of triangles processed"/>
+ <event counter="ARM_Mali-T83x_TI_LINES" title="Mali Tiler Primitives" name="Lines" description="Number of lines processed"/>
+ <event counter="ARM_Mali-T83x_TI_POINTS" title="Mali Tiler Primitives" name="Points" description="Number of points processed"/>
+
+ <event counter="ARM_Mali-T83x_TI_FRONT_FACING" title="Mali Tiler Culling" name="Front facing prims" description="Number of front facing primitives"/>
+ <event counter="ARM_Mali-T83x_TI_BACK_FACING" title="Mali Tiler Culling" name="Back facing prims" description="Number of back facing primitives"/>
+ <event counter="ARM_Mali-T83x_TI_PRIM_VISIBLE" title="Mali Tiler Culling" name="Visible prims" description="Number of visible primitives"/>
+ <event counter="ARM_Mali-T83x_TI_PRIM_CULLED" title="Mali Tiler Culling" name="Culled prims" description="Number of culled primitives"/>
+ <event counter="ARM_Mali-T83x_TI_PRIM_CLIPPED" title="Mali Tiler Culling" name="Clipped prims" description="Number of clipped primitives"/>
+
+ </category>
+
+ <category name="Mali Shader Core" per_cpu="no">
+
+ <event counter="ARM_Mali-T83x_TRIPIPE_ACTIVE" title="Mali Core Cycles" name="Tripipe cycles" description="Number of cycles tripipe was active"/>
+ <event counter="ARM_Mali-T83x_FRAG_ACTIVE" title="Mali Core Cycles" name="Fragment cycles" description="Number of cycles fragment processing was active"/>
+ <event counter="ARM_Mali-T83x_COMPUTE_ACTIVE" title="Mali Core Cycles" name="Compute cycles" description="Number of cycles vertex\compute processing was active"/>
+ <event counter="ARM_Mali-T83x_FRAG_CYCLES_NO_TILE" title="Mali Core Cycles" name="Fragment cycles waiting for tile" description="Number of cycles spent waiting for a physical tile buffer"/>
+ <event counter="ARM_Mali-T83x_FRAG_CYCLES_FPKQ_ACTIVE" title="Mali Core Cycles" name="Fragment cycles pre-pipe buffer not empty" description="Number of cycles the pre-pipe queue contains quads"/>
+
+ <event counter="ARM_Mali-T83x_FRAG_THREADS" title="Mali Fragment Threads" name="Fragment threads" description="Number of fragment threads started"/>
+ <event counter="ARM_Mali-T83x_FRAG_DUMMY_THREADS" title="Mali Fragment Threads" name="Dummy fragment threads" description="Number of dummy fragment threads started"/>
+ <event counter="ARM_Mali-T83x_FRAG_THREADS_LZS_TEST" title="Mali Fragment Threads" name="Fragment threads doing late ZS" description="Number of threads doing late ZS test"/>
+ <event counter="ARM_Mali-T83x_FRAG_THREADS_LZS_KILLED" title="Mali Fragment Threads" name="Fragment threads killed late ZS" description="Number of threads killed by late ZS test"/>
+
+ <event counter="ARM_Mali-T83x_COMPUTE_TASKS" title="Mali Compute Tasks" name="Compute tasks" description="Number of compute tasks"/>
+ <event counter="ARM_Mali-T83x_COMPUTE_THREADS" title="Mali Compute Threads" name="Compute threads" description="Number of compute threads started"/>
+
+ <event counter="ARM_Mali-T83x_FRAG_PRIMITIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/>
+ <event counter="ARM_Mali-T83x_FRAG_PRIMITIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/>
+
+ <event counter="ARM_Mali-T83x_FRAG_QUADS_RAST" title="Mali Fragment Quads" name="Quads rasterized" description="Number of quads rasterized"/>
+ <event counter="ARM_Mali-T83x_FRAG_QUADS_EZS_TEST" title="Mali Fragment Quads" name="Quads doing early ZS" description="Number of quads doing early ZS test"/>
+ <event counter="ARM_Mali-T83x_FRAG_QUADS_EZS_KILLED" title="Mali Fragment Quads" name="Quads killed early Z" description="Number of quads killed by early ZS test"/>
+
+ <event counter="ARM_Mali-T83x_FRAG_NUM_TILES" title="Mali Fragment Tasks" name="Tiles rendered" description="Number of tiles rendered"/>
+ <event counter="ARM_Mali-T83x_FRAG_TRANS_ELIM" title="Mali Fragment Tasks" name="Tile writes killed by TE" description="Number of tile writes skipped by transaction elimination"/>
+
+ <event counter="ARM_Mali-T83x_ARITH_WORDS" title="Mali Arithmetic Pipe" name="A instructions" description="Number of batched instructions executed by the A-pipe (normalized per pipe)"/>
+
+ <event counter="ARM_Mali-T83x_LS_WORDS" title="Mali Load/Store Pipe" name="LS instructions" description="Number of instructions completed by the LS-pipe"/>
+ <event counter="ARM_Mali-T83x_LS_ISSUES" title="Mali Load/Store Pipe" name="LS instruction issues" description="Number of instructions issued to the LS-pipe, including restarts"/>
+
+ <event counter="ARM_Mali-T83x_TEX_WORDS" title="Mali Texture Pipe" name="T instructions" description="Number of instructions completed by the T-pipe"/>
+ <event counter="ARM_Mali-T83x_TEX_ISSUES" title="Mali Texture Pipe" name="T instruction issues" description="Number of threads through loop 2 address calculation"/>
+ <event counter="ARM_Mali-T83x_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/>
+
+ <event counter="ARM_Mali-T83x_LSC_READ_OP" title="Mali Load/Store Cache Reads" name="Read operations" description="Number of read operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T83x_LSC_READ_HITS" title="Mali Load/Store Cache Reads" name="Read hits" description="Number of read hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T83x_LSC_WRITE_OP" title="Mali Load/Store Cache Writes" name="Write operations" description="Number of write operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T83x_LSC_WRITE_HITS" title="Mali Load/Store Cache Writes" name="Write hits" description="Number of write hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T83x_LSC_ATOMIC_OP" title="Mali Load/Store Cache Atomics" name="Atomic operations" description="Number of atomic operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T83x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache Atomics" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T83x_LSC_LINE_FETCHES" title="Mali Load/Store Cache Bus" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
+ <event counter="ARM_Mali-T83x_LSC_DIRTY_LINE" title="Mali Load/Store Cache Bus" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T83x_LSC_SNOOPS" title="Mali Load/Store Cache Bus" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
+
+ </category>
+
+ <category name="Mali L2 Cache" per_cpu="no">
+
+ <event counter="ARM_Mali-T83x_L2_READ_LOOKUP" title="Mali L2 Cache Reads" name="L2 read lookups" description="Number of reads into the L2 cache"/>
+ <event counter="ARM_Mali-T83x_L2_READ_SNOOP" title="Mali L2 Cache Reads" name="Read snoops" description="Number of read transaction snoops"/>
+ <event counter="ARM_Mali-T83x_L2_READ_HIT" title="Mali L2 Cache Reads" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
+
+ <event counter="ARM_Mali-T83x_L2_WRITE_SNOOP" title="Mali L2 Cache Writes" name="Write snoops" description="Number of write transaction snoops"/>
+ <event counter="ARM_Mali-T83x_L2_WRITE_HIT" title="Mali L2 Cache Writes" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
+ <event counter="ARM_Mali-T83x_L2_WRITE_LOOKUP" title="Mali L2 Cache Writes" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+
+ <event counter="ARM_Mali-T83x_L2_EXT_READ_BEATS" title="Mali L2 Cache Ext Reads" name="External read beats" description="Number of external bus read beats"/>
+ <event counter="ARM_Mali-T83x_L2_EXT_AR_STALL" title="Mali L2 Cache Ext Reads" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T83x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
+ <event counter="ARM_Mali-T83x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
+
+ <event counter="ARM_Mali-T83x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache Ext Writes" name="External write beats" description="Number of external bus write beats"/>
+ <event counter="ARM_Mali-T83x_L2_EXT_W_STALL" title="Mali L2 Cache Ext Writes" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T83x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache Ext Writes" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
+
+ </category>
diff --git a/daemon/events-Mali-T86x_hw.xml b/daemon/events-Mali-T86x_hw.xml
new file mode 100644
index 0000000..6653543
--- /dev/null
+++ b/daemon/events-Mali-T86x_hw.xml
@@ -0,0 +1,117 @@
+
+ <category name="Mali Job Manager" per_cpu="no">
+
+ <event counter="ARM_Mali-T86x_GPU_ACTIVE" title="Mali Job Manager Cycles" name="GPU cycles" description="Number of cycles GPU active"/>
+ <event counter="ARM_Mali-T86x_IRQ_ACTIVE" title="Mali Job Manager Cycles" name="IRQ cycles" description="Number of cycles GPU interrupt pending"/>
+ <event counter="ARM_Mali-T86x_JS0_ACTIVE" title="Mali Job Manager Cycles" name="JS0 cycles" description="Number of cycles JS0 (fragment) active"/>
+ <event counter="ARM_Mali-T86x_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) active"/>
+ <event counter="ARM_Mali-T86x_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) active"/>
+
+ <event counter="ARM_Mali-T86x_JS0_JOBS" title="Mali Job Manager Jobs" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
+ <event counter="ARM_Mali-T86x_JS1_JOBS" title="Mali Job Manager Jobs" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
+ <event counter="ARM_Mali-T86x_JS2_JOBS" title="Mali Job Manager Jobs" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-T86x_JS0_TASKS" title="Mali Job Manager Tasks" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
+ <event counter="ARM_Mali-T86x_JS1_TASKS" title="Mali Job Manager Tasks" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
+ <event counter="ARM_Mali-T86x_JS2_TASKS" title="Mali Job Manager Tasks" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
+
+ </category>
+
+ <category name="Mali Tiler" per_cpu="no">
+
+ <event counter="ARM_Mali-T86x_TI_ACTIVE" title="Mali Tiler Cycles" name="Tiler cycles" description="Number of cycles Tiler active"/>
+
+ <event counter="ARM_Mali-T86x_TI_POLYGONS" title="Mali Tiler Primitives" name="Polygons" description="Number of polygons processed"/>
+ <event counter="ARM_Mali-T86x_TI_QUADS" title="Mali Tiler Primitives" name="Quads" description="Number of quads processed"/>
+ <event counter="ARM_Mali-T86x_TI_TRIANGLES" title="Mali Tiler Primitives" name="Triangles" description="Number of triangles processed"/>
+ <event counter="ARM_Mali-T86x_TI_LINES" title="Mali Tiler Primitives" name="Lines" description="Number of lines processed"/>
+ <event counter="ARM_Mali-T86x_TI_POINTS" title="Mali Tiler Primitives" name="Points" description="Number of points processed"/>
+
+ <event counter="ARM_Mali-T86x_TI_FRONT_FACING" title="Mali Tiler Culling" name="Front facing prims" description="Number of front facing primitives"/>
+ <event counter="ARM_Mali-T86x_TI_BACK_FACING" title="Mali Tiler Culling" name="Back facing prims" description="Number of back facing primitives"/>
+ <event counter="ARM_Mali-T86x_TI_PRIM_VISIBLE" title="Mali Tiler Culling" name="Visible prims" description="Number of visible primitives"/>
+ <event counter="ARM_Mali-T86x_TI_PRIM_CULLED" title="Mali Tiler Culling" name="Culled prims" description="Number of culled primitives"/>
+ <event counter="ARM_Mali-T86x_TI_PRIM_CLIPPED" title="Mali Tiler Culling" name="Clipped prims" description="Number of clipped primitives"/>
+
+ <event counter="ARM_Mali-T86x_TI_LEVEL0" title="Mali Tiler Hierarchy" name="L0 prims" description="Number of primitives in hierarchy level 0"/>
+ <event counter="ARM_Mali-T86x_TI_LEVEL1" title="Mali Tiler Hierarchy" name="L1 prims" description="Number of primitives in hierarchy level 1"/>
+ <event counter="ARM_Mali-T86x_TI_LEVEL2" title="Mali Tiler Hierarchy" name="L2 prims" description="Number of primitives in hierarchy level 2"/>
+ <event counter="ARM_Mali-T86x_TI_LEVEL3" title="Mali Tiler Hierarchy" name="L3 prims" description="Number of primitives in hierarchy level 3"/>
+ <event counter="ARM_Mali-T86x_TI_LEVEL4" title="Mali Tiler Hierarchy" name="L4 prims" description="Number of primitives in hierarchy level 4"/>
+ <event counter="ARM_Mali-T86x_TI_LEVEL5" title="Mali Tiler Hierarchy" name="L5 prims" description="Number of primitives in hierarchy level 5"/>
+ <event counter="ARM_Mali-T86x_TI_LEVEL6" title="Mali Tiler Hierarchy" name="L6 prims" description="Number of primitives in hierarchy level 6"/>
+ <event counter="ARM_Mali-T86x_TI_LEVEL7" title="Mali Tiler Hierarchy" name="L7 prims" description="Number of primitives in hierarchy level 7"/>
+
+ </category>
+
+ <category name="Mali Shader Core" per_cpu="no">
+
+ <event counter="ARM_Mali-T86x_TRIPIPE_ACTIVE" title="Mali Core Cycles" name="Tripipe cycles" description="Number of cycles tripipe was active"/>
+ <event counter="ARM_Mali-T86x_FRAG_ACTIVE" title="Mali Core Cycles" name="Fragment cycles" description="Number of cycles fragment processing was active"/>
+ <event counter="ARM_Mali-T86x_COMPUTE_ACTIVE" title="Mali Core Cycles" name="Compute cycles" description="Number of cycles vertex\compute processing was active"/>
+ <event counter="ARM_Mali-T86x_FRAG_CYCLES_NO_TILE" title="Mali Core Cycles" name="Fragment cycles waiting for tile" description="Number of cycles spent waiting for a physical tile buffer"/>
+ <event counter="ARM_Mali-T86x_FRAG_CYCLES_FPKQ_ACTIVE" title="Mali Core Cycles" name="Fragment cycles pre-pipe buffer not empty" description="Number of cycles the pre-pipe queue contains quads"/>
+
+ <event counter="ARM_Mali-T86x_FRAG_THREADS" title="Mali Fragment Threads" name="Fragment threads" description="Number of fragment threads started"/>
+ <event counter="ARM_Mali-T86x_FRAG_DUMMY_THREADS" title="Mali Fragment Threads" name="Dummy fragment threads" description="Number of dummy fragment threads started"/>
+ <event counter="ARM_Mali-T86x_FRAG_THREADS_LZS_TEST" title="Mali Fragment Threads" name="Fragment threads doing late ZS" description="Number of threads doing late ZS test"/>
+ <event counter="ARM_Mali-T86x_FRAG_THREADS_LZS_KILLED" title="Mali Fragment Threads" name="Fragment threads killed late ZS" description="Number of threads killed by late ZS test"/>
+
+ <event counter="ARM_Mali-T86x_COMPUTE_TASKS" title="Mali Compute Tasks" name="Compute tasks" description="Number of compute tasks"/>
+ <event counter="ARM_Mali-T86x_COMPUTE_THREADS" title="Mali Compute Threads" name="Compute threads" description="Number of compute threads started"/>
+
+ <event counter="ARM_Mali-T86x_FRAG_PRIMITIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/>
+ <event counter="ARM_Mali-T86x_FRAG_PRIMITIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/>
+
+ <event counter="ARM_Mali-T86x_FRAG_QUADS_RAST" title="Mali Fragment Quads" name="Quads rasterized" description="Number of quads rasterized"/>
+ <event counter="ARM_Mali-T86x_FRAG_QUADS_EZS_TEST" title="Mali Fragment Quads" name="Quads doing early ZS" description="Number of quads doing early ZS test"/>
+ <event counter="ARM_Mali-T86x_FRAG_QUADS_EZS_KILLED" title="Mali Fragment Quads" name="Quads killed early Z" description="Number of quads killed by early ZS test"/>
+
+ <event counter="ARM_Mali-T86x_FRAG_NUM_TILES" title="Mali Fragment Tasks" name="Tiles rendered" description="Number of tiles rendered"/>
+ <event counter="ARM_Mali-T86x_FRAG_TRANS_ELIM" title="Mali Fragment Tasks" name="Tile writes killed by TE" description="Number of tile writes skipped by transaction elimination"/>
+
+ <event counter="ARM_Mali-T86x_ARITH_WORDS" title="Mali Arithmetic Pipe" name="A instructions" description="Number of instructions completed by the the A-pipe (normalized per pipeline)"/>
+
+ <event counter="ARM_Mali-T86x_LS_WORDS" title="Mali Load/Store Pipe" name="LS instructions" description="Number of instructions completed by the LS-pipe"/>
+ <event counter="ARM_Mali-T86x_LS_ISSUES" title="Mali Load/Store Pipe" name="LS instruction issues" description="Number of instructions issued to the LS-pipe, including restarts"/>
+
+ <event counter="ARM_Mali-T86x_TEX_WORDS" title="Mali Texture Pipe" name="T instructions" description="Number of instructions completed by the T-pipe"/>
+ <event counter="ARM_Mali-T86x_TEX_ISSUES" title="Mali Texture Pipe" name="T instruction issues" description="Number of threads through loop 2 address calculation"/>
+ <event counter="ARM_Mali-T86x_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/>
+
+ <event counter="ARM_Mali-T86x_LSC_READ_OP" title="Mali Load/Store Cache Reads" name="Read operations" description="Number of read operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T86x_LSC_READ_HITS" title="Mali Load/Store Cache Reads" name="Read hits" description="Number of read hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T86x_LSC_WRITE_OP" title="Mali Load/Store Cache Writes" name="Write operations" description="Number of write operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T86x_LSC_WRITE_HITS" title="Mali Load/Store Cache Writes" name="Write hits" description="Number of write hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T86x_LSC_ATOMIC_OP" title="Mali Load/Store Cache Atomics" name="Atomic operations" description="Number of atomic operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T86x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache Atomics" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T86x_LSC_LINE_FETCHES" title="Mali Load/Store Cache Bus" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
+ <event counter="ARM_Mali-T86x_LSC_DIRTY_LINE" title="Mali Load/Store Cache Bus" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T86x_LSC_SNOOPS" title="Mali Load/Store Cache Bus" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
+
+ </category>
+
+ <category name="Mali L2 Cache" per_cpu="no">
+
+ <event counter="ARM_Mali-T86x_L2_READ_LOOKUP" title="Mali L2 Cache Reads" name="L2 read lookups" description="Number of reads into the L2 cache"/>
+ <event counter="ARM_Mali-T86x_L2_READ_SNOOP" title="Mali L2 Cache Reads" name="Read snoops" description="Number of read transaction snoops"/>
+ <event counter="ARM_Mali-T86x_L2_READ_HIT" title="Mali L2 Cache Reads" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
+
+ <event counter="ARM_Mali-T86x_L2_WRITE_SNOOP" title="Mali L2 Cache Writes" name="Write snoops" description="Number of write transaction snoops"/>
+ <event counter="ARM_Mali-T86x_L2_WRITE_HIT" title="Mali L2 Cache Writes" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
+ <event counter="ARM_Mali-T86x_L2_WRITE_LOOKUP" title="Mali L2 Cache Writes" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+
+ <event counter="ARM_Mali-T86x_L2_EXT_READ_BEATS" title="Mali L2 Cache Ext Reads" name="External read beats" description="Number of external bus read beats"/>
+ <event counter="ARM_Mali-T86x_L2_EXT_AR_STALL" title="Mali L2 Cache Ext Reads" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T86x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
+ <event counter="ARM_Mali-T86x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
+
+ <event counter="ARM_Mali-T86x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache Ext Writes" name="External write beats" description="Number of external bus write beats"/>
+ <event counter="ARM_Mali-T86x_L2_EXT_W_STALL" title="Mali L2 Cache Ext Writes" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T86x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache Ext Writes" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
+
+ </category>
diff --git a/daemon/events-Mali-T88x_hw.xml b/daemon/events-Mali-T88x_hw.xml
new file mode 100644
index 0000000..19385d1
--- /dev/null
+++ b/daemon/events-Mali-T88x_hw.xml
@@ -0,0 +1,117 @@
+
+ <category name="Mali Job Manager" per_cpu="no">
+
+ <event counter="ARM_Mali-T88x_GPU_ACTIVE" title="Mali Job Manager Cycles" name="GPU cycles" description="Number of cycles GPU active"/>
+ <event counter="ARM_Mali-T88x_IRQ_ACTIVE" title="Mali Job Manager Cycles" name="IRQ cycles" description="Number of cycles GPU interrupt pending"/>
+ <event counter="ARM_Mali-T88x_JS0_ACTIVE" title="Mali Job Manager Cycles" name="JS0 cycles" description="Number of cycles JS0 (fragment) active"/>
+ <event counter="ARM_Mali-T88x_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) active"/>
+ <event counter="ARM_Mali-T88x_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) active"/>
+
+ <event counter="ARM_Mali-T88x_JS0_JOBS" title="Mali Job Manager Jobs" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
+ <event counter="ARM_Mali-T88x_JS1_JOBS" title="Mali Job Manager Jobs" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
+ <event counter="ARM_Mali-T88x_JS2_JOBS" title="Mali Job Manager Jobs" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
+
+ <event counter="ARM_Mali-T88x_JS0_TASKS" title="Mali Job Manager Tasks" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
+ <event counter="ARM_Mali-T88x_JS1_TASKS" title="Mali Job Manager Tasks" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
+ <event counter="ARM_Mali-T88x_JS2_TASKS" title="Mali Job Manager Tasks" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
+
+ </category>
+
+ <category name="Mali Tiler" per_cpu="no">
+
+ <event counter="ARM_Mali-T88x_TI_ACTIVE" title="Mali Tiler Cycles" name="Tiler cycles" description="Number of cycles Tiler active"/>
+
+ <event counter="ARM_Mali-T88x_TI_POLYGONS" title="Mali Tiler Primitives" name="Polygons" description="Number of polygons processed"/>
+ <event counter="ARM_Mali-T88x_TI_QUADS" title="Mali Tiler Primitives" name="Quads" description="Number of quads processed"/>
+ <event counter="ARM_Mali-T88x_TI_TRIANGLES" title="Mali Tiler Primitives" name="Triangles" description="Number of triangles processed"/>
+ <event counter="ARM_Mali-T88x_TI_LINES" title="Mali Tiler Primitives" name="Lines" description="Number of lines processed"/>
+ <event counter="ARM_Mali-T88x_TI_POINTS" title="Mali Tiler Primitives" name="Points" description="Number of points processed"/>
+
+ <event counter="ARM_Mali-T88x_TI_FRONT_FACING" title="Mali Tiler Culling" name="Front facing prims" description="Number of front facing primitives"/>
+ <event counter="ARM_Mali-T88x_TI_BACK_FACING" title="Mali Tiler Culling" name="Back facing prims" description="Number of back facing primitives"/>
+ <event counter="ARM_Mali-T88x_TI_PRIM_VISIBLE" title="Mali Tiler Culling" name="Visible prims" description="Number of visible primitives"/>
+ <event counter="ARM_Mali-T88x_TI_PRIM_CULLED" title="Mali Tiler Culling" name="Culled prims" description="Number of culled primitives"/>
+ <event counter="ARM_Mali-T88x_TI_PRIM_CLIPPED" title="Mali Tiler Culling" name="Clipped prims" description="Number of clipped primitives"/>
+
+ <event counter="ARM_Mali-T88x_TI_LEVEL0" title="Mali Tiler Hierarchy" name="L0 prims" description="Number of primitives in hierarchy level 0"/>
+ <event counter="ARM_Mali-T88x_TI_LEVEL1" title="Mali Tiler Hierarchy" name="L1 prims" description="Number of primitives in hierarchy level 1"/>
+ <event counter="ARM_Mali-T88x_TI_LEVEL2" title="Mali Tiler Hierarchy" name="L2 prims" description="Number of primitives in hierarchy level 2"/>
+ <event counter="ARM_Mali-T88x_TI_LEVEL3" title="Mali Tiler Hierarchy" name="L3 prims" description="Number of primitives in hierarchy level 3"/>
+ <event counter="ARM_Mali-T88x_TI_LEVEL4" title="Mali Tiler Hierarchy" name="L4 prims" description="Number of primitives in hierarchy level 4"/>
+ <event counter="ARM_Mali-T88x_TI_LEVEL5" title="Mali Tiler Hierarchy" name="L5 prims" description="Number of primitives in hierarchy level 5"/>
+ <event counter="ARM_Mali-T88x_TI_LEVEL6" title="Mali Tiler Hierarchy" name="L6 prims" description="Number of primitives in hierarchy level 6"/>
+ <event counter="ARM_Mali-T88x_TI_LEVEL7" title="Mali Tiler Hierarchy" name="L7 prims" description="Number of primitives in hierarchy level 7"/>
+
+ </category>
+
+ <category name="Mali Shader Core" per_cpu="no">
+
+ <event counter="ARM_Mali-T88x_TRIPIPE_ACTIVE" title="Mali Core Cycles" name="Tripipe cycles" description="Number of cycles tripipe was active"/>
+ <event counter="ARM_Mali-T88x_FRAG_ACTIVE" title="Mali Core Cycles" name="Fragment cycles" description="Number of cycles fragment processing was active"/>
+ <event counter="ARM_Mali-T88x_COMPUTE_ACTIVE" title="Mali Core Cycles" name="Compute cycles" description="Number of cycles vertex\compute processing was active"/>
+ <event counter="ARM_Mali-T88x_FRAG_CYCLES_NO_TILE" title="Mali Core Cycles" name="Fragment cycles waiting for tile" description="Number of cycles spent waiting for a physical tile buffer"/>
+ <event counter="ARM_Mali-T88x_FRAG_CYCLES_FPKQ_ACTIVE" title="Mali Core Cycles" name="Fragment cycles pre-pipe buffer not empty" description="Number of cycles the pre-pipe queue contains quads"/>
+
+ <event counter="ARM_Mali-T88x_FRAG_THREADS" title="Mali Fragment Threads" name="Fragment threads" description="Number of fragment threads started"/>
+ <event counter="ARM_Mali-T88x_FRAG_DUMMY_THREADS" title="Mali Fragment Threads" name="Dummy fragment threads" description="Number of dummy fragment threads started"/>
+ <event counter="ARM_Mali-T88x_FRAG_THREADS_LZS_TEST" title="Mali Fragment Threads" name="Fragment threads doing late ZS" description="Number of threads doing late ZS test"/>
+ <event counter="ARM_Mali-T88x_FRAG_THREADS_LZS_KILLED" title="Mali Fragment Threads" name="Fragment threads killed late ZS" description="Number of threads killed by late ZS test"/>
+
+ <event counter="ARM_Mali-T88x_COMPUTE_TASKS" title="Mali Compute Tasks" name="Compute tasks" description="Number of compute tasks"/>
+ <event counter="ARM_Mali-T88x_COMPUTE_THREADS" title="Mali Compute Threads" name="Compute threads" description="Number of compute threads started"/>
+
+ <event counter="ARM_Mali-T88x_FRAG_PRIMITIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/>
+ <event counter="ARM_Mali-T88x_FRAG_PRIMITIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/>
+
+ <event counter="ARM_Mali-T88x_FRAG_QUADS_RAST" title="Mali Fragment Quads" name="Quads rasterized" description="Number of quads rasterized"/>
+ <event counter="ARM_Mali-T88x_FRAG_QUADS_EZS_TEST" title="Mali Fragment Quads" name="Quads doing early ZS" description="Number of quads doing early ZS test"/>
+ <event counter="ARM_Mali-T88x_FRAG_QUADS_EZS_KILLED" title="Mali Fragment Quads" name="Quads killed early Z" description="Number of quads killed by early ZS test"/>
+
+ <event counter="ARM_Mali-T88x_FRAG_NUM_TILES" title="Mali Fragment Tasks" name="Tiles rendered" description="Number of tiles rendered"/>
+ <event counter="ARM_Mali-T88x_FRAG_TRANS_ELIM" title="Mali Fragment Tasks" name="Tile writes killed by TE" description="Number of tile writes skipped by transaction elimination"/>
+
+ <event counter="ARM_Mali-T88x_ARITH_WORDS" title="Mali Arithmetic Pipe" name="A instructions" description="Number of instructions completed by the the A-pipe (normalized per pipeline)"/>
+
+ <event counter="ARM_Mali-T88x_LS_WORDS" title="Mali Load/Store Pipe" name="LS instructions" description="Number of instructions completed by the LS-pipe"/>
+ <event counter="ARM_Mali-T88x_LS_ISSUES" title="Mali Load/Store Pipe" name="LS instruction issues" description="Number of instructions issued to the LS-pipe, including restarts"/>
+
+ <event counter="ARM_Mali-T88x_TEX_WORDS" title="Mali Texture Pipe" name="T instructions" description="Number of instructions completed by the T-pipe"/>
+ <event counter="ARM_Mali-T88x_TEX_ISSUES" title="Mali Texture Pipe" name="T instruction issues" description="Number of threads through loop 2 address calculation"/>
+ <event counter="ARM_Mali-T88x_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/>
+
+ <event counter="ARM_Mali-T88x_LSC_READ_OP" title="Mali Load/Store Cache Reads" name="Read operations" description="Number of read operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T88x_LSC_READ_HITS" title="Mali Load/Store Cache Reads" name="Read hits" description="Number of read hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T88x_LSC_WRITE_OP" title="Mali Load/Store Cache Writes" name="Write operations" description="Number of write operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T88x_LSC_WRITE_HITS" title="Mali Load/Store Cache Writes" name="Write hits" description="Number of write hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T88x_LSC_ATOMIC_OP" title="Mali Load/Store Cache Atomics" name="Atomic operations" description="Number of atomic operations in the Load/Store cache"/>
+ <event counter="ARM_Mali-T88x_LSC_ATOMIC_HITS" title="Mali Load/Store Cache Atomics" name="Atomic hits" description="Number of atomic hits in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T88x_LSC_LINE_FETCHES" title="Mali Load/Store Cache Bus" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
+ <event counter="ARM_Mali-T88x_LSC_DIRTY_LINE" title="Mali Load/Store Cache Bus" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
+
+ <event counter="ARM_Mali-T88x_LSC_SNOOPS" title="Mali Load/Store Cache Bus" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
+
+ </category>
+
+ <category name="Mali L2 Cache" per_cpu="no">
+
+ <event counter="ARM_Mali-T88x_L2_READ_LOOKUP" title="Mali L2 Cache Reads" name="L2 read lookups" description="Number of reads into the L2 cache"/>
+ <event counter="ARM_Mali-T88x_L2_READ_SNOOP" title="Mali L2 Cache Reads" name="Read snoops" description="Number of read transaction snoops"/>
+ <event counter="ARM_Mali-T88x_L2_READ_HIT" title="Mali L2 Cache Reads" name="L2 read hits" description="Number of reads hitting in the L2 cache"/>
+
+ <event counter="ARM_Mali-T88x_L2_WRITE_SNOOP" title="Mali L2 Cache Writes" name="Write snoops" description="Number of write transaction snoops"/>
+ <event counter="ARM_Mali-T88x_L2_WRITE_HIT" title="Mali L2 Cache Writes" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
+ <event counter="ARM_Mali-T88x_L2_WRITE_LOOKUP" title="Mali L2 Cache Writes" name="L2 write lookups" description="Number of writes into the L2 cache"/>
+
+ <event counter="ARM_Mali-T88x_L2_EXT_READ_BEATS" title="Mali L2 Cache Ext Reads" name="External read beats" description="Number of external bus read beats"/>
+ <event counter="ARM_Mali-T88x_L2_EXT_AR_STALL" title="Mali L2 Cache Ext Reads" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T88x_L2_EXT_R_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus response buffer full" description="Number of cycles a valid request is blocked by a full response buffer"/>
+ <event counter="ARM_Mali-T88x_L2_EXT_RD_BUF_FULL" title="Mali L2 Cache Ext Reads" name="External bus read data buffer full" description="Number of cycles a valid request is blocked by a full read data buffer"/>
+
+ <event counter="ARM_Mali-T88x_L2_EXT_WRITE_BEATS" title="Mali L2 Cache Ext Writes" name="External write beats" description="Number of external bus write beats"/>
+ <event counter="ARM_Mali-T88x_L2_EXT_W_STALL" title="Mali L2 Cache Ext Writes" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
+ <event counter="ARM_Mali-T88x_L2_EXT_W_BUF_FULL" title="Mali L2 Cache Ext Writes" name="External bus write buffer full" description="Number of cycles a valid request is blocked by a full write buffer"/>
+
+ </category>
diff --git a/daemon/events-Other.xml b/daemon/events-Other.xml
new file mode 100644
index 0000000..8aec282
--- /dev/null
+++ b/daemon/events-Other.xml
@@ -0,0 +1,33 @@
+ <counter_set name="Other_cnt" count="6"/>
+ <category name="Other" counter_set="Other_cnt" per_cpu="yes" supports_event_based_sampling="yes">
+ <event counter="Other_ccnt" event="0xff" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
+ <event event="0x00" title="Software" name="Increment" description="Instruction architecturally executed, condition code check pass, software increment"/>
+ <event event="0x01" title="Cache" name="Instruction refill" description="Level 1 instruction cache refill"/>
+ <event event="0x02" title="Cache" name="Inst TLB refill" description="Level 1 instruction TLB refill"/>
+ <event event="0x03" title="Cache" name="Data refill" description="Level 1 data cache refill"/>
+ <event event="0x04" title="Cache" name="Data access" description="Level 1 data cache access"/>
+ <event event="0x05" title="Cache" name="Data TLB refill" description="Level 1 data TLB refill"/>
+ <event event="0x06" title="Instruction" name="Memory read" description="Instruction architecturally executed, condition code check pass, load"/>
+ <event event="0x07" title="Instruction" name="Memory write" description="Instruction architecturally executed, condition code check pass, store"/>
+ <event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken"/>
+ <event event="0x0a" title="Exception" name="Return" description="Instruction architecturally executed, condition code check pass, exception return"/>
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction architecturally executed, condition code check pass, write to CONTEXTIDR"/>
+ <event event="0x0c" title="Branch" name="PC change" description="Instruction architecturally executed, condition code check pass, software change of the PC"/>
+ <event event="0x0d" title="Branch" name="Immediate" description="Instruction architecturally executed, immediate branch"/>
+ <event event="0x0e" title="Procedure" name="Return" description="Instruction architecturally executed, condition code check pass, procedure return"/>
+ <event event="0x0f" title="Memory" name="Unaligned access" description="Instruction architecturally executed, condition code check pass, unaligned load or store"/>
+ <event event="0x10" title="Branch" name="Mispredicted" description="Mispredicted or not predicted branch speculatively executed"/>
+ <event event="0x12" title="Branch" name="Potential prediction" description="Predictable branch speculatively executed"/>
+ <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
+ <event event="0x14" title="Cache" name="L1 inst access" description="Level 1 instruction cache access"/>
+ <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache write-back"/>
+ <event event="0x16" title="Cache" name="L2 data access" description="Level 2 data cache access"/>
+ <event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/>
+ <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache write-back"/>
+ <event event="0x19" title="Bus" name="Access" description="Bus access"/>
+ <event event="0x1a" title="Memory" name="Error" description="Local memory error"/>
+ <event event="0x1b" title="Instruction" name="Speculative" description="Instruction speculatively executed"/>
+ <event event="0x1c" title="Memory" name="Translation table" description="Instruction architecturally executed, condition code check pass, write to TTBR"/>
+ <event event="0x1d" title="Bus" name="Cycle" description="Bus cycle"/>
+ </category>
diff --git a/daemon/events-ftrace.xml b/daemon/events-ftrace.xml
index 33ab7aa..ae5529f 100644
--- a/daemon/events-ftrace.xml
+++ b/daemon/events-ftrace.xml
@@ -1,7 +1,22 @@
<category name="Ftrace">
- <!-- counter attribute must start with ftrace_ and be unique -->
- <!-- regex item in () is the value shown -->
<!--
- <event counter="ftrace_trace_marker_numbers" title="ftrace" name="trace_marker" class="absolute" regex="([0-9]+)" description="Numbers written to /sys/kernel/debug/tracing/trace_marker, ex: echo 42 > /sys/kernel/debug/tracing/trace_marker"/>
+ Ftrace counters require Linux 3.10 or later. If you do you see ftrace counters in counter configuration, please check your Linux version.
+ 'counter' attribute must start with ftrace_ and be unique
+ the regex item in () is the value shown or, if the parentheses are missing, the number of regex matches is counted
+ 'enable' (optional) is the ftrace event to enable associated with the gator event
-->
+ <!--
+ <event counter="ftrace_trace_marker_numbers" title="ftrace" name="trace_marker" regex="^tracing_mark_write: ([0-9]+)\s$" class="absolute" description="Numbers written to /sys/kernel/debug/tracing/trace_marker, ex: echo 42 > /sys/kernel/debug/tracing/trace_marker"/>
+ -->
+
+ <!-- ftrace counters -->
+ <event counter="ftrace_kmem_kmalloc" title="Kmem" name="kmalloc" regex="^kmalloc:.* bytes_alloc=([0-9]+) " enable="kmem/kmalloc" class="incident" description="Number of bytes allocated in the kernel using kmalloc"/>
+ <event counter="ftrace_ext4_ext4_da_write" title="Ext4" name="ext4_da_write" regex="^ext4_da_write_end:.* len ([0-9]+) " enable="ext4/ext4_da_write_end" class="incident" description="Number of bytes written to an ext4 filesystem"/>
+ <event counter="ftrace_f2fs_f2fs_write" title="F2FS" name="f2fs_write" regex="^f2fs_write_end:.* len ([0-9]+), " enable="f2fs/f2fs_write_end" class="incident" description="Number of bytes written to an f2fs filesystem"/>
+ <event counter="ftrace_power_clock_set_rate" title="Power" name="clock_set_rate" regex="^clock_set_rate:.* state=([0-9]+) " enable="power/clock_set_rate" class="absolute" description="Clock rate state"/>
+
+ <!-- counting ftrace counters -->
+ <event counter="ftrace_block_block_rq_complete" title="Block" name="block_rq_complete" regex="^block_rq_complete: " enable="block/block_rq_complete" class="delta" description="Number of block IO operations completed by device driver"/>
+ <event counter="ftrace_block_block_rq_issue" title="Block" name="block_rq_issue" regex="^block_rq_issue: " enable="block/block_rq_issue" class="delta" description="Number of block IO operations issued to device driver"/>
+ <event counter="ftrace_power_cpu_idle" title="Power" name="cpu_idle" regex="^cpu_idle: " enable="power/cpu_idle" class="delta" description="Number of times cpu_idle is entered or exited"/>
</category>
diff --git a/daemon/main.cpp b/daemon/main.cpp
index fbce1e1..c68a892 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
#include <sys/wait.h>
#include <unistd.h>
+#include "AnnotateListener.h"
#include "CCNDriver.h"
#include "Child.h"
#include "EventsXML.h"
@@ -133,7 +134,7 @@ public:
memset(&mDstAns, 0, sizeof(mDstAns));
memcpy(mDstAns.rviHeader, "STR_ANS ", sizeof(mDstAns.rviHeader));
if (gethostname(mDstAns.dhcpName, sizeof(mDstAns.dhcpName) - 1) != 0) {
- logg->logError(__FILE__, __LINE__, "gethostname failed");
+ logg->logError("gethostname failed");
handleException();
}
// Subvert the defaultGateway field for the port number
@@ -156,7 +157,7 @@ public:
addrlen = sizeof(sockaddr);
read = recvfrom(mReq, &buf, sizeof(buf), 0, (struct sockaddr *)&sockaddr, &addrlen);
if (read < 0) {
- logg->logError(__FILE__, __LINE__, "recvfrom failed");
+ logg->logError("recvfrom failed");
handleException();
} else if ((read == 12) && (memcmp(buf, DST_REQ, sizeof(DST_REQ)) == 0)) {
// Don't care if sendto fails - gatord shouldn't exit because of it and Streamline will retry
@@ -180,23 +181,29 @@ private:
family = AF_INET;
s = socket_cloexec(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) {
- logg->logError(__FILE__, __LINE__, "socket failed");
+ logg->logError("socket failed");
handleException();
}
}
on = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) {
- logg->logError(__FILE__, __LINE__, "setsockopt failed");
+ logg->logError("setsockopt REUSEADDR failed");
handleException();
}
+ // Listen on both IPv4 and IPv6
+ on = 0;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(on)) != 0) {
+ logg->logMessage("setsockopt IPV6_V6ONLY failed");
+ }
+
memset((void*)&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin6_family = family;
sockaddr.sin6_port = htons(port);
sockaddr.sin6_addr = in6addr_any;
if (bind(s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) {
- logg->logError(__FILE__, __LINE__, "socket failed");
+ logg->logError("socket failed");
handleException();
}
@@ -252,7 +259,7 @@ static bool setupFilesystem(char* module) {
// if still mounted
if (access("/dev/gator/buffer", F_OK) == 0) {
- logg->logError(__FILE__, __LINE__, "Unable to remove the running gator.ko. Manually remove the module or use the running module by not specifying one on the commandline");
+ logg->logError("Unable to remove the running gator.ko. Manually remove the module or use the running module by not specifying one on the commandline");
handleException();
}
}
@@ -284,7 +291,7 @@ static bool setupFilesystem(char* module) {
return false;
} else {
// gator location specified on the command line but it was not found
- logg->logError(__FILE__, __LINE__, "gator module not found at %s", location);
+ logg->logError("gator module not found at %s", location);
handleException();
}
}
@@ -296,13 +303,13 @@ static bool setupFilesystem(char* module) {
snprintf(command, sizeof(command), "insmod %s >/dev/null 2>&1", location);
if (system(command) != 0) {
logg->logMessage("Unable to load gator.ko driver with command: %s", command);
- logg->logError(__FILE__, __LINE__, "Unable to load (insmod) gator.ko driver:\n >>> gator.ko must be built against the current kernel version & configuration\n >>> See dmesg for more details");
+ logg->logError("Unable to load (insmod) gator.ko driver:\n >>> gator.ko must be built against the current kernel version & configuration\n >>> See dmesg for more details");
handleException();
}
}
if (mountGatorFS() == -1) {
- logg->logError(__FILE__, __LINE__, "Unable to mount the gator filesystem needed for profiling.");
+ logg->logError("Unable to mount the gator filesystem needed for profiling.");
handleException();
}
}
@@ -326,7 +333,7 @@ static int shutdownFilesystem() {
return 0; // success
}
-static const char OPTSTRING[] = "hvudap:s:c:e:m:o:";
+static const char OPTSTRING[] = "hvVudap:s:c:e:E:m:o:";
static bool hasDebugFlag(int argc, char** argv) {
int c;
@@ -368,11 +375,18 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
case 'e':
gSessionData->mEventsXMLPath = optarg;
break;
+ case 'E':
+ gSessionData->mEventsXMLAppend = optarg;
+ break;
case 'm':
cmdline.module = optarg;
break;
case 'p':
cmdline.port = strtol(optarg, NULL, 10);
+ if ((cmdline.port == 8082) || (cmdline.port == 8083)) {
+ logg->logError("Gator can't use port %i, as it already uses ports 8082 and 8083 for annotations. Please select a different port.", cmdline.port);
+ handleException();
+ }
break;
case 's':
gSessionData->mSessionXMLPath = optarg;
@@ -388,10 +402,11 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
break;
case 'h':
case '?':
- logg->logError(__FILE__, __LINE__,
+ logg->logError(
"%s. All parameters are optional:\n"
- "-c config_xml path and filename of the configuration.xml to use\n"
- "-e events_xml path and filename of the events.xml to use\n"
+ "-c config_xml path and filename of the configuration XML to use\n"
+ "-e events_xml path and filename of the events XML to use\n"
+ "-E events_xml path and filename of events XML to append\n"
"-h this help page\n"
"-m module path and filename of gator.ko\n"
"-p port_number port upon which the server listens; default is 8080\n"
@@ -399,12 +414,16 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
"-o apc_dir path and name of the output for a local capture\n"
"-v version information\n"
"-d enable debug messages\n"
- "-a allow the user user to provide a command to run at the start of a capture"
+ "-a allow the user to issue a command from Streamline"
, version_string);
handleException();
break;
case 'v':
- logg->logError(__FILE__, __LINE__, version_string);
+ logg->logError("%s", version_string);
+ handleException();
+ break;
+ case 'V':
+ logg->logError("%s\nSRC_MD5: %s", version_string, gSrcMd5);
handleException();
break;
}
@@ -412,35 +431,38 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
// Error checking
if (cmdline.port != DEFAULT_PORT && gSessionData->mSessionXMLPath != NULL) {
- logg->logError(__FILE__, __LINE__, "Only a port or a session xml can be specified, not both");
+ logg->logError("Only a port or a session xml can be specified, not both");
handleException();
}
if (gSessionData->mTargetPath != NULL && gSessionData->mSessionXMLPath == NULL) {
- logg->logError(__FILE__, __LINE__, "Missing -s command line option required for a local capture.");
+ logg->logError("Missing -s command line option required for a local capture.");
handleException();
}
if (optind < argc) {
- logg->logError(__FILE__, __LINE__, "Unknown argument: %s. Use '-h' for help.", argv[optind]);
+ logg->logError("Unknown argument: %s. Use '-h' for help.", argv[optind]);
handleException();
}
return cmdline;
}
+static AnnotateListener annotateListener;
+
static void handleClient() {
OlySocket client(sock->acceptConnection());
int pid = fork();
if (pid < 0) {
// Error
- logg->logError(__FILE__, __LINE__, "Fork process failed. Please power cycle the target device if this error persists.");
+ logg->logError("Fork process failed. Please power cycle the target device if this error persists.");
} else if (pid == 0) {
// Child
sock->closeServerSocket();
udpListener.close();
monitor.close();
+ annotateListener.close();
child = new Child(&client, numSessions + 1);
child->run();
delete child;
@@ -500,21 +522,23 @@ int main(int argc, char** argv) {
struct cmdline_t cmdline = parseCommandLine(argc, argv);
if (cmdline.update) {
- return update(argv[0]);
+ update(argv[0]);
+ cmdline.update = false;
+ gSessionData->mAllowCommands = true;
}
// Verify root permissions
uid_t euid = geteuid();
if (euid) {
- logg->logError(__FILE__, __LINE__, "gatord must be launched with root privileges");
+ logg->logError("gatord must be launched with root privileges");
handleException();
}
// Call before setting up the SIGCHLD handler, as system() spawns child processes
if (!setupFilesystem(cmdline.module)) {
- logg->logMessage("Unable to setup gatorfs, trying perf");
+ logg->logMessage("Unable to set up gatorfs, trying perf");
if (!gSessionData->perf.setup()) {
- logg->logError(__FILE__, __LINE__,
+ logg->logError(
"Unable to locate gator.ko driver:\n"
" >>> gator.ko should be co-located with gatord in the same directory\n"
" >>> OR insmod gator.ko prior to launching gatord\n"
@@ -547,15 +571,23 @@ int main(int argc, char** argv) {
child->run();
delete child;
} else {
- gSessionData->annotateListener.setup();
+ annotateListener.setup();
+ int pipefd[2];
+ if (pipe_cloexec(pipefd) != 0) {
+ logg->logError("Unable to set up annotate pipe");
+ handleException();
+ }
+ gSessionData->mAnnotateStart = pipefd[1];
sock = new OlyServerSocket(cmdline.port);
udpListener.setup(cmdline.port);
if (!monitor.init() ||
!monitor.add(sock->getFd()) ||
!monitor.add(udpListener.getReq()) ||
- !monitor.add(gSessionData->annotateListener.getFd()) ||
+ !monitor.add(annotateListener.getSockFd()) ||
+ !monitor.add(annotateListener.getUdsFd()) ||
+ !monitor.add(pipefd[0]) ||
false) {
- logg->logError(__FILE__, __LINE__, "Monitor setup failed");
+ logg->logError("Monitor setup failed");
handleException();
}
// Forever loop, can be exited via a signal or exception
@@ -564,7 +596,7 @@ int main(int argc, char** argv) {
logg->logMessage("Waiting on connection...");
int ready = monitor.wait(events, ARRAY_LENGTH(events), -1);
if (ready < 0) {
- logg->logError(__FILE__, __LINE__, "Monitor::wait failed");
+ logg->logError("Monitor::wait failed");
handleException();
}
for (int i = 0; i < ready; ++i) {
@@ -572,8 +604,16 @@ int main(int argc, char** argv) {
handleClient();
} else if (events[i].data.fd == udpListener.getReq()) {
udpListener.handle();
- } else if (events[i].data.fd == gSessionData->annotateListener.getFd()) {
- gSessionData->annotateListener.handle();
+ } else if (events[i].data.fd == annotateListener.getSockFd()) {
+ annotateListener.handleSock();
+ } else if (events[i].data.fd == annotateListener.getUdsFd()) {
+ annotateListener.handleUds();
+ } else if (events[i].data.fd == pipefd[0]) {
+ uint64_t val;
+ if (read(pipefd[0], &val, sizeof(val)) != sizeof(val)) {
+ logg->logMessage("Reading annotate pipe failed");
+ }
+ annotateListener.signal();
}
}
}
diff --git a/driver/Makefile b/driver/Makefile
index 28d2070..c4c4e6f 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -14,6 +14,7 @@ gator-y := gator_main.o \
gator_events_net.o \
gator_events_perf_pmu.o \
gator_events_sched.o \
+ gator_src_md5.o \
# Convert the old GATOR_WITH_MALI_SUPPORT to the new kernel flags
ifneq ($(GATOR_WITH_MALI_SUPPORT),)
@@ -63,6 +64,20 @@ gator-$(CONFIG_ARM) += gator_events_armv6.o \
gator-$(CONFIG_ARM64) +=
+clean-files := gator_src_md5.c
+
+# Note, in the recipe below we use "cd $(srctree) && cd $(src)" rather than
+# "cd $(srctree)/$(src)" because under DKMS $(src) is an absolute path, and we
+# can't just use $(src) because for normal kernel builds this is relative to
+# $(srctree)
+
+ chk_events.h = :
+ quiet_chk_events.h = echo ' CHK $@'
+silent_chk_events.h = :
+$(obj)/gator_src_md5.c: FORCE
+ @$($(quiet)chk_events.h)
+ $(Q)cd $(srctree) && cd $(src) ; $(CONFIG_SHELL) -c "echo 'char *gator_src_md5 = \"'\`ls *.c *.h mali/*.h | grep -Ev '^(gator_src_md5\.c|gator\.mod\.c)$$' | LC_ALL=C sort | xargs cat | md5sum | cut -b 1-32\`'\";'" > $(@F)
+
else
all:
@@ -73,7 +88,7 @@ all:
$(error)
clean:
- rm -f *.o .*.cmd modules.order Module.symvers gator.ko gator.mod.c
+ rm -f *.o .*.cmd gator_src_md5.c modules.order Module.symvers gator.ko gator.mod.c
rm -rf .tmp_versions
endif
diff --git a/driver/gator.h b/driver/gator.h
index 64173ec..202eb41 100644
--- a/driver/gator.h
+++ b/driver/gator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -21,26 +21,26 @@
#define GATOR_IKS_SUPPORT defined(CONFIG_BL_SWITCHER)
/* cpu ids */
-#define ARM1136 0xb36
-#define ARM1156 0xb56
-#define ARM1176 0xb76
-#define ARM11MPCORE 0xb02
-#define CORTEX_A5 0xc05
-#define CORTEX_A7 0xc07
-#define CORTEX_A8 0xc08
-#define CORTEX_A9 0xc09
-#define CORTEX_A15 0xc0f
-#define CORTEX_A17 0xc0e
-#define SCORPION 0x00f
-#define SCORPIONMP 0x02d
-#define KRAITSIM 0x049
-#define KRAIT 0x04d
-#define KRAIT_S4_PRO 0x06f
-#define CORTEX_A53 0xd03
-#define CORTEX_A57 0xd07
-#define CORTEX_A72 0xd08
-#define AARCH64 0xd0f
-#define OTHER 0xfff
+#define ARM1136 0x41b36
+#define ARM1156 0x41b56
+#define ARM1176 0x41b76
+#define ARM11MPCORE 0x41b02
+#define CORTEX_A5 0x41c05
+#define CORTEX_A7 0x41c07
+#define CORTEX_A8 0x41c08
+#define CORTEX_A9 0x41c09
+#define CORTEX_A15 0x41c0f
+#define CORTEX_A12 0x41c0d
+#define CORTEX_A17 0x41c0e
+#define SCORPION 0x5100f
+#define SCORPIONMP 0x5102d
+#define KRAITSIM 0x51049
+#define KRAIT 0x5104d
+#define KRAIT_S4_PRO 0x5106f
+#define CORTEX_A53 0x41d03
+#define CORTEX_A57 0x41d07
+#define CORTEX_A72 0x41d08
+#define OTHER 0xfffff
/* gpu enums */
#define MALI_4xx 1
diff --git a/driver/gator_annotate.c b/driver/gator_annotate.c
index ff9a3ce..cc9ae02 100644
--- a/driver/gator_annotate.c
+++ b/driver/gator_annotate.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_annotate_kernel.c b/driver/gator_annotate_kernel.c
index 69471f9..54e8e86 100644
--- a/driver/gator_annotate_kernel.c
+++ b/driver/gator_annotate_kernel.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2012-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c
index 76c941d..5557ec0 100644
--- a/driver/gator_backtrace.c
+++ b/driver/gator_backtrace.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_buffer.c b/driver/gator_buffer.c
index 910d5aa..f335457 100644
--- a/driver/gator_buffer.c
+++ b/driver/gator_buffer.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_buffer_write.c b/driver/gator_buffer_write.c
index 654ec60..b731e6a 100644
--- a/driver/gator_buffer_write.c
+++ b/driver/gator_buffer_write.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_cookies.c b/driver/gator_cookies.c
index c43cce8..9bd4c8b 100644
--- a/driver/gator_cookies.c
+++ b/driver/gator_cookies.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_armv6.c b/driver/gator_events_armv6.c
index a157a00..1783970 100644
--- a/driver/gator_events_armv6.c
+++ b/driver/gator_events_armv6.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_armv7.c b/driver/gator_events_armv7.c
index 09c9422..e1f6a5f 100644
--- a/driver/gator_events_armv7.c
+++ b/driver/gator_events_armv7.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_block.c b/driver/gator_events_block.c
index a352a54..b3467b1 100644
--- a/driver/gator_events_block.c
+++ b/driver/gator_events_block.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_irq.c b/driver/gator_events_irq.c
index 5221aac..81b976a 100644
--- a/driver/gator_events_irq.c
+++ b/driver/gator_events_irq.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_l2c-310.c b/driver/gator_events_l2c-310.c
index 73aaac3..063a060 100644
--- a/driver/gator_events_l2c-310.c
+++ b/driver/gator_events_l2c-310.c
@@ -1,7 +1,7 @@
/**
* l2c310 (L2 Cache Controller) event counters for gator
*
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_mali_4xx.c b/driver/gator_events_mali_4xx.c
index 9cf43fe..423b4e0 100644
--- a/driver/gator_events_mali_4xx.c
+++ b/driver/gator_events_mali_4xx.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_mali_4xx.h b/driver/gator_events_mali_4xx.h
index 976ca8c..8f6a870 100644
--- a/driver/gator_events_mali_4xx.h
+++ b/driver/gator_events_mali_4xx.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2011-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_mali_common.c b/driver/gator_events_mali_common.c
index 1af87d6..7741f25 100644
--- a/driver/gator_events_mali_common.c
+++ b/driver/gator_events_mali_common.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2012-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_mali_common.h b/driver/gator_events_mali_common.h
index e7082e6..a4fc9d7 100644
--- a/driver/gator_events_mali_common.h
+++ b/driver/gator_events_mali_common.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2012-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_mali_midgard.c b/driver/gator_events_mali_midgard.c
index 0aec906..3b0963a 100644
--- a/driver/gator_events_mali_midgard.c
+++ b/driver/gator_events_mali_midgard.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2011-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_mali_midgard_hw.c b/driver/gator_events_mali_midgard_hw.c
index cada130..7e1eee3 100644
--- a/driver/gator_events_mali_midgard_hw.c
+++ b/driver/gator_events_mali_midgard_hw.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2012-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -18,7 +18,7 @@
/* Mali Midgard DDK includes */
#if defined(MALI_SIMPLE_API)
/* Header with wrapper functions to kbase structures and functions */
-#include "mali/mali_kbase_gator_api.h"
+#include "mali_kbase_gator_api.h"
#elif defined(MALI_DIR_MIDGARD)
/* New DDK Directory structure with kernel/drivers/gpu/arm/midgard */
#include "mali_linux_trace.h"
@@ -40,6 +40,10 @@
#error MALI_DDK_GATOR_API_VERSION is invalid (must be 1 for r1/r2 DDK, or 2 for r3/r4 DDK, or 3 for r5 and later DDK).
#endif
+#if !defined(CONFIG_MALI_GATOR_SUPPORT)
+#error CONFIG_MALI_GATOR_SUPPORT is required for GPU activity and software counters
+#endif
+
#include "gator_events_mali_common.h"
/*
@@ -842,17 +846,17 @@ static int read(int **buffer, bool sched_switch)
return -1;
/* Mali symbols can be called safely since a kbcontext is valid */
- if (kbase_gator_instr_hwcnt_dump_complete_symbol(handles, &success) == MALI_TRUE) {
+ if (kbase_gator_instr_hwcnt_dump_complete_symbol(handles, &success)) {
#else
if (!kbcontext)
return -1;
/* Mali symbols can be called safely since a kbcontext is valid */
- if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE) {
+ if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success)) {
#endif
kbase_device_busy = false;
- if (success == MALI_TRUE) {
+ if (success) {
/* Cycle through hardware counters and accumulate totals */
for (cnt = 0; cnt < number_of_hardware_counters; cnt++) {
const struct mali_counter *counter = &counters[cnt];
diff --git a/driver/gator_events_mali_midgard_hw_test.c b/driver/gator_events_mali_midgard_hw_test.c
index 31a91e1..87c569c 100644
--- a/driver/gator_events_mali_midgard_hw_test.c
+++ b/driver/gator_events_mali_midgard_hw_test.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2012-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_meminfo.c b/driver/gator_events_meminfo.c
index c625ac5..985b312 100644
--- a/driver/gator_events_meminfo.c
+++ b/driver/gator_events_meminfo.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -58,6 +58,8 @@ static ulong proc_enabled[PROC_COUNT];
static ulong proc_keys[PROC_COUNT];
static DEFINE_PER_CPU(long long, proc_buffer[2 * (PROC_COUNT + 3)]);
+static void do_read(void);
+
#if USE_THREAD
static int gator_meminfo_func(void *data);
@@ -177,6 +179,7 @@ static int gator_events_meminfo_start(void)
if (GATOR_REGISTER_TRACE(mm_page_alloc))
goto mm_page_alloc_exit;
+ do_read();
#if USE_THREAD
/* Start worker thread */
gator_meminfo_run = true;
diff --git a/driver/gator_events_mmapped.c b/driver/gator_events_mmapped.c
index 6b2af99..7b51761 100644
--- a/driver/gator_events_mmapped.c
+++ b/driver/gator_events_mmapped.c
@@ -1,7 +1,7 @@
/*
* Example events provider
*
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_net.c b/driver/gator_events_net.c
index d21b4db..1e36731 100644
--- a/driver/gator_events_net.c
+++ b/driver/gator_events_net.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_perf_pmu.c b/driver/gator_events_perf_pmu.c
index 47cf278..f6b4f18 100644
--- a/driver/gator_events_perf_pmu.c
+++ b/driver/gator_events_perf_pmu.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -23,11 +23,13 @@ extern bool event_based_sampling;
/* Maximum number of per-core counters - currently reserves enough space for two full hardware PMUs for big.LITTLE */
#define CNTMAX 16
#define CCI_400 4
+#define CCI_500 8
#define CCN_5XX 8
/* Maximum number of uncore counters */
/* + 1 for the cci-400 cycles counter */
+/* cci-500 has no cycles counter */
/* + 1 for the CCN-5xx cycles counter */
-#define UCCNT (CCI_400 + 1 + CCN_5XX + 1)
+#define UCCNT (CCI_400 + 1 + CCI_500 + CCN_5XX + 1)
/* Default to 0 if unable to probe the revision which was the previous behavior */
#define DEFAULT_CCI_REVISION 0
@@ -58,9 +60,9 @@ static struct gator_attr uc_attrs[UCCNT];
static int uc_attr_count;
struct gator_event {
- int curr;
- int prev;
- int prev_delta;
+ uint32_t curr;
+ uint32_t prev;
+ uint32_t prev_delta;
bool zero;
struct perf_event *pevent;
struct perf_event_attr *pevent_attr;
@@ -315,7 +317,7 @@ static void gator_events_perf_pmu_stop(void)
static void __read(int *const len, int cpu, struct gator_attr *const attr, struct gator_event *const event)
{
- int delta;
+ uint32_t delta;
struct perf_event *const ev = event->pevent;
if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) {
@@ -341,8 +343,6 @@ static void __read(int *const len, int cpu, struct gator_attr *const attr, struc
event->prev_delta = delta;
event->prev = event->curr;
per_cpu(perf_cnt, cpu)[(*len)++] = attr->key;
- if (delta < 0)
- delta *= -1;
per_cpu(perf_cnt, cpu)[(*len)++] = delta;
}
}
@@ -436,13 +436,15 @@ static int probe_cci_revision(void)
#endif
-static void gator_events_perf_pmu_uncore_init(const char *const name, const int type, const int count)
+static void gator_events_perf_pmu_uncore_init(const char *const name, const int type, const int count, const bool has_cycles_counter)
{
int cnt;
- snprintf(uc_attrs[uc_attr_count].name, sizeof(uc_attrs[uc_attr_count].name), "%s_ccnt", name);
- uc_attrs[uc_attr_count].type = type;
- ++uc_attr_count;
+ if (has_cycles_counter) {
+ snprintf(uc_attrs[uc_attr_count].name, sizeof(uc_attrs[uc_attr_count].name), "%s_ccnt", name);
+ uc_attrs[uc_attr_count].type = type;
+ ++uc_attr_count;
+ }
for (cnt = 0; cnt < count; ++cnt, ++uc_attr_count) {
struct gator_attr *const attr = &uc_attrs[uc_attr_count];
@@ -452,7 +454,7 @@ static void gator_events_perf_pmu_uncore_init(const char *const name, const int
}
}
-static void gator_events_perf_pmu_cci_init(const int type)
+static void gator_events_perf_pmu_cci_400_init(const int type)
{
const char *cci_name;
@@ -468,7 +470,7 @@ static void gator_events_perf_pmu_cci_init(const int type)
return;
}
- gator_events_perf_pmu_uncore_init(cci_name, type, CCI_400);
+ gator_events_perf_pmu_uncore_init(cci_name, type, CCI_400, true);
}
static void gator_events_perf_pmu_cpu_init(const struct gator_cpu *const gator_cpu, const int type)
@@ -535,9 +537,11 @@ int gator_events_perf_pmu_init(void)
if (pe->pmu != NULL && type == pe->pmu->type) {
if (strcmp("CCI", pe->pmu->name) == 0 || strcmp("CCI_400", pe->pmu->name) == 0 || strcmp("CCI_400-r1", pe->pmu->name) == 0) {
- gator_events_perf_pmu_cci_init(type);
+ gator_events_perf_pmu_cci_400_init(type);
+ } else if (strcmp("CCI_500", pe->pmu->name) == 0) {
+ gator_events_perf_pmu_uncore_init("CCI_500", type, CCI_500, false);
} else if (strcmp("ccn", pe->pmu->name) == 0) {
- gator_events_perf_pmu_uncore_init("ARM_CCN_5XX", type, CCN_5XX);
+ gator_events_perf_pmu_uncore_init("ARM_CCN_5XX", type, CCN_5XX, true);
} else if ((gator_cpu = gator_find_cpu_by_pmu_name(pe->pmu->name)) != NULL) {
found_cpu = true;
gator_events_perf_pmu_cpu_init(gator_cpu, type);
@@ -549,10 +553,15 @@ int gator_events_perf_pmu_init(void)
}
if (!found_cpu) {
- const struct gator_cpu *const gator_cpu = gator_find_cpu_by_cpuid(gator_cpuid());
+ const struct gator_cpu *gator_cpu = gator_find_cpu_by_cpuid(gator_cpuid());
- if (gator_cpu == NULL)
- return -1;
+ if (gator_cpu == NULL) {
+ gator_cpu = gator_find_cpu_by_cpuid(OTHER);
+ if (gator_cpu == NULL) {
+ pr_err("gator: Didn't find cpu\n");
+ return -1;
+ }
+ }
gator_events_perf_pmu_cpu_init(gator_cpu, PERF_TYPE_RAW);
}
diff --git a/driver/gator_events_sched.c b/driver/gator_events_sched.c
index 637107d..463d834 100644
--- a/driver/gator_events_sched.c
+++ b/driver/gator_events_sched.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_events_scorpion.c b/driver/gator_events_scorpion.c
index 4921936..b51dcd3 100644
--- a/driver/gator_events_scorpion.c
+++ b/driver/gator_events_scorpion.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2011-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_hrtimer_gator.c b/driver/gator_hrtimer_gator.c
index c1525e1..36961f8 100644
--- a/driver/gator_hrtimer_gator.c
+++ b/driver/gator_hrtimer_gator.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2011-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_iks.c b/driver/gator_iks.c
index fb78c10..80535c7 100644
--- a/driver/gator_iks.c
+++ b/driver/gator_iks.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_main.c b/driver/gator_main.c
index 2bb3e87..1dcca0e 100644
--- a/driver/gator_main.c
+++ b/driver/gator_main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -8,7 +8,7 @@
*/
/* This version must match the gator daemon version */
-#define PROTOCOL_VERSION 20
+#define PROTOCOL_VERSION 21
static unsigned long gator_protocol_version = PROTOCOL_VERSION;
#include <linux/slab.h>
@@ -92,21 +92,17 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION;
/* Name Frame Messages */
#define MESSAGE_COOKIE 1
#define MESSAGE_THREAD_NAME 2
-#define MESSAGE_LINK 4
/* Scheduler Trace Frame Messages */
#define MESSAGE_SCHED_SWITCH 1
#define MESSAGE_SCHED_EXIT 2
-/* Idle Frame Messages */
-#define MESSAGE_IDLE_ENTER 1
-#define MESSAGE_IDLE_EXIT 2
-
/* Summary Frame Messages */
#define MESSAGE_SUMMARY 1
#define MESSAGE_CORE_NAME 3
/* Activity Frame Messages */
+#define MESSAGE_LINK 1
#define MESSAGE_SWITCH 2
#define MESSAGE_EXIT 3
@@ -267,6 +263,10 @@ GATOR_EVENTS_LIST
* Misc
******************************************************************************/
+MODULE_PARM_DESC(gator_src_md5, "Gator driver source code md5sum");
+extern char *gator_src_md5;
+module_param_named(src_md5, gator_src_md5, charp, 0444);
+
static const struct gator_cpu gator_cpus[] = {
{
.cpuid = ARM1136,
@@ -332,6 +332,13 @@ static const struct gator_cpu gator_cpus[] = {
.pmnc_counters = 6,
},
{
+ .cpuid = CORTEX_A12,
+ .core_name = "Cortex-A17",
+ .pmnc_name = "ARMv7_Cortex_A17",
+ .dt_name = "arm,cortex-a17",
+ .pmnc_counters = 6,
+ },
+ {
.cpuid = CORTEX_A17,
.core_name = "Cortex-A17",
.pmnc_name = "ARMv7_Cortex_A17",
@@ -390,12 +397,6 @@ static const struct gator_cpu gator_cpus[] = {
.pmnc_counters = 6,
},
{
- .cpuid = AARCH64,
- .core_name = "AArch64",
- .pmnc_name = "ARM_AArch64",
- .pmnc_counters = 6,
- },
- {
.cpuid = OTHER,
.core_name = "Other",
.pmnc_name = "Other",
@@ -450,7 +451,7 @@ u32 gator_cpuid(void)
#else
asm volatile("mrs %0, midr_el1" : "=r" (val));
#endif
- return (val >> 4) & 0xfff;
+ return ((val & 0xff000000) >> 12) | ((val & 0xfff0) >> 4);
#else
return OTHER;
#endif
@@ -604,7 +605,7 @@ static void gator_send_core_name(const int cpu, const u32 cpuid)
if (cpuid == -1)
snprintf(core_name_buf, sizeof(core_name_buf), "Unknown");
else
- snprintf(core_name_buf, sizeof(core_name_buf), "Unknown (0x%.3x)", cpuid);
+ snprintf(core_name_buf, sizeof(core_name_buf), "Unknown (0x%.5x)", cpuid);
core_name = core_name_buf;
}
@@ -874,7 +875,9 @@ static void gator_summary(void)
marshal_summary(timestamp, uptime, gator_monotonic_started, uname_buf);
gator_sync_time = 0;
- gator_emit_perf_time(gator_monotonic_started);
+ gator_emit_perf_time(gator_monotonic_started);
+ /* Always flush COUNTER_BUF so that the initial perf_time is received before it's used */
+ gator_commit_buffer(get_physical_cpu(), COUNTER_BUF, 0);
preempt_enable();
}
diff --git a/driver/gator_marshaling.c b/driver/gator_marshaling.c
index 0d11676..f5b8184 100644
--- a/driver/gator_marshaling.c
+++ b/driver/gator_marshaling.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2012-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -107,16 +107,16 @@ static void marshal_link(int cookie, int tgid, int pid)
local_irq_save(flags);
time = gator_get_time();
- if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
- gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_LINK);
- gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
- gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
- gator_buffer_write_packed_int(cpu, NAME_BUF, tgid);
- gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
+ if (buffer_check_space(cpu, ACTIVITY_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
+ gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, MESSAGE_LINK);
+ gator_buffer_write_packed_int64(cpu, ACTIVITY_BUF, time);
+ gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, cookie);
+ gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, tgid);
+ gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, pid);
}
local_irq_restore(flags);
/* Check and commit; commit is set to occur once buffer is 3/4 full */
- buffer_check(cpu, NAME_BUF, time);
+ buffer_check(cpu, ACTIVITY_BUF, time);
}
static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, u64 time)
diff --git a/driver/gator_trace_gpu.c b/driver/gator_trace_gpu.c
index 5de9152..d9b82ee 100644
--- a/driver/gator_trace_gpu.c
+++ b/driver/gator_trace_gpu.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/gator_trace_power.c b/driver/gator_trace_power.c
index 46e04b2..aaa8f86 100644
--- a/driver/gator_trace_power.c
+++ b/driver/gator_trace_power.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2011-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -80,13 +80,7 @@ GATOR_DEFINE_PROBE(cpu_idle, TP_PROTO(unsigned int state, unsigned int cpu))
return;
if (implements_wfi()) {
- if (state == PWR_EVENT_EXIT) {
- /* transition from wfi to non-wfi */
- marshal_idle(cpu, MESSAGE_IDLE_EXIT);
- } else {
- /* transition from non-wfi to wfi */
- marshal_idle(cpu, MESSAGE_IDLE_ENTER);
- }
+ marshal_idle(cpu, state);
}
per_cpu(idle_prev_state, cpu) = state;
diff --git a/driver/gator_trace_sched.c b/driver/gator_trace_sched.c
index 6d7cbd7..ad7c39e 100644
--- a/driver/gator_trace_sched.c
+++ b/driver/gator_trace_sched.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/mali/mali_kbase_gator_api.h b/driver/mali/mali_kbase_gator_api.h
deleted file mode 100644
index 5ed0697..0000000
--- a/driver/mali/mali_kbase_gator_api.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/**
- * Copyright (C) ARM Limited 2014. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef _KBASE_GATOR_API_H_
-#define _KBASE_GATOR_API_H_
-
-/**
- * @brief This file describes the API used by Gator to collect hardware counters data from a Mali device.
- */
-
-/* This define is used by the gator kernel module compile to select which DDK
- * API calling convention to use. If not defined (legacy DDK) gator assumes
- * version 1. The version to DDK release mapping is:
- * Version 1 API: DDK versions r1px, r2px
- * Version 2 API: DDK versions r3px, r4px
- * Version 3 API: DDK version r5p0 and newer
- *
- * API Usage
- * =========
- *
- * 1] Call kbase_gator_hwcnt_init_names() to return the list of short counter
- * names for the GPU present in this device.
- *
- * 2] Create a kbase_gator_hwcnt_info structure and set the counter enables for
- * the counters you want enabled. The enables can all be set for simplicity in
- * most use cases, but disabling some will let you minimize bandwidth impact.
- *
- * 3] Call kbase_gator_hwcnt_init() using the above structure, to create a
- * counter context. On successful return the DDK will have populated the
- * structure with a variety of useful information.
- *
- * 4] Call kbase_gator_hwcnt_dump_irq() to queue a non-blocking request for a
- * counter dump. If this returns a non-zero value the request has been queued,
- * otherwise the driver has been unable to do so (typically because of another
- * user of the instrumentation exists concurrently).
- *
- * 5] Call kbase_gator_hwcnt_dump_complete() to test whether the previously
- * requested dump has been succesful. If this returns non-zero the counter dump
- * has resolved, but the value of *success must also be tested as the dump
- * may have not been successful. If it returns zero the counter dump was
- * abandoned due to the device being busy (typically because of another
- * user of the instrumentation exists concurrently).
- *
- * 6] Process the counters stored in the buffer pointed to by ...
- *
- * kbase_gator_hwcnt_info->kernel_dump_buffer
- *
- * In pseudo code you can find all of the counters via this approach:
- *
- *
- * hwcnt_info # pointer to kbase_gator_hwcnt_info structure
- * hwcnt_name # pointer to name list
- *
- * u32 * hwcnt_data = (u32*)hwcnt_info->kernel_dump_buffer
- *
- * # Iterate over each 64-counter block in this GPU configuration
- * for( i = 0; i < hwcnt_info->nr_hwc_blocks; i++) {
- * hwc_type type = hwcnt_info->hwc_layout[i];
- *
- * # Skip reserved type blocks - they contain no counters at all
- * if( type == RESERVED_BLOCK ) {
- * continue;
- * }
- *
- * size_t name_offset = type * 64;
- * size_t data_offset = i * 64;
- *
- * # Iterate over the names of the counters in this block type
- * for( j = 0; j < 64; j++) {
- * const char * name = hwcnt_name[name_offset+j];
- *
- * # Skip empty name strings - there is no counter here
- * if( name[0] == '\0' ) {
- * continue;
- * }
- *
- * u32 data = hwcnt_data[data_offset+j];
- *
- * printk( "COUNTER: %s DATA: %u\n", name, data );
- * }
- * }
- *
- *
- * Note that in most implementations you typically want to either SUM or
- * AVERAGE multiple instances of the same counter if, for example, you have
- * multiple shader cores or multiple L2 caches. The most sensible view for
- * analysis is to AVERAGE shader core counters, but SUM L2 cache and MMU
- * counters.
- *
- * 7] Goto 4, repeating until you want to stop collecting counters.
- *
- * 8] Release the dump resources by calling kbase_gator_hwcnt_term().
- *
- * 9] Release the name table resources by calling kbase_gator_hwcnt_term_names().
- * This function must only be called if init_names() returned a non-NULL value.
- **/
-
-#define MALI_DDK_GATOR_API_VERSION 3
-
-#if !defined(MALI_TRUE)
- #define MALI_TRUE ((uint32_t)1)
-#endif
-
-#if !defined(MALI_FALSE)
- #define MALI_FALSE ((uint32_t)0)
-#endif
-
-enum hwc_type {
- JM_BLOCK = 0,
- TILER_BLOCK,
- SHADER_BLOCK,
- MMU_L2_BLOCK,
- RESERVED_BLOCK
-};
-
-struct kbase_gator_hwcnt_info {
-
- /* Passed from Gator to kbase */
-
- /* the bitmask of enabled hardware counters for each counter block */
- uint16_t bitmask[4];
-
- /* Passed from kbase to Gator */
-
- /* ptr to counter dump memory */
- void *kernel_dump_buffer;
-
- /* size of counter dump memory */
- uint32_t size;
-
- /* the ID of the Mali device */
- uint32_t gpu_id;
-
- /* the number of shader cores in the GPU */
- uint32_t nr_cores;
-
- /* the number of core groups */
- uint32_t nr_core_groups;
-
- /* the memory layout of the performance counters */
- enum hwc_type *hwc_layout;
-
- /* the total number of hardware couter blocks */
- uint32_t nr_hwc_blocks;
-};
-
-/**
- * @brief Opaque block of Mali data which Gator needs to return to the API later.
- */
-struct kbase_gator_hwcnt_handles;
-
-/**
- * @brief Initialize the resources Gator needs for performance profiling.
- *
- * @param in_out_info A pointer to a structure containing the enabled counters passed from Gator and all the Mali
- * specific information that will be returned to Gator. On entry Gator must have populated the
- * 'bitmask' field with the counters it wishes to enable for each class of counter block.
- * Each entry in the array corresponds to a single counter class based on the "hwc_type"
- * enumeration, and each bit corresponds to an enable for 4 sequential counters (LSB enables
- * the first 4 counters in the block, and so on). See the GPU counter array as returned by
- * kbase_gator_hwcnt_get_names() for the index values of each counter for the curernt GPU.
- *
- * @return Pointer to an opaque handle block on success, NULL on error.
- */
-extern struct kbase_gator_hwcnt_handles *kbase_gator_hwcnt_init(struct kbase_gator_hwcnt_info *in_out_info);
-
-/**
- * @brief Free all resources once Gator has finished using performance counters.
- *
- * @param in_out_info A pointer to a structure containing the enabled counters passed from Gator and all the
- * Mali specific information that will be returned to Gator.
- * @param opaque_handles A wrapper structure for kbase structures.
- */
-extern void kbase_gator_hwcnt_term(struct kbase_gator_hwcnt_info *in_out_info, struct kbase_gator_hwcnt_handles *opaque_handles);
-
-/**
- * @brief Poll whether a counter dump is successful.
- *
- * @param opaque_handles A wrapper structure for kbase structures.
- * @param[out] success Non-zero on success, zero on failure.
- *
- * @return Zero if the dump is still pending, non-zero if the dump has completed. Note that a
- * completed dump may not have dumped succesfully, so the caller must test for both
- * a completed and successful dump before processing counters.
- */
-extern uint32_t kbase_gator_instr_hwcnt_dump_complete(struct kbase_gator_hwcnt_handles *opaque_handles, uint32_t * const success);
-
-/**
- * @brief Request the generation of a new counter dump.
- *
- * @param opaque_handles A wrapper structure for kbase structures.
- *
- * @return Zero if the hardware device is busy and cannot handle the request, non-zero otherwise.
- */
-extern uint32_t kbase_gator_instr_hwcnt_dump_irq(struct kbase_gator_hwcnt_handles *opaque_handles);
-
-/**
- * @brief This function is used to fetch the names table based on the Mali device in use.
- *
- * @param[out] total_number_of_counters The total number of counters short names in the Mali devices' list.
- *
- * @return Pointer to an array of strings of length *total_number_of_counters.
- */
-extern const char * const *kbase_gator_hwcnt_init_names(uint32_t *total_number_of_counters);
-
-/**
- * @brief This function is used to terminate the use of the names table.
- *
- * This function must only be called if the initial call to kbase_gator_hwcnt_init_names returned a non-NULL value.
- */
-extern void kbase_gator_hwcnt_term_names(void);
-
-#endif
diff --git a/driver/mali/mali_mjollnir_profiling_gator_api.h b/driver/mali/mali_mjollnir_profiling_gator_api.h
index 2bc0b03..a5d1651 100644
--- a/driver/mali/mali_mjollnir_profiling_gator_api.h
+++ b/driver/mali/mali_mjollnir_profiling_gator_api.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/mali/mali_utgard_profiling_gator_api.h b/driver/mali/mali_utgard_profiling_gator_api.h
index d646531..f550490 100644
--- a/driver/mali/mali_utgard_profiling_gator_api.h
+++ b/driver/mali/mali_utgard_profiling_gator_api.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/driver/mali_midgard.mk b/driver/mali_midgard.mk
index 1b784d5..b0076c2 100644
--- a/driver/mali_midgard.mk
+++ b/driver/mali_midgard.mk
@@ -23,6 +23,7 @@ endif
ifneq ($(wildcard $(DDK_DIR)/drivers/gpu/arm/midgard/mali_kbase_gator_api.h),)
EXTRA_CFLAGS += -DMALI_SIMPLE_API=1
+EXTRA_CFLAGS += -I$(DDK_DIR)/drivers/gpu/arm/midgard
endif
UMP_DIR = $(DDK_DIR)/include/linux