diff options
author | Jon Medhurst | 2012-11-05 05:20:25 -0600 |
---|---|---|
committer | Jon Medhurst | 2012-11-05 05:20:25 -0600 |
commit | 197f43d9c9c94dec5f05cb93047d9d10f7915265 (patch) | |
tree | cb05e23addd88c9601e1cc7b5eab0ffd4838f2a9 | |
parent | 408ffc1cdebaf3a34d3815077860fb8c3bbaf2e8 (diff) | |
parent | ee4f56e0d75f42583505dd338d1b91e67ff0ab53 (diff) | |
download | arm-ds5-gator-197f43d9c9c94dec5f05cb93047d9d10f7915265.tar.gz arm-ds5-gator-197f43d9c9c94dec5f05cb93047d9d10f7915265.tar.xz arm-ds5-gator-197f43d9c9c94dec5f05cb93047d9d10f7915265.zip |
Merge branch 'master' into android
58 files changed, 1048 insertions, 956 deletions
diff --git a/daemon/CapturedXML.cpp b/daemon/CapturedXML.cpp index f02ed2a..30d984f 100644 --- a/daemon/CapturedXML.cpp +++ b/daemon/CapturedXML.cpp | |||
@@ -22,12 +22,12 @@ CapturedXML::CapturedXML() { | |||
22 | CapturedXML::~CapturedXML() { | 22 | CapturedXML::~CapturedXML() { |
23 | } | 23 | } |
24 | 24 | ||
25 | mxml_node_t* CapturedXML::getTree() { | 25 | mxml_node_t* CapturedXML::getTree(bool includeTime) { |
26 | bool perfCounters = false; | 26 | bool perfCounters = false; |
27 | mxml_node_t *xml; | 27 | mxml_node_t *xml; |
28 | mxml_node_t *captured; | 28 | mxml_node_t *captured; |
29 | mxml_node_t *target; | 29 | mxml_node_t *target; |
30 | mxml_node_t *counters; | 30 | mxml_node_t *counters; |
31 | mxml_node_t *counter; | 31 | mxml_node_t *counter; |
32 | int x; | 32 | int x; |
33 | 33 | ||
@@ -43,11 +43,10 @@ mxml_node_t* CapturedXML::getTree() { | |||
43 | captured = mxmlNewElement(xml, "captured"); | 43 | captured = mxmlNewElement(xml, "captured"); |
44 | mxmlElementSetAttr(captured, "version", "1"); | 44 | mxmlElementSetAttr(captured, "version", "1"); |
45 | mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION); | 45 | mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION); |
46 | if (gSessionData->mBytes > 0) { // Send the following only after the capture is complete | 46 | if (includeTime) { // Send the following only after the capture is complete |
47 | if (time(NULL) > 1267000000) { // If the time is reasonable (after Feb 23, 2010) | 47 | if (time(NULL) > 1267000000) { // If the time is reasonable (after Feb 23, 2010) |
48 | mxmlElementSetAttrf(captured, "created", "%lu", time(NULL)); // Valid until the year 2038 | 48 | mxmlElementSetAttrf(captured, "created", "%lu", time(NULL)); // Valid until the year 2038 |
49 | } | 49 | } |
50 | mxmlElementSetAttrf(captured, "bytes", "%d", gSessionData->mBytes); | ||
51 | } | 50 | } |
52 | 51 | ||
53 | target = mxmlNewElement(captured, "target"); | 52 | target = mxmlNewElement(captured, "target"); |
@@ -69,18 +68,9 @@ mxml_node_t* CapturedXML::getTree() { | |||
69 | if (gSessionData->mPerfCounterPerCPU[x]) { | 68 | if (gSessionData->mPerfCounterPerCPU[x]) { |
70 | mxmlElementSetAttr(counter, "per_cpu", "yes"); | 69 | mxmlElementSetAttr(counter, "per_cpu", "yes"); |
71 | } | 70 | } |
72 | if (strlen(gSessionData->mPerfCounterOperation[x]) > 0) { | ||
73 | mxmlElementSetAttr(counter, "operation", gSessionData->mPerfCounterOperation[x]); | ||
74 | } | ||
75 | if (gSessionData->mPerfCounterCount[x] > 0) { | 71 | if (gSessionData->mPerfCounterCount[x] > 0) { |
76 | mxmlElementSetAttrf(counter, "count", "%d", gSessionData->mPerfCounterCount[x]); | 72 | mxmlElementSetAttrf(counter, "count", "%d", gSessionData->mPerfCounterCount[x]); |
77 | } | 73 | } |
78 | if (gSessionData->mPerfCounterLevel[x]) { | ||
79 | mxmlElementSetAttr(counter, "level", "yes"); | ||
80 | } | ||
81 | if (strlen(gSessionData->mPerfCounterAlias[x]) > 0) { | ||
82 | mxmlElementSetAttr(counter, "alias", gSessionData->mPerfCounterAlias[x]); | ||
83 | } | ||
84 | if (strlen(gSessionData->mPerfCounterDisplay[x]) > 0) { | 74 | if (strlen(gSessionData->mPerfCounterDisplay[x]) > 0) { |
85 | mxmlElementSetAttr(counter, "display", gSessionData->mPerfCounterDisplay[x]); | 75 | mxmlElementSetAttr(counter, "display", gSessionData->mPerfCounterDisplay[x]); |
86 | } | 76 | } |
@@ -98,9 +88,9 @@ mxml_node_t* CapturedXML::getTree() { | |||
98 | return xml; | 88 | return xml; |
99 | } | 89 | } |
100 | 90 | ||
101 | char* CapturedXML::getXML() { | 91 | char* CapturedXML::getXML(bool includeTime) { |
102 | char* xml_string; | 92 | char* xml_string; |
103 | mxml_node_t *xml = getTree(); | 93 | mxml_node_t *xml = getTree(includeTime); |
104 | xml_string = mxmlSaveAllocString(xml, mxmlWhitespaceCB); | 94 | xml_string = mxmlSaveAllocString(xml, mxmlWhitespaceCB); |
105 | mxmlDelete(xml); | 95 | mxmlDelete(xml); |
106 | return xml_string; | 96 | return xml_string; |
@@ -112,7 +102,7 @@ void CapturedXML::write(char* path) { | |||
112 | // Set full path | 102 | // Set full path |
113 | snprintf(file, PATH_MAX, "%s/captured.xml", path); | 103 | snprintf(file, PATH_MAX, "%s/captured.xml", path); |
114 | 104 | ||
115 | char* xml = getXML(); | 105 | char* xml = getXML(true); |
116 | if (util->writeToDisk(file, xml) < 0) { | 106 | if (util->writeToDisk(file, xml) < 0) { |
117 | logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file); | 107 | logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file); |
118 | handleException(); | 108 | handleException(); |
diff --git a/daemon/CapturedXML.h b/daemon/CapturedXML.h index 984d1f2..3f6a4de 100644 --- a/daemon/CapturedXML.h +++ b/daemon/CapturedXML.h | |||
@@ -16,10 +16,10 @@ class CapturedXML { | |||
16 | public: | 16 | public: |
17 | CapturedXML(); | 17 | CapturedXML(); |
18 | ~CapturedXML(); | 18 | ~CapturedXML(); |
19 | char* getXML(); // the string should be freed by the caller | 19 | char* getXML(bool includeTime); // the string should be freed by the caller |
20 | void write(char* path); | 20 | void write(char* path); |
21 | private: | 21 | private: |
22 | mxml_node_t* getTree(); | 22 | mxml_node_t* getTree(bool includeTime); |
23 | }; | 23 | }; |
24 | 24 | ||
25 | #endif //__CAPTURED_XML_H__ | 25 | #endif //__CAPTURED_XML_H__ |
diff --git a/daemon/Child.cpp b/daemon/Child.cpp index 2c7c292..b97e0db 100644 --- a/daemon/Child.cpp +++ b/daemon/Child.cpp | |||
@@ -102,7 +102,10 @@ void* stopThread(void* pVoid) { | |||
102 | prctl(PR_SET_NAME, (unsigned long)&"gatord-stopper", 0, 0, 0); | 102 | prctl(PR_SET_NAME, (unsigned long)&"gatord-stopper", 0, 0, 0); |
103 | while (gSessionData->mSessionIsActive) { | 103 | while (gSessionData->mSessionIsActive) { |
104 | // This thread will stall until the APC_STOP or PING command is received over the socket or the socket is disconnected | 104 | // This thread will stall until the APC_STOP or PING command is received over the socket or the socket is disconnected |
105 | if (socket->receiveNBytes(&type, sizeof(type)) > 0) { | 105 | const int result = socket->receiveNBytes(&type, sizeof(type)); |
106 | if (result == -1) { | ||
107 | child->endSession(); | ||
108 | } else if (result > 0) { | ||
106 | if ((type != COMMAND_APC_STOP) && (type != COMMAND_PING)) { | 109 | if ((type != COMMAND_APC_STOP) && (type != COMMAND_PING)) { |
107 | logg->logMessage("INVESTIGATE: Received unknown command type %d", type); | 110 | logg->logMessage("INVESTIGATE: Received unknown command type %d", type); |
108 | } else { | 111 | } else { |
@@ -228,7 +231,7 @@ void Child::run() { | |||
228 | } | 231 | } |
229 | gSessionData->parseSessionXML(xmlString); | 232 | gSessionData->parseSessionXML(xmlString); |
230 | localCapture = new LocalCapture(); | 233 | localCapture = new LocalCapture(); |
231 | localCapture->createAPCDirectory(gSessionData->mTargetPath, gSessionData->mTitle); | 234 | localCapture->createAPCDirectory(gSessionData->mTargetPath); |
232 | localCapture->copyImages(gSessionData->mImages); | 235 | localCapture->copyImages(gSessionData->mImages); |
233 | localCapture->write(xmlString); | 236 | localCapture->write(xmlString); |
234 | sender->createDataFile(gSessionData->mAPCDir); | 237 | sender->createDataFile(gSessionData->mAPCDir); |
diff --git a/daemon/Collector.cpp b/daemon/Collector.cpp index d29cd16..25bb934 100644 --- a/daemon/Collector.cpp +++ b/daemon/Collector.cpp | |||
@@ -202,7 +202,10 @@ void Collector::stop() { | |||
202 | 202 | ||
203 | int Collector::collect(char* buffer) { | 203 | int Collector::collect(char* buffer) { |
204 | // Calls event_buffer_read in the driver | 204 | // Calls event_buffer_read in the driver |
205 | int bytesRead = read(mBufferFD, buffer, mBufferSize); | 205 | int bytesRead; |
206 | |||
207 | errno = 0; | ||
208 | bytesRead = read(mBufferFD, buffer, mBufferSize); | ||
206 | 209 | ||
207 | // If read() returned due to an interrupt signal, re-read to obtain the last bit of collected data | 210 | // If read() returned due to an interrupt signal, re-read to obtain the last bit of collected data |
208 | if (bytesRead == -1 && errno == EINTR) { | 211 | if (bytesRead == -1 && errno == EINTR) { |
diff --git a/daemon/ConfigurationXML.cpp b/daemon/ConfigurationXML.cpp index 145ddbd..a213cbb 100644 --- a/daemon/ConfigurationXML.cpp +++ b/daemon/ConfigurationXML.cpp | |||
@@ -21,20 +21,19 @@ static const char* ATTR_REVISION = "revision"; | |||
21 | static const char* ATTR_TITLE = "title"; | 21 | static const char* ATTR_TITLE = "title"; |
22 | static const char* ATTR_NAME = "name"; | 22 | static const char* ATTR_NAME = "name"; |
23 | static const char* ATTR_EVENT = "event"; | 23 | static const char* ATTR_EVENT = "event"; |
24 | static const char* ATTR_COLOR = "color"; | ||
25 | static const char* ATTR_COUNT = "count"; | 24 | static const char* ATTR_COUNT = "count"; |
26 | static const char* ATTR_OPERATION = "operation"; | ||
27 | static const char* ATTR_PER_CPU = "per_cpu"; | 25 | static const char* ATTR_PER_CPU = "per_cpu"; |
28 | static const char* ATTR_DESCRIPTION = "description"; | 26 | static const char* ATTR_DESCRIPTION = "description"; |
29 | static const char* ATTR_EBS = "event_based_sampling"; | 27 | static const char* ATTR_EBS = "supports_event_based_sampling"; |
30 | static const char* ATTR_LEVEL = "level"; | ||
31 | static const char* ATTR_ALIAS = "alias"; | ||
32 | static const char* ATTR_DISPLAY = "display"; | 28 | static const char* ATTR_DISPLAY = "display"; |
33 | static const char* ATTR_UNITS = "units"; | 29 | static const char* ATTR_UNITS = "units"; |
34 | static const char* ATTR_AVERAGE_SELECTION = "average_selection"; | 30 | static const char* ATTR_AVERAGE_SELECTION = "average_selection"; |
35 | 31 | ||
36 | ConfigurationXML::ConfigurationXML() { | 32 | ConfigurationXML::ConfigurationXML() { |
37 | #include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len | 33 | const char * configuration_xml; |
34 | unsigned int configuration_xml_len; | ||
35 | getDefaultConfigurationXml(configuration_xml, configuration_xml_len); | ||
36 | |||
38 | mIndex = 0; | 37 | mIndex = 0; |
39 | char* path = (char*)malloc(PATH_MAX); | 38 | char* path = (char*)malloc(PATH_MAX); |
40 | 39 | ||
@@ -61,6 +60,9 @@ ConfigurationXML::ConfigurationXML() { | |||
61 | gSessionData->mPerfCounterEnabled[i] = 0; | 60 | gSessionData->mPerfCounterEnabled[i] = 0; |
62 | } | 61 | } |
63 | 62 | ||
63 | // clear counter overflow | ||
64 | gSessionData->mCounterOverflow = false; | ||
65 | |||
64 | int ret = parse(mConfigurationXML); | 66 | int ret = parse(mConfigurationXML); |
65 | if (ret == 1) { | 67 | if (ret == 1) { |
66 | // remove configuration.xml on disk to use the default | 68 | // remove configuration.xml on disk to use the default |
@@ -151,8 +153,8 @@ int ConfigurationXML::configurationsTag(mxml_node_t *node) { | |||
151 | void ConfigurationXML::configurationTag(mxml_node_t *node) { | 153 | void ConfigurationXML::configurationTag(mxml_node_t *node) { |
152 | // handle all other performance counters | 154 | // handle all other performance counters |
153 | if (mIndex >= MAX_PERFORMANCE_COUNTERS) { | 155 | if (mIndex >= MAX_PERFORMANCE_COUNTERS) { |
154 | logg->logError(__FILE__, __LINE__, "Exceeded maximum number of %d performance counters", MAX_PERFORMANCE_COUNTERS); | 156 | gSessionData->mCounterOverflow = true; |
155 | handleException(); | 157 | return; |
156 | } | 158 | } |
157 | 159 | ||
158 | // read attributes | 160 | // read attributes |
@@ -162,12 +164,8 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) { | |||
162 | if (mxmlElementGetAttr(node, ATTR_DESCRIPTION)) strncpy(gSessionData->mPerfCounterDescription[mIndex], mxmlElementGetAttr(node, ATTR_DESCRIPTION), sizeof(gSessionData->mPerfCounterDescription[mIndex])); | 164 | if (mxmlElementGetAttr(node, ATTR_DESCRIPTION)) strncpy(gSessionData->mPerfCounterDescription[mIndex], mxmlElementGetAttr(node, ATTR_DESCRIPTION), sizeof(gSessionData->mPerfCounterDescription[mIndex])); |
163 | if (mxmlElementGetAttr(node, ATTR_EVENT)) gSessionData->mPerfCounterEvent[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_EVENT), NULL, 16); | 165 | if (mxmlElementGetAttr(node, ATTR_EVENT)) gSessionData->mPerfCounterEvent[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_EVENT), NULL, 16); |
164 | if (mxmlElementGetAttr(node, ATTR_COUNT)) gSessionData->mPerfCounterCount[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_COUNT), NULL, 10); | 166 | if (mxmlElementGetAttr(node, ATTR_COUNT)) gSessionData->mPerfCounterCount[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_COUNT), NULL, 10); |
165 | if (mxmlElementGetAttr(node, ATTR_COLOR)) gSessionData->mPerfCounterColor[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_COLOR), NULL, 16); | ||
166 | if (mxmlElementGetAttr(node, ATTR_PER_CPU)) gSessionData->mPerfCounterPerCPU[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_PER_CPU), false); | 167 | if (mxmlElementGetAttr(node, ATTR_PER_CPU)) gSessionData->mPerfCounterPerCPU[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_PER_CPU), false); |
167 | if (mxmlElementGetAttr(node, ATTR_EBS)) gSessionData->mPerfCounterEBSCapable[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_EBS), false); | 168 | if (mxmlElementGetAttr(node, ATTR_EBS)) gSessionData->mPerfCounterEBSCapable[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_EBS), false); |
168 | if (mxmlElementGetAttr(node, ATTR_OPERATION)) strncpy(gSessionData->mPerfCounterOperation[mIndex], mxmlElementGetAttr(node, ATTR_OPERATION), sizeof(gSessionData->mPerfCounterOperation[mIndex])); | ||
169 | if (mxmlElementGetAttr(node, ATTR_LEVEL)) gSessionData->mPerfCounterLevel[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_LEVEL), false); | ||
170 | if (mxmlElementGetAttr(node, ATTR_ALIAS)) strncpy(gSessionData->mPerfCounterAlias[mIndex], mxmlElementGetAttr(node, ATTR_ALIAS), sizeof(gSessionData->mPerfCounterAlias[mIndex])); | ||
171 | if (mxmlElementGetAttr(node, ATTR_DISPLAY)) strncpy(gSessionData->mPerfCounterDisplay[mIndex], mxmlElementGetAttr(node, ATTR_DISPLAY), sizeof(gSessionData->mPerfCounterDisplay[mIndex])); | 169 | if (mxmlElementGetAttr(node, ATTR_DISPLAY)) strncpy(gSessionData->mPerfCounterDisplay[mIndex], mxmlElementGetAttr(node, ATTR_DISPLAY), sizeof(gSessionData->mPerfCounterDisplay[mIndex])); |
172 | if (mxmlElementGetAttr(node, ATTR_UNITS)) strncpy(gSessionData->mPerfCounterUnits[mIndex], mxmlElementGetAttr(node, ATTR_UNITS), sizeof(gSessionData->mPerfCounterUnits[mIndex])); | 170 | if (mxmlElementGetAttr(node, ATTR_UNITS)) strncpy(gSessionData->mPerfCounterUnits[mIndex], mxmlElementGetAttr(node, ATTR_UNITS), sizeof(gSessionData->mPerfCounterUnits[mIndex])); |
173 | if (mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION)) gSessionData->mPerfCounterAverageSelection[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION), false); | 171 | if (mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION)) gSessionData->mPerfCounterAverageSelection[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION), false); |
@@ -178,11 +176,17 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) { | |||
178 | gSessionData->mPerfCounterTitle[mIndex][sizeof(gSessionData->mPerfCounterTitle[mIndex]) - 1] = 0; | 176 | gSessionData->mPerfCounterTitle[mIndex][sizeof(gSessionData->mPerfCounterTitle[mIndex]) - 1] = 0; |
179 | gSessionData->mPerfCounterName[mIndex][sizeof(gSessionData->mPerfCounterName[mIndex]) - 1] = 0; | 177 | gSessionData->mPerfCounterName[mIndex][sizeof(gSessionData->mPerfCounterName[mIndex]) - 1] = 0; |
180 | gSessionData->mPerfCounterDescription[mIndex][sizeof(gSessionData->mPerfCounterDescription[mIndex]) - 1] = 0; | 178 | gSessionData->mPerfCounterDescription[mIndex][sizeof(gSessionData->mPerfCounterDescription[mIndex]) - 1] = 0; |
181 | gSessionData->mPerfCounterOperation[mIndex][sizeof(gSessionData->mPerfCounterOperation[mIndex]) - 1] = 0; | ||
182 | gSessionData->mPerfCounterAlias[mIndex][sizeof(gSessionData->mPerfCounterAlias[mIndex]) - 1] = 0; | ||
183 | gSessionData->mPerfCounterDisplay[mIndex][sizeof(gSessionData->mPerfCounterDisplay[mIndex]) - 1] = 0; | 179 | gSessionData->mPerfCounterDisplay[mIndex][sizeof(gSessionData->mPerfCounterDisplay[mIndex]) - 1] = 0; |
184 | gSessionData->mPerfCounterUnits[mIndex][sizeof(gSessionData->mPerfCounterUnits[mIndex]) - 1] = 0; | 180 | gSessionData->mPerfCounterUnits[mIndex][sizeof(gSessionData->mPerfCounterUnits[mIndex]) - 1] = 0; |
185 | 181 | ||
186 | // update counter index | 182 | // update counter index |
187 | mIndex++; | 183 | mIndex++; |
188 | } | 184 | } |
185 | |||
186 | void ConfigurationXML::getDefaultConfigurationXml(const char * & xml, unsigned int & len) { | ||
187 | // the first line of configuration_xml.h is "unsigned char configuration_xml", but configuration_xml needs to be const static as well | ||
188 | const static | ||
189 | #include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len | ||
190 | xml = (const char *)configuration_xml; | ||
191 | len = configuration_xml_len; | ||
192 | } | ||
diff --git a/daemon/ConfigurationXML.h b/daemon/ConfigurationXML.h index b48d32f..66ad587 100644 --- a/daemon/ConfigurationXML.h +++ b/daemon/ConfigurationXML.h | |||
@@ -13,10 +13,13 @@ | |||
13 | 13 | ||
14 | class ConfigurationXML { | 14 | class ConfigurationXML { |
15 | public: | 15 | public: |
16 | static void getDefaultConfigurationXml(const char * & xml, unsigned int & len); | ||
17 | |||
16 | ConfigurationXML(); | 18 | ConfigurationXML(); |
17 | ~ConfigurationXML(); | 19 | ~ConfigurationXML(); |
18 | const char* getConfigurationXML() {return mConfigurationXML;} | 20 | const char* getConfigurationXML() {return mConfigurationXML;} |
19 | void validate(void); | 21 | void validate(void); |
22 | |||
20 | private: | 23 | private: |
21 | char* mConfigurationXML; | 24 | char* mConfigurationXML; |
22 | int mIndex; | 25 | int mIndex; |
diff --git a/daemon/LocalCapture.cpp b/daemon/LocalCapture.cpp index 6449d03..f8cd17f 100644 --- a/daemon/LocalCapture.cpp +++ b/daemon/LocalCapture.cpp | |||
@@ -23,8 +23,8 @@ LocalCapture::LocalCapture() {} | |||
23 | 23 | ||
24 | LocalCapture::~LocalCapture() {} | 24 | LocalCapture::~LocalCapture() {} |
25 | 25 | ||
26 | void LocalCapture::createAPCDirectory(char* target_path, char* name) { | 26 | void LocalCapture::createAPCDirectory(char* target_path) { |
27 | gSessionData->mAPCDir = createUniqueDirectory(target_path, ".apc", name); | 27 | gSessionData->mAPCDir = createUniqueDirectory(target_path, ".apc"); |
28 | if ((removeDirAndAllContents(gSessionData->mAPCDir) != 0 || mkdir(gSessionData->mAPCDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)) { | 28 | if ((removeDirAndAllContents(gSessionData->mAPCDir) != 0 || mkdir(gSessionData->mAPCDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)) { |
29 | logg->logError(__FILE__, __LINE__, "Unable to create directory %s", gSessionData->mAPCDir); | 29 | logg->logError(__FILE__, __LINE__, "Unable to create directory %s", gSessionData->mAPCDir); |
30 | handleException(); | 30 | handleException(); |
@@ -46,17 +46,14 @@ void LocalCapture::write(char* string) { | |||
46 | free(file); | 46 | free(file); |
47 | } | 47 | } |
48 | 48 | ||
49 | char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* ending, char* title) { | 49 | char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* ending) { |
50 | int i; | ||
51 | char* output; | 50 | char* output; |
52 | char* path = (char*)malloc(PATH_MAX); | 51 | char* path = (char*)malloc(PATH_MAX); |
53 | 52 | ||
54 | // Ensure the path is an absolute path, i.e. starts with a slash | 53 | // Ensure the path is an absolute path, i.e. starts with a slash |
55 | if (initialPath == 0 || strlen(initialPath) == 0) { | 54 | if (initialPath == 0 || strlen(initialPath) == 0) { |
56 | if (getcwd(path, PATH_MAX) == 0) { | 55 | logg->logError(__FILE__, __LINE__, "Missing -o command line option required for a local capture."); |
57 | logg->logMessage("Unable to retrive the current working directory"); | 56 | handleException(); |
58 | } | ||
59 | strncat(path, "/@F_@N", PATH_MAX - strlen(path) - 1); | ||
60 | } else if (initialPath[0] != '/') { | 57 | } else if (initialPath[0] != '/') { |
61 | if (getcwd(path, PATH_MAX) == 0) { | 58 | if (getcwd(path, PATH_MAX) == 0) { |
62 | logg->logMessage("Unable to retrive the current working directory"); | 59 | logg->logMessage("Unable to retrive the current working directory"); |
@@ -68,98 +65,17 @@ char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* e | |||
68 | path[PATH_MAX - 1] = 0; // strncpy does not guarantee a null-terminated string | 65 | path[PATH_MAX - 1] = 0; // strncpy does not guarantee a null-terminated string |
69 | } | 66 | } |
70 | 67 | ||
71 | // Convert to uppercase | ||
72 | replaceAll(path, "@f", "@F", PATH_MAX); | ||
73 | replaceAll(path, "@n", "@N", PATH_MAX); | ||
74 | |||
75 | // Replace @F with the session xml title | ||
76 | replaceAll(path, "@F", title, PATH_MAX); | ||
77 | |||
78 | // Add ending if it is not already there | 68 | // Add ending if it is not already there |
79 | if (strcmp(&path[strlen(path) - strlen(ending)], ending) != 0) { | 69 | if (strcmp(&path[strlen(path) - strlen(ending)], ending) != 0) { |
80 | strncat(path, ending, PATH_MAX - strlen(path) - 1); | 70 | strncat(path, ending, PATH_MAX - strlen(path) - 1); |
81 | } | 71 | } |
82 | 72 | ||
83 | // Replace @N with a unique integer | 73 | output = strdup(path); |
84 | if (strstr(path, "@N")) { | ||
85 | char* tempPath = (char*)malloc(PATH_MAX); | ||
86 | for (i = 1; i < 1000; i++) { | ||
87 | char number[4]; | ||
88 | snprintf(number, sizeof(number), "%03d", i); | ||
89 | strcpy(tempPath, path); | ||
90 | replaceAll(tempPath, "@N", number, PATH_MAX); | ||
91 | struct stat mFileInfo; | ||
92 | if (stat(tempPath, &mFileInfo) != 0) { | ||
93 | // if the direcotry does not exist, break | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | if (i == 1000) { | ||
99 | logg->logError(__FILE__, __LINE__, "Unable to create .apc directory, please delete older directories."); | ||
100 | handleException(); | ||
101 | } | ||
102 | |||
103 | output = strdup(tempPath); | ||
104 | free(tempPath); | ||
105 | } else { | ||
106 | output = strdup(path); | ||
107 | } | ||
108 | 74 | ||
109 | free(path); | 75 | free(path); |
110 | return output; | 76 | return output; |
111 | } | 77 | } |
112 | 78 | ||
113 | //Replaces all occurrences of <find> in <target> with <replace> provided enough <size> is available | ||
114 | void LocalCapture::replaceAll(char* target, const char* find, const char* replace, unsigned int size) { | ||
115 | char* nextOccurrence; | ||
116 | unsigned int count = 0; | ||
117 | |||
118 | // Duplicate the original string | ||
119 | char* original = strdup(target); | ||
120 | char* ptr = original; | ||
121 | |||
122 | // Determine number of <find>s | ||
123 | ptr = strstr(ptr, find); | ||
124 | while (ptr) { | ||
125 | count++; | ||
126 | ptr += strlen(find); | ||
127 | ptr = strstr(ptr, find); | ||
128 | } | ||
129 | |||
130 | // Is there enough space available | ||
131 | if (strlen(target) + (strlen(replace) - strlen(find)) * count > size - 1) { | ||
132 | free(original); | ||
133 | return; | ||
134 | } | ||
135 | |||
136 | // Reset | ||
137 | ptr = original; | ||
138 | |||
139 | nextOccurrence = strstr(ptr, find); | ||
140 | while (nextOccurrence) { | ||
141 | // Move pointers to location of replace | ||
142 | int length = nextOccurrence - ptr; | ||
143 | target += length; | ||
144 | ptr += length; | ||
145 | |||
146 | // Replace <find> with <replace> | ||
147 | memcpy(target, replace, strlen(replace)); | ||
148 | |||
149 | // Increment over <replace>/<find> | ||
150 | target += strlen(replace); | ||
151 | ptr += strlen(find); | ||
152 | |||
153 | // Copy remainder of ptr | ||
154 | strcpy(target, ptr); | ||
155 | |||
156 | // Get next occurrence | ||
157 | nextOccurrence = strstr(ptr, find); | ||
158 | } | ||
159 | |||
160 | free(original); | ||
161 | } | ||
162 | |||
163 | int LocalCapture::removeDirAndAllContents(char* path) { | 79 | int LocalCapture::removeDirAndAllContents(char* path) { |
164 | int error = 0; | 80 | int error = 0; |
165 | struct stat mFileInfo; | 81 | struct stat mFileInfo; |
diff --git a/daemon/LocalCapture.h b/daemon/LocalCapture.h index ca37f6e..40f7883 100644 --- a/daemon/LocalCapture.h +++ b/daemon/LocalCapture.h | |||
@@ -17,10 +17,9 @@ public: | |||
17 | ~LocalCapture(); | 17 | ~LocalCapture(); |
18 | void write(char* string); | 18 | void write(char* string); |
19 | void copyImages(ImageLinkList* ptr); | 19 | void copyImages(ImageLinkList* ptr); |
20 | void createAPCDirectory(char* target_path, char* name); | 20 | void createAPCDirectory(char* target_path); |
21 | private: | 21 | private: |
22 | char* createUniqueDirectory(const char* path, const char* ending, char* title); | 22 | char* createUniqueDirectory(const char* path, const char* ending); |
23 | void replaceAll(char* target, const char* find, const char* replace, unsigned int size); | ||
24 | int removeDirAndAllContents(char* path); | 23 | int removeDirAndAllContents(char* path); |
25 | }; | 24 | }; |
26 | 25 | ||
diff --git a/daemon/Makefile b/daemon/Makefile index b62a223..5562db7 100644 --- a/daemon/Makefile +++ b/daemon/Makefile | |||
@@ -3,7 +3,11 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Uncomment and define CROSS_COMPILE if it is not already defined | 5 | # Uncomment and define CROSS_COMPILE if it is not already defined |
6 | # CROSS_COMPILE=/path/to/cross-compiler/arm-none-linux-gnueabi- | 6 | # CROSS_COMPILE=/path/to/cross-compiler/arm-linux-gnueabihf- |
7 | # NOTE: This toolchain uses the hardfloat abi by default. For non-hardfloat | ||
8 | # targets it is necessary to add options | ||
9 | # '-marm -march=armv4t -mfloat-abi=soft'. | ||
10 | |||
7 | ARCH=arm | 11 | ARCH=arm |
8 | 12 | ||
9 | CPP=$(CROSS_COMPILE)g++ | 13 | CPP=$(CROSS_COMPILE)g++ |
@@ -17,7 +21,10 @@ GCC=$(CROSS_COMPILE)gcc | |||
17 | # -std=c++0x is the planned new c++ standard | 21 | # -std=c++0x is the planned new c++ standard |
18 | # -std=c++98 is the 1998 c++ standard | 22 | # -std=c++98 is the 1998 c++ standard |
19 | # -mthumb-interwork is required for interworking to ARM or Thumb stdlibc | 23 | # -mthumb-interwork is required for interworking to ARM or Thumb stdlibc |
20 | CFLAGS=-O3 -Wall -Werror -Wno-error=sequence-point -mthumb-interwork | 24 | CFLAGS=-O3 -Wall -mthumb-interwork |
25 | ifeq ($(WERROR),1) | ||
26 | CFLAGS += -Werror | ||
27 | endif | ||
21 | # -s strips the binary of debug info | 28 | # -s strips the binary of debug info |
22 | LDFLAGS=-s | 29 | LDFLAGS=-s |
23 | TARGET=gatord | 30 | TARGET=gatord |
diff --git a/daemon/OlyUtility.cpp b/daemon/OlyUtility.cpp index c72b0d1..adc7aba 100644 --- a/daemon/OlyUtility.cpp +++ b/daemon/OlyUtility.cpp | |||
@@ -24,6 +24,10 @@ OlyUtility* util = NULL; | |||
24 | bool OlyUtility::stringToBool(const char* string, bool defValue) { | 24 | bool OlyUtility::stringToBool(const char* string, bool defValue) { |
25 | char value[32]; | 25 | char value[32]; |
26 | 26 | ||
27 | if (string == NULL) { | ||
28 | return defValue; | ||
29 | } | ||
30 | |||
27 | strncpy(value, string, sizeof(value)); | 31 | strncpy(value, string, sizeof(value)); |
28 | if (value[0] == 0) { | 32 | if (value[0] == 0) { |
29 | return defValue; | 33 | return defValue; |
diff --git a/daemon/Sender.cpp b/daemon/Sender.cpp index efff753..eba8343 100644 --- a/daemon/Sender.cpp +++ b/daemon/Sender.cpp | |||
@@ -38,8 +38,9 @@ Sender::Sender(OlySocket* socket) { | |||
38 | } | 38 | } |
39 | 39 | ||
40 | // Send magic sequence - must be done first, afterwhich error messages can be sent | 40 | // Send magic sequence - must be done first, afterwhich error messages can be sent |
41 | char magic[] = {'G', 'A', 'T', 'O', 'R', '\n'}; | 41 | char magic[32]; |
42 | mDataSocket->send(magic, sizeof(magic)); | 42 | snprintf(magic, 32, "GATOR %i\n", PROTOCOL_VERSION); |
43 | mDataSocket->send(magic, strlen(magic)); | ||
43 | 44 | ||
44 | gSessionData->mWaitingOnCommand = true; | 45 | gSessionData->mWaitingOnCommand = true; |
45 | logg->logMessage("Completed magic sequence"); | 46 | logg->logMessage("Completed magic sequence"); |
diff --git a/daemon/Sender.h b/daemon/Sender.h index 98467e0..ceab343 100644 --- a/daemon/Sender.h +++ b/daemon/Sender.h | |||
@@ -14,7 +14,6 @@ | |||
14 | #include "OlySocket.h" | 14 | #include "OlySocket.h" |
15 | 15 | ||
16 | enum { | 16 | enum { |
17 | RESPONSE_END = 0, // unused | ||
18 | RESPONSE_XML = 1, | 17 | RESPONSE_XML = 1, |
19 | RESPONSE_APC_DATA = 3, | 18 | RESPONSE_APC_DATA = 3, |
20 | RESPONSE_ACK = 4, | 19 | RESPONSE_ACK = 4, |
diff --git a/daemon/SessionData.cpp b/daemon/SessionData.cpp index a245369..5aa3f11 100644 --- a/daemon/SessionData.cpp +++ b/daemon/SessionData.cpp | |||
@@ -30,10 +30,10 @@ void SessionData::initialize() { | |||
30 | mConfigurationXMLPath = NULL; | 30 | mConfigurationXMLPath = NULL; |
31 | mSessionXMLPath = NULL; | 31 | mSessionXMLPath = NULL; |
32 | mEventsXMLPath = NULL; | 32 | mEventsXMLPath = NULL; |
33 | mTargetPath = NULL; | ||
33 | mAPCDir = NULL; | 34 | mAPCDir = NULL; |
34 | mSampleRate = 0; | 35 | mSampleRate = 0; |
35 | mDuration = 0; | 36 | mDuration = 0; |
36 | mBytes = 0; | ||
37 | mBacktraceDepth = 0; | 37 | mBacktraceDepth = 0; |
38 | mTotalBufferSize = 0; | 38 | mTotalBufferSize = 0; |
39 | mCores = 1; | 39 | mCores = 1; |
@@ -48,8 +48,6 @@ void SessionData::initializeCounters() { | |||
48 | mPerfCounterTitle[i][0] = 0; | 48 | mPerfCounterTitle[i][0] = 0; |
49 | mPerfCounterName[i][0] = 0; | 49 | mPerfCounterName[i][0] = 0; |
50 | mPerfCounterDescription[i][0] = 0; | 50 | mPerfCounterDescription[i][0] = 0; |
51 | mPerfCounterOperation[i][0] = 0; | ||
52 | mPerfCounterAlias[i][0] = 0; | ||
53 | mPerfCounterDisplay[i][0] = 0; | 51 | mPerfCounterDisplay[i][0] = 0; |
54 | mPerfCounterUnits[i][0] = 0; | 52 | mPerfCounterUnits[i][0] = 0; |
55 | mPerfCounterEnabled[i] = 0; | 53 | mPerfCounterEnabled[i] = 0; |
@@ -59,7 +57,6 @@ void SessionData::initializeCounters() { | |||
59 | mPerfCounterCount[i] = 0; | 57 | mPerfCounterCount[i] = 0; |
60 | mPerfCounterPerCPU[i] = false; | 58 | mPerfCounterPerCPU[i] = false; |
61 | mPerfCounterEBSCapable[i] = false; | 59 | mPerfCounterEBSCapable[i] = false; |
62 | mPerfCounterLevel[i] = false; | ||
63 | mPerfCounterAverageSelection[i] = false; | 60 | mPerfCounterAverageSelection[i] = false; |
64 | } | 61 | } |
65 | } | 62 | } |
@@ -68,15 +65,6 @@ void SessionData::parseSessionXML(char* xmlString) { | |||
68 | SessionXML session(xmlString); | 65 | SessionXML session(xmlString); |
69 | session.parse(); | 66 | session.parse(); |
70 | 67 | ||
71 | // Parameter error checking | ||
72 | if (session.parameters.output_path == 0 && session.parameters.target_path == 0) { | ||
73 | logg->logError(__FILE__, __LINE__, "No capture path (target or host) was provided."); | ||
74 | handleException(); | ||
75 | } else if (gSessionData->mLocalCapture && session.parameters.target_path == 0) { | ||
76 | logg->logError(__FILE__, __LINE__, "Missing target_path tag in session xml required for a local capture."); | ||
77 | handleException(); | ||
78 | } | ||
79 | |||
80 | // Set session data values | 68 | // Set session data values |
81 | if (strcmp(session.parameters.sample_rate, "high") == 0) { | 69 | if (strcmp(session.parameters.sample_rate, "high") == 0) { |
82 | gSessionData->mSampleRate = 10000; | 70 | gSessionData->mSampleRate = 10000; |
@@ -84,8 +72,11 @@ void SessionData::parseSessionXML(char* xmlString) { | |||
84 | gSessionData->mSampleRate = 1000; | 72 | gSessionData->mSampleRate = 1000; |
85 | } else if (strcmp(session.parameters.sample_rate, "low") == 0) { | 73 | } else if (strcmp(session.parameters.sample_rate, "low") == 0) { |
86 | gSessionData->mSampleRate = 100; | 74 | gSessionData->mSampleRate = 100; |
87 | } else { | 75 | } else if (strcmp(session.parameters.sample_rate, "none") == 0) { |
88 | gSessionData->mSampleRate = 0; | 76 | gSessionData->mSampleRate = 0; |
77 | } else { | ||
78 | logg->logError(__FILE__, __LINE__, "Invalid sample rate (%s) in session xml.", session.parameters.sample_rate); | ||
79 | handleException(); | ||
89 | } | 80 | } |
90 | gSessionData->mBacktraceDepth = session.parameters.call_stack_unwinding == true ? 128 : 0; | 81 | gSessionData->mBacktraceDepth = session.parameters.call_stack_unwinding == true ? 128 : 0; |
91 | gSessionData->mDuration = session.parameters.duration; | 82 | gSessionData->mDuration = session.parameters.duration; |
@@ -107,6 +98,4 @@ void SessionData::parseSessionXML(char* xmlString) { | |||
107 | } | 98 | } |
108 | 99 | ||
109 | gSessionData->mImages = session.parameters.images; | 100 | gSessionData->mImages = session.parameters.images; |
110 | gSessionData->mTargetPath = session.parameters.target_path; | ||
111 | gSessionData->mTitle = session.parameters.title; | ||
112 | } | 101 | } |
diff --git a/daemon/SessionData.h b/daemon/SessionData.h index 6f42c07..00a71b1 100644 --- a/daemon/SessionData.h +++ b/daemon/SessionData.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #define MAX_STRING_LEN 80 | 13 | #define MAX_STRING_LEN 80 |
14 | #define MAX_DESCRIPTION_LEN 400 | 14 | #define MAX_DESCRIPTION_LEN 400 |
15 | 15 | ||
16 | #define PROTOCOL_VERSION 10 | 16 | #define PROTOCOL_VERSION 11 |
17 | #define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions | 17 | #define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions |
18 | 18 | ||
19 | struct ImageLinkList { | 19 | struct ImageLinkList { |
@@ -36,7 +36,6 @@ public: | |||
36 | char* mEventsXMLPath; | 36 | char* mEventsXMLPath; |
37 | char* mTargetPath; | 37 | char* mTargetPath; |
38 | char* mAPCDir; | 38 | char* mAPCDir; |
39 | char* mTitle; | ||
40 | 39 | ||
41 | bool mWaitingOnCommand; | 40 | bool mWaitingOnCommand; |
42 | bool mSessionIsActive; | 41 | bool mSessionIsActive; |
@@ -48,15 +47,13 @@ public: | |||
48 | int mSampleRate; | 47 | int mSampleRate; |
49 | int mDuration; | 48 | int mDuration; |
50 | int mCores; | 49 | int mCores; |
51 | int mBytes; | ||
52 | 50 | ||
53 | // PMU Counters | 51 | // PMU Counters |
52 | bool mCounterOverflow; | ||
54 | char mPerfCounterType[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; | 53 | char mPerfCounterType[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; |
55 | char mPerfCounterTitle[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; | 54 | char mPerfCounterTitle[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; |
56 | char mPerfCounterName[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; | 55 | char mPerfCounterName[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; |
57 | char mPerfCounterDescription[MAX_PERFORMANCE_COUNTERS][MAX_DESCRIPTION_LEN]; | 56 | char mPerfCounterDescription[MAX_PERFORMANCE_COUNTERS][MAX_DESCRIPTION_LEN]; |
58 | char mPerfCounterOperation[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; | ||
59 | char mPerfCounterAlias[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; | ||
60 | char mPerfCounterDisplay[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; | 57 | char mPerfCounterDisplay[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; |
61 | char mPerfCounterUnits[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; | 58 | char mPerfCounterUnits[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; |
62 | int mPerfCounterEnabled[MAX_PERFORMANCE_COUNTERS]; | 59 | int mPerfCounterEnabled[MAX_PERFORMANCE_COUNTERS]; |
@@ -66,7 +63,6 @@ public: | |||
66 | int mPerfCounterKey[MAX_PERFORMANCE_COUNTERS]; | 63 | int mPerfCounterKey[MAX_PERFORMANCE_COUNTERS]; |
67 | bool mPerfCounterPerCPU[MAX_PERFORMANCE_COUNTERS]; | 64 | bool mPerfCounterPerCPU[MAX_PERFORMANCE_COUNTERS]; |
68 | bool mPerfCounterEBSCapable[MAX_PERFORMANCE_COUNTERS]; | 65 | bool mPerfCounterEBSCapable[MAX_PERFORMANCE_COUNTERS]; |
69 | bool mPerfCounterLevel[MAX_PERFORMANCE_COUNTERS]; | ||
70 | bool mPerfCounterAverageSelection[MAX_PERFORMANCE_COUNTERS]; | 66 | bool mPerfCounterAverageSelection[MAX_PERFORMANCE_COUNTERS]; |
71 | }; | 67 | }; |
72 | 68 | ||
diff --git a/daemon/SessionXML.cpp b/daemon/SessionXML.cpp index f1a8258..4c373d8 100644 --- a/daemon/SessionXML.cpp +++ b/daemon/SessionXML.cpp | |||
@@ -19,21 +19,13 @@ static const char* TAG_SESSION = "session"; | |||
19 | static const char* TAG_IMAGE = "image"; | 19 | static const char* TAG_IMAGE = "image"; |
20 | 20 | ||
21 | static const char* ATTR_VERSION = "version"; | 21 | static const char* ATTR_VERSION = "version"; |
22 | static const char* ATTR_TITLE = "title"; | ||
23 | static const char* ATTR_UUID = "uuid"; | ||
24 | static const char* ATTR_CALL_STACK_UNWINDING = "call_stack_unwinding"; | 22 | static const char* ATTR_CALL_STACK_UNWINDING = "call_stack_unwinding"; |
25 | static const char* ATTR_BUFFER_MODE = "buffer_mode"; | 23 | static const char* ATTR_BUFFER_MODE = "buffer_mode"; |
26 | static const char* ATTR_SAMPLE_RATE = "sample_rate"; | 24 | static const char* ATTR_SAMPLE_RATE = "sample_rate"; |
27 | static const char* ATTR_TARGET_PATH = "target_path"; | ||
28 | static const char* ATTR_OUTPUT_PATH = "output_path"; | ||
29 | static const char* ATTR_DURATION = "duration"; | 25 | static const char* ATTR_DURATION = "duration"; |
30 | static const char* ATTR_PATH = "path"; | 26 | static const char* ATTR_PATH = "path"; |
31 | 27 | ||
32 | SessionXML::SessionXML(const char* str) { | 28 | SessionXML::SessionXML(const char* str) { |
33 | parameters.title = 0; | ||
34 | parameters.uuid[0] = 0; | ||
35 | parameters.target_path = 0; | ||
36 | parameters.output_path = 0; | ||
37 | parameters.buffer_mode[0] = 0; | 29 | parameters.buffer_mode[0] = 0; |
38 | parameters.sample_rate[0] = 0; | 30 | parameters.sample_rate[0] = 0; |
39 | parameters.duration = 0; | 31 | parameters.duration = 0; |
@@ -75,34 +67,7 @@ void SessionXML::sessionTag(mxml_node_t *tree, mxml_node_t *node) { | |||
75 | handleException(); | 67 | handleException(); |
76 | } | 68 | } |
77 | 69 | ||
78 | // allocate strings | ||
79 | if (mxmlElementGetAttr(node, ATTR_TITLE)) { | ||
80 | parameters.title = strdup(mxmlElementGetAttr(node, ATTR_TITLE)); // freed when the child process exits | ||
81 | if (parameters.title == NULL) { | ||
82 | logg->logError(__FILE__, __LINE__, "failed to allocate parameters.title"); | ||
83 | handleException(); | ||
84 | } | ||
85 | } | ||
86 | if (mxmlElementGetAttr(node, ATTR_TARGET_PATH)) { | ||
87 | parameters.target_path = strdup(mxmlElementGetAttr(node, ATTR_TARGET_PATH)); // freed when the child process exits | ||
88 | if (parameters.target_path == NULL) { | ||
89 | logg->logError(__FILE__, __LINE__, "failed to allocate parameters.target_path"); | ||
90 | handleException(); | ||
91 | } | ||
92 | } | ||
93 | if (mxmlElementGetAttr(node, ATTR_OUTPUT_PATH)) { | ||
94 | parameters.output_path = strdup(mxmlElementGetAttr(node, ATTR_OUTPUT_PATH)); // freed when the child process exits | ||
95 | if (parameters.output_path == NULL) { | ||
96 | logg->logError(__FILE__, __LINE__, "failed to allocate parameters.output_path"); | ||
97 | handleException(); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | // copy to pre-allocated strings | 70 | // copy to pre-allocated strings |
102 | if (mxmlElementGetAttr(node, ATTR_UUID)) { | ||
103 | strncpy(parameters.uuid, mxmlElementGetAttr(node, ATTR_UUID), sizeof(parameters.uuid)); | ||
104 | parameters.uuid[sizeof(parameters.uuid) - 1] = 0; // strncpy does not guarantee a null-terminated string | ||
105 | } | ||
106 | if (mxmlElementGetAttr(node, ATTR_BUFFER_MODE)) { | 71 | if (mxmlElementGetAttr(node, ATTR_BUFFER_MODE)) { |
107 | strncpy(parameters.buffer_mode, mxmlElementGetAttr(node, ATTR_BUFFER_MODE), sizeof(parameters.buffer_mode)); | 72 | strncpy(parameters.buffer_mode, mxmlElementGetAttr(node, ATTR_BUFFER_MODE), sizeof(parameters.buffer_mode)); |
108 | parameters.buffer_mode[sizeof(parameters.buffer_mode) - 1] = 0; // strncpy does not guarantee a null-terminated string | 73 | parameters.buffer_mode[sizeof(parameters.buffer_mode) - 1] = 0; // strncpy does not guarantee a null-terminated string |
diff --git a/daemon/SessionXML.h b/daemon/SessionXML.h index c2b5489..f7a5641 100644 --- a/daemon/SessionXML.h +++ b/daemon/SessionXML.h | |||
@@ -13,10 +13,6 @@ | |||
13 | #include "SessionData.h" | 13 | #include "SessionData.h" |
14 | 14 | ||
15 | struct ConfigParameters { | 15 | struct ConfigParameters { |
16 | char* title; // status title | ||
17 | char uuid[64]; // universal unique identifier | ||
18 | char* target_path; // target path of where to write to disk | ||
19 | char* output_path; // host path of where to write to disk | ||
20 | char buffer_mode[64]; // buffer mode, "streaming", "low", "normal", "high" defines oneshot and buffer size | 16 | char buffer_mode[64]; // buffer mode, "streaming", "low", "normal", "high" defines oneshot and buffer size |
21 | char sample_rate[64]; // capture mode, "high", "normal", or "low" | 17 | char sample_rate[64]; // capture mode, "high", "normal", or "low" |
22 | int duration; // length of profile in seconds | 18 | int duration; // length of profile in seconds |
diff --git a/daemon/StreamlineSetup.cpp b/daemon/StreamlineSetup.cpp index 53729ab..3f59eab 100644 --- a/daemon/StreamlineSetup.cpp +++ b/daemon/StreamlineSetup.cpp | |||
@@ -28,13 +28,13 @@ static const char* TAG_SESSION = "session"; | |||
28 | static const char* TAG_REQUEST = "request"; | 28 | static const char* TAG_REQUEST = "request"; |
29 | static const char* TAG_CONFIGURATIONS = "configurations"; | 29 | static const char* TAG_CONFIGURATIONS = "configurations"; |
30 | 30 | ||
31 | static const char* ATTR_PROTOCOL = "protocol"; | 31 | static const char* ATTR_TYPE = "type"; |
32 | static const char* ATTR_EVENTS = "events"; | 32 | static const char* VALUE_EVENTS = "events"; |
33 | static const char* ATTR_CONFIGURATION = "configuration"; | 33 | static const char* VALUE_CONFIGURATION = "configuration"; |
34 | static const char* ATTR_COUNTERS = "counters"; | 34 | static const char* VALUE_COUNTERS = "counters"; |
35 | static const char* ATTR_SESSION = "session"; | 35 | static const char* VALUE_SESSION = "session"; |
36 | static const char* ATTR_CAPTURED = "captured"; | 36 | static const char* VALUE_CAPTURED = "captured"; |
37 | static const char* ATTR_DEFAULTS = "defaults"; | 37 | static const char* VALUE_DEFAULTS = "defaults"; |
38 | 38 | ||
39 | StreamlineSetup::StreamlineSetup(OlySocket* s) { | 39 | StreamlineSetup::StreamlineSetup(OlySocket* s) { |
40 | bool ready = false; | 40 | bool ready = false; |
@@ -81,6 +81,11 @@ StreamlineSetup::StreamlineSetup(OlySocket* s) { | |||
81 | 81 | ||
82 | free(data); | 82 | free(data); |
83 | } | 83 | } |
84 | |||
85 | if (gSessionData->mCounterOverflow) { | ||
86 | logg->logError(__FILE__, __LINE__, "Exceeded maximum number of %d performance counters", MAX_PERFORMANCE_COUNTERS); | ||
87 | handleException(); | ||
88 | } | ||
84 | } | 89 | } |
85 | 90 | ||
86 | StreamlineSetup::~StreamlineSetup() { | 91 | StreamlineSetup::~StreamlineSetup() { |
@@ -143,30 +148,32 @@ char* StreamlineSetup::readCommand(int* command) { | |||
143 | 148 | ||
144 | void StreamlineSetup::handleRequest(char* xml) { | 149 | void StreamlineSetup::handleRequest(char* xml) { |
145 | mxml_node_t *tree, *node; | 150 | mxml_node_t *tree, *node; |
151 | const char * attr = NULL; | ||
146 | 152 | ||
147 | tree = mxmlLoadString(NULL, xml, MXML_NO_CALLBACK); | 153 | tree = mxmlLoadString(NULL, xml, MXML_NO_CALLBACK); |
148 | if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_PROTOCOL, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_PROTOCOL), false)) { | 154 | node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_TYPE, NULL, MXML_DESCEND_FIRST); |
149 | sendProtocol(); | 155 | if (node) { |
150 | logg->logMessage("Sent protocol xml response"); | 156 | attr = mxmlElementGetAttr(node, ATTR_TYPE); |
151 | } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_EVENTS, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_EVENTS), false)) { | 157 | } |
158 | if (attr && strcmp(attr, VALUE_EVENTS) == 0) { | ||
152 | sendEvents(); | 159 | sendEvents(); |
153 | logg->logMessage("Sent events xml response"); | 160 | logg->logMessage("Sent events xml response"); |
154 | } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_CONFIGURATION, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_CONFIGURATION), false)) { | 161 | } else if (attr && strcmp(attr, VALUE_CONFIGURATION) == 0) { |
155 | sendConfiguration(); | 162 | sendConfiguration(); |
156 | logg->logMessage("Sent configuration xml response"); | 163 | logg->logMessage("Sent configuration xml response"); |
157 | } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_COUNTERS, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_COUNTERS), false)) { | 164 | } else if (attr && strcmp(attr, VALUE_COUNTERS) == 0) { |
158 | sendCounters(); | 165 | sendCounters(); |
159 | logg->logMessage("Sent counters xml response"); | 166 | logg->logMessage("Sent counters xml response"); |
160 | } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_SESSION, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_SESSION), false)) { | 167 | } else if (attr && strcmp(attr, VALUE_SESSION) == 0) { |
161 | sendData(mSessionXML, strlen(mSessionXML), RESPONSE_XML); | 168 | sendData(mSessionXML, strlen(mSessionXML), RESPONSE_XML); |
162 | logg->logMessage("Sent session xml response"); | 169 | logg->logMessage("Sent session xml response"); |
163 | } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_CAPTURED, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_CAPTURED), false)) { | 170 | } else if (attr && strcmp(attr, VALUE_CAPTURED) == 0) { |
164 | CapturedXML capturedXML; | 171 | CapturedXML capturedXML; |
165 | char* capturedText = capturedXML.getXML(); | 172 | char* capturedText = capturedXML.getXML(false); |
166 | sendData(capturedText, strlen(capturedText), RESPONSE_XML); | 173 | sendData(capturedText, strlen(capturedText), RESPONSE_XML); |
167 | free(capturedText); | 174 | free(capturedText); |
168 | logg->logMessage("Sent captured xml response"); | 175 | logg->logMessage("Sent captured xml response"); |
169 | } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_DEFAULTS, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_DEFAULTS), false)) { | 176 | } else if (attr && strcmp(attr, VALUE_DEFAULTS) == 0) { |
170 | sendDefaults(); | 177 | sendDefaults(); |
171 | logg->logMessage("Sent default configuration xml response"); | 178 | logg->logMessage("Sent default configuration xml response"); |
172 | } else { | 179 | } else { |
@@ -215,21 +222,6 @@ void StreamlineSetup::sendData(const char* data, int length, int type) { | |||
215 | mSocket->send((char*)data, length); | 222 | mSocket->send((char*)data, length); |
216 | } | 223 | } |
217 | 224 | ||
218 | void StreamlineSetup::sendProtocol() { | ||
219 | mxml_node_t *xml; | ||
220 | mxml_node_t *protocol; | ||
221 | |||
222 | xml = mxmlNewXML("1.0"); | ||
223 | protocol = mxmlNewElement(xml, "protocol"); | ||
224 | mxmlElementSetAttrf(protocol, "version", "%d", PROTOCOL_VERSION); | ||
225 | |||
226 | char* string = mxmlSaveAllocString(xml, mxmlWhitespaceCB); | ||
227 | sendString(string, RESPONSE_XML); | ||
228 | |||
229 | free(string); | ||
230 | mxmlDelete(xml); | ||
231 | } | ||
232 | |||
233 | void StreamlineSetup::sendEvents() { | 225 | void StreamlineSetup::sendEvents() { |
234 | #include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len | 226 | #include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len |
235 | char* path = (char*)malloc(PATH_MAX);; | 227 | char* path = (char*)malloc(PATH_MAX);; |
@@ -264,10 +256,10 @@ void StreamlineSetup::sendConfiguration() { | |||
264 | } | 256 | } |
265 | 257 | ||
266 | void StreamlineSetup::sendDefaults() { | 258 | void StreamlineSetup::sendDefaults() { |
267 | #include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len | ||
268 | // Send the config built into the binary | 259 | // Send the config built into the binary |
269 | char* xml = (char*)configuration_xml; | 260 | const char* xml; |
270 | unsigned int size = configuration_xml_len; | 261 | unsigned int size; |
262 | ConfigurationXML::getDefaultConfigurationXml(xml, size); | ||
271 | 263 | ||
272 | // Artificial size restriction | 264 | // Artificial size restriction |
273 | if (size > 1024*1024) { | 265 | if (size > 1024*1024) { |
@@ -282,7 +274,7 @@ void StreamlineSetup::sendDefaults() { | |||
282 | void StreamlineSetup::sendCounters() { | 274 | void StreamlineSetup::sendCounters() { |
283 | struct dirent *ent; | 275 | struct dirent *ent; |
284 | mxml_node_t *xml; | 276 | mxml_node_t *xml; |
285 | mxml_node_t *counters; | 277 | mxml_node_t *counters; |
286 | mxml_node_t *counter; | 278 | mxml_node_t *counter; |
287 | 279 | ||
288 | // counters.xml is simply a file listing of /dev/gator/events | 280 | // counters.xml is simply a file listing of /dev/gator/events |
@@ -328,4 +320,9 @@ void StreamlineSetup::writeConfiguration(char* xml) { | |||
328 | // Re-populate gSessionData with the configuration, as it has now changed | 320 | // Re-populate gSessionData with the configuration, as it has now changed |
329 | new ConfigurationXML(); | 321 | new ConfigurationXML(); |
330 | free(path); | 322 | free(path); |
323 | |||
324 | if (gSessionData->mCounterOverflow) { | ||
325 | logg->logError(__FILE__, __LINE__, "Exceeded maximum number of %d performance counters", MAX_PERFORMANCE_COUNTERS); | ||
326 | handleException(); | ||
327 | } | ||
331 | } | 328 | } |
diff --git a/daemon/StreamlineSetup.h b/daemon/StreamlineSetup.h index c46ae08..8086fe2 100644 --- a/daemon/StreamlineSetup.h +++ b/daemon/StreamlineSetup.h | |||
@@ -35,7 +35,6 @@ private: | |||
35 | void handleDeliver(char* xml); | 35 | void handleDeliver(char* xml); |
36 | void sendData(const char* data, int length, int type); | 36 | void sendData(const char* data, int length, int type); |
37 | void sendString(const char* string, int type) {sendData(string, strlen(string), type);} | 37 | void sendString(const char* string, int type) {sendData(string, strlen(string), type);} |
38 | void sendProtocol(); | ||
39 | void sendEvents(); | 38 | void sendEvents(); |
40 | void sendConfiguration(); | 39 | void sendConfiguration(); |
41 | void sendDefaults(); | 40 | void sendDefaults(); |
diff --git a/daemon/configuration.xml b/daemon/configuration.xml index 4875f1f..fbdef31 100644 --- a/daemon/configuration.xml +++ b/daemon/configuration.xml | |||
@@ -1,49 +1,45 @@ | |||
1 | <?xml version="1.0" encoding='UTF-8'?> | 1 | <?xml version="1.0" encoding='UTF-8'?> |
2 | <configurations version="1" revision="1"> | 2 | <configurations revision="1"> |
3 | <configuration counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <configuration counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
4 | <configuration counter="ARM_ARM11_cnt0" event="0x7" title="Instruction" name="Executed" per_cpu="yes" description="Instructions executed"/> | 4 | <configuration counter="ARM_ARM11_cnt0" event="0x7" title="Instruction" name="Executed" per_cpu="yes" description="Instructions executed"/> |
5 | <configuration counter="ARM_ARM11_cnt1" event="0xb" title="Cache" name="Data miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/> | 5 | <configuration counter="ARM_ARM11_cnt1" event="0xb" title="Cache" name="Data miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/> |
6 | <configuration counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 6 | <configuration counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
7 | <configuration counter="ARM_ARM11MPCore_cnt0" event="0x08" title="Core" name="Instructions" per_cpu="yes" description="Instructions executed"/> | 7 | <configuration counter="ARM_ARM11MPCore_cnt0" event="0x08" title="Core" name="Instructions" per_cpu="yes" description="Instructions executed"/> |
8 | <configuration counter="ARM_ARM11MPCore_cnt1" event="0x0b" title="Cache" name="Data read miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/> | 8 | <configuration counter="ARM_ARM11MPCore_cnt1" event="0x0b" title="Cache" name="Data read miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/> |
9 | <configuration counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 9 | <configuration counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
10 | <configuration counter="ARM_Cortex-A5_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> | 10 | <configuration counter="ARM_Cortex-A5_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/> |
11 | <configuration counter="ARM_Cortex-A5_cnt1" event="0x1" title="Cache" name="Instruction refill" per_cpu="yes" event_based_sampling="yes" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> | 11 | <configuration counter="ARM_Cortex-A5_cnt1" event="0x1" title="Cache" name="Instruction refill" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> |
12 | <configuration counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 12 | <configuration counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
13 | <configuration counter="ARM_Cortex-A7_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> | 13 | <configuration counter="ARM_Cortex-A7_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/> |
14 | <configuration counter="ARM_Cortex-A7_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> | 14 | <configuration counter="ARM_Cortex-A7_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/> |
15 | <configuration counter="ARM_Cortex-A7_cnt2" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" event_based_sampling="yes" description="Level 2 data cache access"/> | 15 | <configuration counter="ARM_Cortex-A7_cnt2" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" supports_event_based_sampling="yes" description="Level 2 data cache access"/> |
16 | <configuration counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 16 | <configuration counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
17 | <configuration counter="ARM_Cortex-A8_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> | 17 | <configuration counter="ARM_Cortex-A8_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/> |
18 | <configuration counter="ARM_Cortex-A8_cnt1" event="0x44" title="Cache" name="L2 miss" per_cpu="yes" event_based_sampling="yes" description="Any cacheable miss in the L2 cache"/> | 18 | <configuration counter="ARM_Cortex-A8_cnt1" event="0x44" title="Cache" name="L2 miss" per_cpu="yes" supports_event_based_sampling="yes" description="Any cacheable miss in the L2 cache"/> |
19 | <configuration counter="ARM_Cortex-A8_cnt2" event="0x43" title="Cache" name="L1 miss" per_cpu="yes" event_based_sampling="yes" description="Any accesses to the L2 cache"/> | 19 | <configuration counter="ARM_Cortex-A8_cnt2" event="0x43" title="Cache" name="L1 miss" per_cpu="yes" supports_event_based_sampling="yes" description="Any accesses to the L2 cache"/> |
20 | <configuration counter="ARM_Cortex-A8_cnt3" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> | 20 | <configuration counter="ARM_Cortex-A8_cnt3" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/> |
21 | <configuration counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 21 | <configuration counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
22 | <configuration counter="ARM_Cortex-A9_cnt0" event="0x68" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" 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"/> | 22 | <configuration counter="ARM_Cortex-A9_cnt0" event="0x68" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" 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"/> |
23 | <configuration counter="ARM_Cortex-A9_cnt1" event="0x06" title="Instruction" name="Memory read" per_cpu="yes" event_based_sampling="yes" description="Memory-reading instruction architecturally executed"/> | 23 | <configuration counter="ARM_Cortex-A9_cnt1" event="0x06" title="Instruction" name="Memory read" per_cpu="yes" supports_event_based_sampling="yes" description="Memory-reading instruction architecturally executed"/> |
24 | <configuration counter="ARM_Cortex-A9_cnt2" event="0x07" title="Instruction" name="Memory write" per_cpu="yes" event_based_sampling="yes" description="Memory-writing instruction architecturally executed"/> | 24 | <configuration counter="ARM_Cortex-A9_cnt2" event="0x07" title="Instruction" name="Memory write" per_cpu="yes" supports_event_based_sampling="yes" description="Memory-writing instruction architecturally executed"/> |
25 | <configuration counter="ARM_Cortex-A9_cnt3" event="0x03" title="Cache" name="Data refill" per_cpu="yes" event_based_sampling="yes" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/> | 25 | <configuration counter="ARM_Cortex-A9_cnt3" event="0x03" title="Cache" name="Data refill" per_cpu="yes" supports_event_based_sampling="yes" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/> |
26 | <configuration counter="ARM_Cortex-A9_cnt4" event="0x04" title="Cache" name="Data access" per_cpu="yes" event_based_sampling="yes" 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"/> | 26 | <configuration counter="ARM_Cortex-A9_cnt4" event="0x04" title="Cache" name="Data access" per_cpu="yes" supports_event_based_sampling="yes" 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"/> |
27 | <configuration counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 27 | <configuration counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
28 | <configuration counter="ARM_Cortex-A15_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> | 28 | <configuration counter="ARM_Cortex-A15_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/> |
29 | <configuration counter="ARM_Cortex-A15_cnt1" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" event_based_sampling="yes" description="Level 2 data cache access"/> | 29 | <configuration counter="ARM_Cortex-A15_cnt1" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" supports_event_based_sampling="yes" description="Level 2 data cache access"/> |
30 | <configuration counter="ARM_Cortex-A15_cnt2" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> | 30 | <configuration counter="ARM_Cortex-A15_cnt2" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/> |
31 | <configuration counter="ARM_Cortex-A15_cnt3" event="0x19" title="Bus" name="Access" per_cpu="yes" event_based_sampling="yes" description=""/> | 31 | <configuration counter="ARM_Cortex-A15_cnt3" event="0x19" title="Bus" name="Access" per_cpu="yes" supports_event_based_sampling="yes" description=""/> |
32 | <configuration counter="Scorpion_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 32 | <configuration counter="Scorpion_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
33 | <configuration counter="Scorpion_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> | 33 | <configuration counter="Scorpion_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/> |
34 | <configuration counter="Scorpion_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> | 34 | <configuration counter="Scorpion_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/> |
35 | <configuration counter="ScorpionMP_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 35 | <configuration counter="ScorpionMP_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
36 | <configuration counter="ScorpionMP_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> | 36 | <configuration counter="ScorpionMP_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/> |
37 | <configuration counter="ScorpionMP_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> | 37 | <configuration counter="ScorpionMP_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/> |
38 | <configuration counter="Krait_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 38 | <configuration counter="Krait_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
39 | <configuration counter="Krait_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> | 39 | <configuration counter="Krait_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/> |
40 | <configuration counter="Krait_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> | 40 | <configuration counter="Krait_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/> |
41 | <configuration counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/> | 41 | <configuration counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/> |
42 | <configuration counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/> | 42 | <configuration counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/> |
43 | <configuration counter="Linux_net_rx" title="Network" name="Receive" units="B" description="Receive network traffic, including effect from Streamline"/> | ||
44 | <configuration counter="Linux_net_tx" title="Network" name="Transmit" units="B" description="Transmit network traffic, including effect from Streamline"/> | ||
45 | <configuration counter="Linux_cpuload_system" title="CPU Load" name="System" description="Scheduler CPU Load of System Behavior"/> | ||
46 | <configuration counter="Linux_cpuload_user" title="CPU Load" name="User" description="Scheduler CPU Load of User Application"/> | ||
47 | <configuration counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/> | 43 | <configuration counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/> |
48 | <configuration counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/> | 44 | <configuration counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/> |
49 | <configuration counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" display="maximum" units="Hz" average_selection="yes" description="Frequency setting of the CPU"/> | 45 | <configuration counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" display="maximum" units="Hz" average_selection="yes" description="Frequency setting of the CPU"/> |
diff --git a/daemon/events-ARM11.xml b/daemon/events-ARM11.xml index d4a2914..0a5ee66 100644 --- a/daemon/events-ARM11.xml +++ b/daemon/events-ARM11.xml | |||
@@ -1,9 +1,5 @@ | |||
1 | <counter_set name="ARM_ARM11_cntX"> | 1 | <counter_set name="ARM_ARM11_cnt" count="3"/> |
2 | <counter name="ARM_ARM11_cnt0"/> | 2 | <category name="ARM11" counter_set="ARM_ARM11_cnt" per_cpu="yes"> |
3 | <counter name="ARM_ARM11_cnt1"/> | ||
4 | <counter name="ARM_ARM11_cnt2"/> | ||
5 | </counter_set> | ||
6 | <category name="ARM11" counter_set="ARM_ARM11_cntX" per_cpu="yes"> | ||
7 | <event counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
8 | <event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/> | 4 | <event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/> |
9 | <event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/> | 5 | <event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/> |
diff --git a/daemon/events-ARM11MPCore.xml b/daemon/events-ARM11MPCore.xml index 7de51b0..1a9ca3f 100644 --- a/daemon/events-ARM11MPCore.xml +++ b/daemon/events-ARM11MPCore.xml | |||
@@ -1,9 +1,5 @@ | |||
1 | <counter_set name="ARM_ARM11MPCore_cntX"> | 1 | <counter_set name="ARM_ARM11MPCore_cnt" count="3"/> |
2 | <counter name="ARM_ARM11MPCore_cnt0"/> | 2 | <category name="ARM11MPCore" counter_set="ARM_ARM11MPCore_cnt" per_cpu="yes"> |
3 | <counter name="ARM_ARM11MPCore_cnt1"/> | ||
4 | <counter name="ARM_ARM11MPCore_cnt2"/> | ||
5 | </counter_set> | ||
6 | <category name="ARM11MPCore" counter_set="ARM_ARM11MPCore_cntX" per_cpu="yes"> | ||
7 | <event counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
8 | <event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/> | 4 | <event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/> |
9 | <event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/> | 5 | <event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/> |
diff --git a/daemon/events-Cortex-A15.xml b/daemon/events-Cortex-A15.xml index d6222eb..0ec196f 100644 --- a/daemon/events-Cortex-A15.xml +++ b/daemon/events-Cortex-A15.xml | |||
@@ -1,12 +1,5 @@ | |||
1 | <counter_set name="ARM_Cortex-A15_cntX"> | 1 | <counter_set name="ARM_Cortex-A15_cnt" count="6"/> |
2 | <counter name="ARM_Cortex-A15_cnt0"/> | 2 | <category name="Cortex-A15" counter_set="ARM_Cortex-A15_cnt" per_cpu="yes" supports_event_based_sampling="yes"> |
3 | <counter name="ARM_Cortex-A15_cnt1"/> | ||
4 | <counter name="ARM_Cortex-A15_cnt2"/> | ||
5 | <counter name="ARM_Cortex-A15_cnt3"/> | ||
6 | <counter name="ARM_Cortex-A15_cnt4"/> | ||
7 | <counter name="ARM_Cortex-A15_cnt5"/> | ||
8 | </counter_set> | ||
9 | <category name="Cortex-A15" counter_set="ARM_Cortex-A15_cntX" per_cpu="yes" event_based_sampling="yes"> | ||
10 | <event counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
11 | <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/> | 4 | <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/> |
12 | <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"/> | 5 | <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"/> |
@@ -19,7 +12,6 @@ | |||
19 | <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/> | 12 | <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/> |
20 | <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/> | 13 | <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/> |
21 | <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/> | 14 | <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/> |
22 | <event event="0x11" title="Cycle" name="Cycle" description=""/> | ||
23 | <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"/> | 15 | <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"/> |
24 | <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/> | 16 | <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/> |
25 | <event event="0x14" title="Cache" name="L1 inst access" description="Instruction cache access"/> | 17 | <event event="0x14" title="Cache" name="L1 inst access" description="Instruction cache access"/> |
diff --git a/daemon/events-Cortex-A5.xml b/daemon/events-Cortex-A5.xml index e01492b..4a894d3 100644 --- a/daemon/events-Cortex-A5.xml +++ b/daemon/events-Cortex-A5.xml | |||
@@ -1,8 +1,5 @@ | |||
1 | <counter_set name="ARM_Cortex-A5_cntX"> | 1 | <counter_set name="ARM_Cortex-A5_cnt" count="2"/> |
2 | <counter name="ARM_Cortex-A5_cnt0"/> | 2 | <category name="Cortex-A5" counter_set="ARM_Cortex-A5_cnt" per_cpu="yes" supports_event_based_sampling="yes"> |
3 | <counter name="ARM_Cortex-A5_cnt1"/> | ||
4 | </counter_set> | ||
5 | <category name="Cortex-A5" counter_set="ARM_Cortex-A5_cntX" per_cpu="yes" event_based_sampling="yes"> | ||
6 | <event counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
7 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> | 4 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> |
8 | <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"/> | 5 | <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"/> |
diff --git a/daemon/events-Cortex-A7.xml b/daemon/events-Cortex-A7.xml index 9ee4580..2bd4797 100644 --- a/daemon/events-Cortex-A7.xml +++ b/daemon/events-Cortex-A7.xml | |||
@@ -1,10 +1,5 @@ | |||
1 | <counter_set name="ARM_Cortex-A7_cntX"> | 1 | <counter_set name="ARM_Cortex-A7_cnt" count="4"/> |
2 | <counter name="ARM_Cortex-A7_cnt0"/> | 2 | <category name="Cortex-A7" counter_set="ARM_Cortex-A7_cnt" per_cpu="yes" supports_event_based_sampling="yes"> |
3 | <counter name="ARM_Cortex-A7_cnt1"/> | ||
4 | <counter name="ARM_Cortex-A7_cnt2"/> | ||
5 | <counter name="ARM_Cortex-A7_cnt3"/> | ||
6 | </counter_set> | ||
7 | <category name="Cortex-A7" counter_set="ARM_Cortex-A7_cntX" per_cpu="yes" event_based_sampling="yes"> | ||
8 | <event counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
9 | <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/> | 4 | <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/> |
10 | <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"/> | 5 | <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"/> |
diff --git a/daemon/events-Cortex-A8.xml b/daemon/events-Cortex-A8.xml index 1981c36..fe4c69d 100644 --- a/daemon/events-Cortex-A8.xml +++ b/daemon/events-Cortex-A8.xml | |||
@@ -1,10 +1,5 @@ | |||
1 | <counter_set name="ARM_Cortex-A8_cntX"> | 1 | <counter_set name="ARM_Cortex-A8_cnt" count="4"/> |
2 | <counter name="ARM_Cortex-A8_cnt0"/> | 2 | <category name="Cortex-A8" counter_set="ARM_Cortex-A8_cnt" per_cpu="yes" supports_event_based_sampling="yes"> |
3 | <counter name="ARM_Cortex-A8_cnt1"/> | ||
4 | <counter name="ARM_Cortex-A8_cnt2"/> | ||
5 | <counter name="ARM_Cortex-A8_cnt3"/> | ||
6 | </counter_set> | ||
7 | <category name="Cortex-A8" counter_set="ARM_Cortex-A8_cntX" per_cpu="yes" event_based_sampling="yes"> | ||
8 | <event counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
9 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> | 4 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> |
10 | <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"/> | 5 | <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"/> |
diff --git a/daemon/events-Cortex-A9.xml b/daemon/events-Cortex-A9.xml index faccb2f..7597f78 100644 --- a/daemon/events-Cortex-A9.xml +++ b/daemon/events-Cortex-A9.xml | |||
@@ -1,12 +1,5 @@ | |||
1 | <counter_set name="ARM_Cortex-A9_cntX"> | 1 | <counter_set name="ARM_Cortex-A9_cnt" count="6"/> |
2 | <counter name="ARM_Cortex-A9_cnt0"/> | 2 | <category name="Cortex-A9" counter_set="ARM_Cortex-A9_cnt" per_cpu="yes" supports_event_based_sampling="yes"> |
3 | <counter name="ARM_Cortex-A9_cnt1"/> | ||
4 | <counter name="ARM_Cortex-A9_cnt2"/> | ||
5 | <counter name="ARM_Cortex-A9_cnt3"/> | ||
6 | <counter name="ARM_Cortex-A9_cnt4"/> | ||
7 | <counter name="ARM_Cortex-A9_cnt5"/> | ||
8 | </counter_set> | ||
9 | <category name="Cortex-A9" counter_set="ARM_Cortex-A9_cntX" per_cpu="yes" event_based_sampling="yes"> | ||
10 | <event counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
11 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> | 4 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> |
12 | <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"/> | 5 | <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"/> |
diff --git a/daemon/events-Krait-architected.xml b/daemon/events-Krait-architected.xml index 6f2982e..06c1901 100644 --- a/daemon/events-Krait-architected.xml +++ b/daemon/events-Krait-architected.xml | |||
@@ -1,10 +1,5 @@ | |||
1 | <counter_set name="Krait_cntX"> | 1 | <counter_set name="Krait_cnt" count="4"/> |
2 | <counter name="Krait_cnt0"/> | 2 | <category name="Krait" counter_set="Krait_cnt" per_cpu="yes" supports_event_based_sampling="yes"> |
3 | <counter name="Krait_cnt1"/> | ||
4 | <counter name="Krait_cnt2"/> | ||
5 | <counter name="Krait_cnt3"/> | ||
6 | </counter_set> | ||
7 | <category name="Krait" counter_set="Krait_cntX" per_cpu="yes"> | ||
8 | <event counter="Krait_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="Krait_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
9 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> | 4 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> |
10 | <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"/> | 5 | <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"/> |
diff --git a/daemon/events-L2C-310.xml b/daemon/events-L2C-310.xml index 695b6b8..4da4d1d 100644 --- a/daemon/events-L2C-310.xml +++ b/daemon/events-L2C-310.xml | |||
@@ -1,8 +1,5 @@ | |||
1 | <counter_set name="L2C-310_cntX"> | 1 | <counter_set name="L2C-310_cnt" count="2"/> |
2 | <counter name="L2C-310_cnt0"/> | 2 | <category name="L2C-310" counter_set="L2C-310_cnt" per_cpu="no"> |
3 | <counter name="L2C-310_cnt1"/> | ||
4 | </counter_set> | ||
5 | <category name="L2C-310" counter_set="L2C-310_cntX" per_cpu="no"> | ||
6 | <event event="0x1" title="L2 Cache" name="CO" description="Eviction, CastOUT, of a line from the L2 cache"/> | 3 | <event event="0x1" title="L2 Cache" name="CO" description="Eviction, CastOUT, of a line from the L2 cache"/> |
7 | <event event="0x2" title="L2 Cache" name="DRH" description="Data read hit"/> | 4 | <event event="0x2" title="L2 Cache" name="DRH" description="Data read hit"/> |
8 | <event event="0x3" title="L2 Cache" name="DRREQ" description="Data read request"/> | 5 | <event event="0x3" title="L2 Cache" name="DRREQ" description="Data read request"/> |
diff --git a/daemon/events-Linux.xml b/daemon/events-Linux.xml index 3f626b3..b45a122 100644 --- a/daemon/events-Linux.xml +++ b/daemon/events-Linux.xml | |||
@@ -1,17 +1,15 @@ | |||
1 | <category name="Linux"> | 1 | <category name="Linux"> |
2 | <event counter="Linux_cpuload_user" title="CPU Load" name="User" per_cpu="yes" description="Scheduler CPU Load of User Application"/> | ||
3 | <event counter="Linux_cpuload_system" title="CPU Load" name="System" per_cpu="yes" description="Scheduler CPU Load of System Behavior"/> | ||
4 | <event counter="Linux_irq_softirq" title="Interrupts" name="SoftIRQ" per_cpu="yes" description="Linux SoftIRQ taken"/> | 2 | <event counter="Linux_irq_softirq" title="Interrupts" name="SoftIRQ" per_cpu="yes" description="Linux SoftIRQ taken"/> |
5 | <event counter="Linux_irq_irq" title="Interrupts" name="IRQ" per_cpu="yes" description="Linux IRQ taken"/> | 3 | <event counter="Linux_irq_irq" title="Interrupts" name="IRQ" per_cpu="yes" description="Linux IRQ taken"/> |
6 | <event counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/> | 4 | <event counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/> |
7 | <event counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/> | 5 | <event counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/> |
8 | <event counter="Linux_net_rx" title="Network" name="Receive" units="B" description="Receive network traffic, including effect from Streamline"/> | 6 | <event counter="Linux_net_rx" title="Network" name="Receive" units="B" description="Receive network traffic, including effect from Streamline"/> |
9 | <event counter="Linux_net_tx" title="Network" name="Transmit" units="B" description="Transmit network traffic, including effect from Streamline"/> | 7 | <event counter="Linux_net_tx" title="Network" name="Transmit" units="B" description="Transmit network traffic, including effect from Streamline"/> |
10 | <event counter="Linux_sched_switch" title="Scheduler" name="Switch" description="Context switch events"/> | 8 | <event counter="Linux_sched_switch" title="Scheduler" name="Switch" per_cpu="yes" description="Context switch events"/> |
11 | <event counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/> | 9 | <event counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/> |
12 | <event counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/> | 10 | <event counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/> |
13 | <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" display="maximum" units="B" average_selection="yes" description="Memory used by buffers"/> | 11 | <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" display="maximum" units="B" average_selection="yes" description="Memory used by buffers"/> |
14 | <event counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" display="maximum" units="Hz" average_selection="yes" description="Frequency setting of the CPU"/> | 12 | <event counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" display="maximum" units="Hz" average_selection="yes" description="Frequency setting of the CPU"/> |
15 | <event counter="Linux_power_cpu_idle" title="Power" name="Idle" per_cpu="yes" display="maximum" average_selection="yes" description="CPU Idle State, set the Sample Rate to None to prevent the hrtimer from interrupting the system"/> | 13 | <event counter="Linux_power_cpu_idle" title="Power" name="Idle" per_cpu="yes" display="maximum" average_selection="yes" description="CPU Idle State + 1, set the Sample Rate to None to prevent the hrtimer from interrupting the system"/> |
16 | </category> | 14 | </category> |
17 | 15 | ||
diff --git a/daemon/events-Mali-400.xml b/daemon/events-Mali-400.xml index cb1c6b4..6830d46 100644 --- a/daemon/events-Mali-400.xml +++ b/daemon/events-Mali-400.xml | |||
@@ -1,33 +1,12 @@ | |||
1 | <counter_set name="ARM_Mali-400_VP_cntX"> | 1 | <counter_set name="ARM_Mali-400_VP_cnt" count="2"/> |
2 | <counter name="ARM_Mali-400_VP_cnt0"/> | 2 | <counter_set name="ARM_Mali-400_FP0_cnt" count="2"/> |
3 | <counter name="ARM_Mali-400_VP_cnt1"/> | 3 | <counter_set name="ARM_Mali-400_FP1_cnt" count="2"/> |
4 | </counter_set> | 4 | <counter_set name="ARM_Mali-400_FP2_cnt" count="2"/> |
5 | <counter_set name="ARM_Mali-400_FP0_cntX"> | 5 | <counter_set name="ARM_Mali-400_FP3_cnt" count="2"/> |
6 | <counter name="ARM_Mali-400_FP0_cnt0"/> | 6 | <counter_set name="ARM_Mali-400_L2_cnt" count="2"/> |
7 | <counter name="ARM_Mali-400_FP0_cnt1"/> | 7 | <counter_set name="ARM_Mali-400_SW_cnt" count="0"/> |
8 | </counter_set> | 8 | <counter_set name="ARM_Mali-400_Filmstrip_cnt" count="1"/> |
9 | <counter_set name="ARM_Mali-400_FP1_cntX"> | 9 | <category name="Mali-400-VP" counter_set="ARM_Mali-400_VP_cnt" per_cpu="no"> |
10 | <counter name="ARM_Mali-400_FP1_cnt0"/> | ||
11 | <counter name="ARM_Mali-400_FP1_cnt1"/> | ||
12 | </counter_set> | ||
13 | <counter_set name="ARM_Mali-400_FP2_cntX"> | ||
14 | <counter name="ARM_Mali-400_FP2_cnt0"/> | ||
15 | <counter name="ARM_Mali-400_FP2_cnt1"/> | ||
16 | </counter_set> | ||
17 | <counter_set name="ARM_Mali-400_FP3_cntX"> | ||
18 | <counter name="ARM_Mali-400_FP3_cnt0"/> | ||
19 | <counter name="ARM_Mali-400_FP3_cnt1"/> | ||
20 | </counter_set> | ||
21 | <counter_set name="ARM_Mali-400_L2_cntX"> | ||
22 | <counter name="ARM_Mali-400_L2_cnt0"/> | ||
23 | <counter name="ARM_Mali-400_L2_cnt1"/> | ||
24 | </counter_set> | ||
25 | <counter_set name="ARM_Mali-400_SW_cntX"> | ||
26 | </counter_set> | ||
27 | <counter_set name="ARM_Mali-400_Filmstrip_cntX"> | ||
28 | <counter name="ARM_Mali-400_Filmstrip"/> | ||
29 | </counter_set> | ||
30 | <category name="Mali-400-VP" counter_set="ARM_Mali-400_VP_cntX" per_cpu="no"> | ||
31 | <event event="0x01" title="Mali GPU Vertex Processor" name="Active cycles" description="Number of cycles per frame the MaliGP2 was active."/> | 10 | <event event="0x01" title="Mali GPU Vertex Processor" name="Active cycles" description="Number of cycles per frame the MaliGP2 was active."/> |
32 | <event event="0x02" title="Mali GPU Vertex Processor" name="Active cycles, vertex shader" description="Number of cycles per frame the vertex shader unit was active."/> | 11 | <event event="0x02" title="Mali GPU Vertex Processor" name="Active cycles, vertex shader" description="Number of cycles per frame the vertex shader unit was active."/> |
33 | <event event="0x03" title="Mali GPU Vertex Processor" name="Active cycles, vertex storer" description="Number of cycles per frame the vertex storer unit was active."/> | 12 | <event event="0x03" title="Mali GPU Vertex Processor" name="Active cycles, vertex storer" description="Number of cycles per frame the vertex storer unit was active."/> |
@@ -54,7 +33,7 @@ | |||
54 | <event event="0x20" title="Mali GPU Vertex Processor" name="Active cycles, Scissor tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over tiles to perform scissoringi. This includes time spent waiting on the bus."/> | 33 | <event event="0x20" title="Mali GPU Vertex Processor" name="Active cycles, Scissor tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over tiles to perform scissoringi. This includes time spent waiting on the bus."/> |
55 | <event event="0x21" title="Mali GPU Vertex Processor" name="Active cycles, PLBU tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over the tiles in the bounding box generating commands (mainly graphics primitives). This includes time spent waiting on the bus."/> | 34 | <event event="0x21" title="Mali GPU Vertex Processor" name="Active cycles, PLBU tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over the tiles in the bounding box generating commands (mainly graphics primitives). This includes time spent waiting on the bus."/> |
56 | </category> | 35 | </category> |
57 | <category name="Mali-400-FP0" counter_set="ARM_Mali-400_FP0_cntX" per_cpu="no"> | 36 | <category name="Mali-400-FP0" counter_set="ARM_Mali-400_FP0_cnt" per_cpu="no"> |
58 | <event event="0x00" title="Mali GPU Fragment Processor 0" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> | 37 | <event event="0x00" title="Mali GPU Fragment Processor 0" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> |
59 | <event event="0x02" title="Mali GPU Fragment Processor 0" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> | 38 | <event event="0x02" title="Mali GPU Fragment Processor 0" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> |
60 | <event event="0x03" title="Mali GPU Fragment Processor 0" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> | 39 | <event event="0x03" title="Mali GPU Fragment Processor 0" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> |
@@ -113,7 +92,7 @@ | |||
113 | <event event="0x3c" title="Mali GPU Fragment Processor 0" name="Program cache hit count" description="Number of hits in the program cache."/> | 92 | <event event="0x3c" title="Mali GPU Fragment Processor 0" name="Program cache hit count" description="Number of hits in the program cache."/> |
114 | <event event="0x3d" title="Mali GPU Fragment Processor 0" name="Program cache miss count" description="Number of misses in the program cache."/> | 93 | <event event="0x3d" title="Mali GPU Fragment Processor 0" name="Program cache miss count" description="Number of misses in the program cache."/> |
115 | </category> | 94 | </category> |
116 | <category name="Mali-400-FP1" counter_set="ARM_Mali-400_FP1_cntX" per_cpu="no"> | 95 | <category name="Mali-400-FP1" counter_set="ARM_Mali-400_FP1_cnt" per_cpu="no"> |
117 | <event event="0x00" title="Mali GPU Fragment Processor 1" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> | 96 | <event event="0x00" title="Mali GPU Fragment Processor 1" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> |
118 | <event event="0x02" title="Mali GPU Fragment Processor 1" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> | 97 | <event event="0x02" title="Mali GPU Fragment Processor 1" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> |
119 | <event event="0x03" title="Mali GPU Fragment Processor 1" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> | 98 | <event event="0x03" title="Mali GPU Fragment Processor 1" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> |
@@ -172,7 +151,7 @@ | |||
172 | <event event="0x3c" title="Mali GPU Fragment Processor 1" name="Program cache hit count" description="Number of hits in the program cache."/> | 151 | <event event="0x3c" title="Mali GPU Fragment Processor 1" name="Program cache hit count" description="Number of hits in the program cache."/> |
173 | <event event="0x3d" title="Mali GPU Fragment Processor 1" name="Program cache miss count" description="Number of misses in the program cache."/> | 152 | <event event="0x3d" title="Mali GPU Fragment Processor 1" name="Program cache miss count" description="Number of misses in the program cache."/> |
174 | </category> | 153 | </category> |
175 | <category name="Mali-400-FP2" counter_set="ARM_Mali-400_FP2_cntX" per_cpu="no"> | 154 | <category name="Mali-400-FP2" counter_set="ARM_Mali-400_FP2_cnt" per_cpu="no"> |
176 | <event event="0x00" title="Mali GPU Fragment Processor 2" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> | 155 | <event event="0x00" title="Mali GPU Fragment Processor 2" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> |
177 | <event event="0x02" title="Mali GPU Fragment Processor 2" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> | 156 | <event event="0x02" title="Mali GPU Fragment Processor 2" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> |
178 | <event event="0x03" title="Mali GPU Fragment Processor 2" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> | 157 | <event event="0x03" title="Mali GPU Fragment Processor 2" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> |
@@ -231,7 +210,7 @@ | |||
231 | <event event="0x3c" title="Mali GPU Fragment Processor 2" name="Program cache hit count" description="Number of hits in the program cache."/> | 210 | <event event="0x3c" title="Mali GPU Fragment Processor 2" name="Program cache hit count" description="Number of hits in the program cache."/> |
232 | <event event="0x3d" title="Mali GPU Fragment Processor 2" name="Program cache miss count" description="Number of misses in the program cache."/> | 211 | <event event="0x3d" title="Mali GPU Fragment Processor 2" name="Program cache miss count" description="Number of misses in the program cache."/> |
233 | </category> | 212 | </category> |
234 | <category name="Mali-400-FP3" counter_set="ARM_Mali-400_FP3_cntX" per_cpu="no"> | 213 | <category name="Mali-400-FP3" counter_set="ARM_Mali-400_FP3_cnt" per_cpu="no"> |
235 | <event event="0x00" title="Mali GPU Fragment Processor 3" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> | 214 | <event event="0x00" title="Mali GPU Fragment Processor 3" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> |
236 | <event event="0x02" title="Mali GPU Fragment Processor 3" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> | 215 | <event event="0x02" title="Mali GPU Fragment Processor 3" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> |
237 | <event event="0x03" title="Mali GPU Fragment Processor 3" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> | 216 | <event event="0x03" title="Mali GPU Fragment Processor 3" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> |
@@ -290,7 +269,7 @@ | |||
290 | <event event="0x3c" title="Mali GPU Fragment Processor 3" name="Program cache hit count" description="Number of hits in the program cache."/> | 269 | <event event="0x3c" title="Mali GPU Fragment Processor 3" name="Program cache hit count" description="Number of hits in the program cache."/> |
291 | <event event="0x3d" title="Mali GPU Fragment Processor 3" name="Program cache miss count" description="Number of misses in the program cache."/> | 270 | <event event="0x3d" title="Mali GPU Fragment Processor 3" name="Program cache miss count" description="Number of misses in the program cache."/> |
292 | </category> | 271 | </category> |
293 | <category name="Mali-400-L2" counter_set="ARM_Mali-400_L2_cntX" per_cpu="no"> | 272 | <category name="Mali-400-L2" counter_set="ARM_Mali-400_L2_cnt" per_cpu="no"> |
294 | <event event="0x01" title="Mali L2 Cache" name="Total clock cycles" description="Total clock cycles."/> | 273 | <event event="0x01" title="Mali L2 Cache" name="Total clock cycles" description="Total clock cycles."/> |
295 | <event event="0x02" title="Mali L2 Cache" name="Active clock cycles" description="Active clock cycles." /> | 274 | <event event="0x02" title="Mali L2 Cache" name="Active clock cycles" description="Active clock cycles." /> |
296 | <event event="0x08" title="Mali L2 Cache" name="Read transactions, master" description="Read transactions, master." /> | 275 | <event event="0x08" title="Mali L2 Cache" name="Read transactions, master" description="Read transactions, master." /> |
@@ -352,7 +331,7 @@ | |||
352 | <event event="0x67" title="Mali L2 Cache" name="Read invalidates, slave 4" description="Read invalidates, slave 4." /> | 331 | <event event="0x67" title="Mali L2 Cache" name="Read invalidates, slave 4" description="Read invalidates, slave 4." /> |
353 | <event event="0x68" title="Mali L2 Cache" name="Cacheable read transactions, slave 4" description="Cacheable read transactions, slave 4." /> | 332 | <event event="0x68" title="Mali L2 Cache" name="Cacheable read transactions, slave 4" description="Cacheable read transactions, slave 4." /> |
354 | </category> | 333 | </category> |
355 | <category name="ARM_Mali-400_Filmstrip" counter_set="ARM_Mali-400_Filmstrip_cntX" per_cpu="no"> | 334 | <category name="ARM_Mali-400_Filmstrip" counter_set="ARM_Mali-400_Filmstrip_cnt" per_cpu="no"> |
356 | <event event="0x040a" title="ARM_Mali-400_Filmstrip" name="Freq 1:10" description="Scaled framebuffer captures every 10th frame." /> | 335 | <event event="0x040a" title="ARM_Mali-400_Filmstrip" name="Freq 1:10" description="Scaled framebuffer captures every 10th frame." /> |
357 | <event event="0x041e" title="ARM_Mali-400_Filmstrip" name="Freq 1:30" description="Scaled framebuffer captures every 30th frame." /> | 336 | <event event="0x041e" title="ARM_Mali-400_Filmstrip" name="Freq 1:30" description="Scaled framebuffer captures every 30th frame." /> |
358 | <event event="0x043c" title="ARM_Mali-400_Filmstrip" name="Freq 1:60" description="Scaled framebuffer captures every 60th frame." /> | 337 | <event event="0x043c" title="ARM_Mali-400_Filmstrip" name="Freq 1:60" description="Scaled framebuffer captures every 60th frame." /> |
@@ -363,7 +342,7 @@ | |||
363 | <category name="ARM_Mali-400_Frequency" per_cpu="no"> | 342 | <category name="ARM_Mali-400_Frequency" per_cpu="no"> |
364 | <event counter="ARM_Mali-400_Frequency" title="Mali GPU Frequency" name="Frequency" display="average" average_selection="yes" units="MHz" description="GPU core frequency."/> | 343 | <event counter="ARM_Mali-400_Frequency" title="Mali GPU Frequency" name="Frequency" display="average" average_selection="yes" units="MHz" description="GPU core frequency."/> |
365 | </category> | 344 | </category> |
366 | <category name="Mali-400-SW" counter_set="ARM_Mali-400_SW_cntX" per_cpu="no"> | 345 | <category name="Mali-400-SW" counter_set="ARM_Mali-400_SW_cnt" per_cpu="no"> |
367 | <!-- EGL Counters --> | 346 | <!-- EGL Counters --> |
368 | <event counter="ARM_Mali-400_SW_17" title="Mali EGL Software Counters" name="Blit Time" description="Time spent blitting the the framebuffer from video memory to framebuffer."/> | 347 | <event counter="ARM_Mali-400_SW_17" title="Mali EGL Software Counters" name="Blit Time" description="Time spent blitting the the framebuffer from video memory to framebuffer."/> |
369 | <!-- glDrawElements Counters --> | 348 | <!-- glDrawElements Counters --> |
diff --git a/daemon/events-Scorpion.xml b/daemon/events-Scorpion.xml index 51ed937..1642e85 100644 --- a/daemon/events-Scorpion.xml +++ b/daemon/events-Scorpion.xml | |||
@@ -1,10 +1,5 @@ | |||
1 | <counter_set name="Scorpion_cntX"> | 1 | <counter_set name="Scorpion_cnt" count="4"/> |
2 | <counter name="Scorpion_cnt0"/> | 2 | <category name="Scorpion" counter_set="Scorpion_cnt" per_cpu="yes" supports_event_based_sampling="yes"> |
3 | <counter name="Scorpion_cnt1"/> | ||
4 | <counter name="Scorpion_cnt2"/> | ||
5 | <counter name="Scorpion_cnt3"/> | ||
6 | </counter_set> | ||
7 | <category name="Scorpion" counter_set="Scorpion_cntX" per_cpu="yes"> | ||
8 | <event counter="Scorpion_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="Scorpion_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
9 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> | 4 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> |
10 | <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"/> | 5 | <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"/> |
diff --git a/daemon/events-ScorpionMP.xml b/daemon/events-ScorpionMP.xml index d3dd430..42acc64 100644 --- a/daemon/events-ScorpionMP.xml +++ b/daemon/events-ScorpionMP.xml | |||
@@ -1,10 +1,5 @@ | |||
1 | <counter_set name="ScorpionMP_cntX"> | 1 | <counter_set name="ScorpionMP_cnt" count="4"/> |
2 | <counter name="ScorpionMP_cnt0"/> | 2 | <category name="ScorpionMP" counter_set="ScorpionMP_cnt" per_cpu="yes" supports_event_based_sampling="yes"> |
3 | <counter name="ScorpionMP_cnt1"/> | ||
4 | <counter name="ScorpionMP_cnt2"/> | ||
5 | <counter name="ScorpionMP_cnt3"/> | ||
6 | </counter_set> | ||
7 | <category name="ScorpionMP" counter_set="ScorpionMP_cntX" per_cpu="yes"> | ||
8 | <event counter="ScorpionMP_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> | 3 | <event counter="ScorpionMP_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> |
9 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> | 4 | <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> |
10 | <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"/> | 5 | <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"/> |
diff --git a/daemon/main.cpp b/daemon/main.cpp index d972913..5bc75ef 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <sys/types.h> | 17 | #include <sys/types.h> |
18 | #include <sys/stat.h> | 18 | #include <sys/stat.h> |
19 | #include <sys/mount.h> | 19 | #include <sys/mount.h> |
20 | #include <fcntl.h> | ||
21 | #include <sys/mman.h> | ||
20 | #include "Child.h" | 22 | #include "Child.h" |
21 | #include "SessionData.h" | 23 | #include "SessionData.h" |
22 | #include "OlySocket.h" | 24 | #include "OlySocket.h" |
@@ -114,6 +116,26 @@ int mountGatorFS() { | |||
114 | } | 116 | } |
115 | } | 117 | } |
116 | 118 | ||
119 | bool init_module (const char * const location) { | ||
120 | bool ret(false); | ||
121 | const int fd = open(location, O_RDONLY); | ||
122 | if (fd >= 0) { | ||
123 | struct stat st; | ||
124 | if (fstat(fd, &st) == 0) { | ||
125 | void * const p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | ||
126 | if (p != MAP_FAILED) { | ||
127 | if (syscall(__NR_init_module, p, st.st_size, "") == 0) { | ||
128 | ret = true; | ||
129 | } | ||
130 | munmap(p, st.st_size); | ||
131 | } | ||
132 | } | ||
133 | close(fd); | ||
134 | } | ||
135 | |||
136 | return ret; | ||
137 | } | ||
138 | |||
117 | int setupFilesystem(char* module) { | 139 | int setupFilesystem(char* module) { |
118 | int retval; | 140 | int retval; |
119 | 141 | ||
@@ -162,11 +184,15 @@ int setupFilesystem(char* module) { | |||
162 | } | 184 | } |
163 | 185 | ||
164 | // Load driver | 186 | // Load driver |
165 | snprintf(command, sizeof(command), "insmod %s >/dev/null 2>&1", location); | 187 | bool success = init_module(location); |
166 | if (system(command) != 0) { | 188 | if (!success) { |
167 | logg->logMessage("Unable to load gator.ko driver with command: %s", command); | 189 | logg->logMessage("init_module failed, trying insmod"); |
168 | 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"); | 190 | snprintf(command, sizeof(command), "insmod %s >/dev/null 2>&1", location); |
169 | handleException(); | 191 | if (system(command) != 0) { |
192 | logg->logMessage("Unable to load gator.ko driver with command: %s", command); | ||
193 | 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"); | ||
194 | handleException(); | ||
195 | } | ||
170 | } | 196 | } |
171 | 197 | ||
172 | if (mountGatorFS() == -1) { | 198 | if (mountGatorFS() == -1) { |
@@ -183,8 +209,11 @@ int shutdownFilesystem() { | |||
183 | umount("/dev/gator"); | 209 | umount("/dev/gator"); |
184 | } | 210 | } |
185 | if (driverRunningAtStart == false) { | 211 | if (driverRunningAtStart == false) { |
186 | if (system("rmmod gator >/dev/null 2>&1") != 0) { | 212 | if (syscall(__NR_delete_module, "gator", O_NONBLOCK) != 0) { |
187 | return -1; | 213 | logg->logMessage("delete_module failed, trying rmmod"); |
214 | if (system("rmmod gator >/dev/null 2>&1") != 0) { | ||
215 | return -1; | ||
216 | } | ||
188 | } | 217 | } |
189 | } | 218 | } |
190 | 219 | ||
@@ -205,7 +234,7 @@ struct cmdline_t parseCommandLine(int argc, char** argv) { | |||
205 | snprintf(version_string, sizeof(version_string), "Streamline gatord development version %d", PROTOCOL_VERSION); | 234 | snprintf(version_string, sizeof(version_string), "Streamline gatord development version %d", PROTOCOL_VERSION); |
206 | } | 235 | } |
207 | 236 | ||
208 | while ((c = getopt(argc, argv, "hvp:s:c:e:m:")) != -1) { | 237 | while ((c = getopt(argc, argv, "hvp:s:c:e:m:o:")) != -1) { |
209 | switch(c) { | 238 | switch(c) { |
210 | case 'c': | 239 | case 'c': |
211 | gSessionData->mConfigurationXMLPath = optarg; | 240 | gSessionData->mConfigurationXMLPath = optarg; |
@@ -222,6 +251,9 @@ struct cmdline_t parseCommandLine(int argc, char** argv) { | |||
222 | case 's': | 251 | case 's': |
223 | gSessionData->mSessionXMLPath = optarg; | 252 | gSessionData->mSessionXMLPath = optarg; |
224 | break; | 253 | break; |
254 | case 'o': | ||
255 | gSessionData->mTargetPath = optarg; | ||
256 | break; | ||
225 | case 'h': | 257 | case 'h': |
226 | case '?': | 258 | case '?': |
227 | logg->logError(__FILE__, __LINE__, | 259 | logg->logError(__FILE__, __LINE__, |
@@ -232,6 +264,7 @@ struct cmdline_t parseCommandLine(int argc, char** argv) { | |||
232 | "-m module path and filename of gator.ko\n" | 264 | "-m module path and filename of gator.ko\n" |
233 | "-p port_number port upon which the server listens; default is 8080\n" | 265 | "-p port_number port upon which the server listens; default is 8080\n" |
234 | "-s session_xml path and filename of a session xml used for local capture\n" | 266 | "-s session_xml path and filename of a session xml used for local capture\n" |
267 | "-o apc_dir path and name of the output for a local capture\n" | ||
235 | "-v version information\n" | 268 | "-v version information\n" |
236 | , version_string); | 269 | , version_string); |
237 | handleException(); | 270 | handleException(); |
@@ -249,6 +282,11 @@ struct cmdline_t parseCommandLine(int argc, char** argv) { | |||
249 | handleException(); | 282 | handleException(); |
250 | } | 283 | } |
251 | 284 | ||
285 | if (gSessionData->mTargetPath != NULL && gSessionData->mSessionXMLPath == NULL) { | ||
286 | logg->logError(__FILE__, __LINE__, "Missing -s command line option required for a local capture."); | ||
287 | handleException(); | ||
288 | } | ||
289 | |||
252 | if (optind < argc) { | 290 | if (optind < argc) { |
253 | logg->logError(__FILE__, __LINE__, "Unknown argument: %s. Use '-h' for help.", argv[optind]); | 291 | logg->logError(__FILE__, __LINE__, "Unknown argument: %s. Use '-h' for help.", argv[optind]); |
254 | handleException(); | 292 | handleException(); |
@@ -259,6 +297,7 @@ struct cmdline_t parseCommandLine(int argc, char** argv) { | |||
259 | 297 | ||
260 | // Gator data flow: collector -> collector fifo -> sender | 298 | // Gator data flow: collector -> collector fifo -> sender |
261 | int main(int argc, char** argv, char* envp[]) { | 299 | int main(int argc, char** argv, char* envp[]) { |
300 | setsid(); | ||
262 | gSessionData = new SessionData(); // Global data class | 301 | gSessionData = new SessionData(); // Global data class |
263 | logg = new Logging(DEBUG); // Set up global thread-safe logging | 302 | logg = new Logging(DEBUG); // Set up global thread-safe logging |
264 | util = new OlyUtility(); // Set up global utility class | 303 | util = new OlyUtility(); // Set up global utility class |
diff --git a/driver/Makefile b/driver/Makefile index 025dd9e..6cafecf 100644 --- a/driver/Makefile +++ b/driver/Makefile | |||
@@ -27,6 +27,10 @@ gator-y += gator_events_mali_common.o | |||
27 | EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT) | 27 | EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT) |
28 | endif | 28 | endif |
29 | 29 | ||
30 | # GATOR_TEST controls whether to include (=1) or exclude (=0) test code. | ||
31 | GATOR_TEST ?= 0 | ||
32 | EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST) | ||
33 | |||
30 | gator-$(CONFIG_ARM) += gator_events_armv6.o \ | 34 | gator-$(CONFIG_ARM) += gator_events_armv6.o \ |
31 | gator_events_armv7.o \ | 35 | gator_events_armv7.o \ |
32 | gator_events_l2c-310.o \ | 36 | gator_events_l2c-310.o \ |
diff --git a/driver/gator.h b/driver/gator.h index 6b96109..5a40e17 100644 --- a/driver/gator.h +++ b/driver/gator.h | |||
@@ -20,19 +20,20 @@ | |||
20 | #define GATOR_CPU_FREQ_SUPPORT (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) && defined(CONFIG_CPU_FREQ) | 20 | #define GATOR_CPU_FREQ_SUPPORT (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) && defined(CONFIG_CPU_FREQ) |
21 | 21 | ||
22 | // cpu ids | 22 | // cpu ids |
23 | #define ARM1136 0xb36 | 23 | #define ARM1136 0xb36 |
24 | #define ARM1156 0xb56 | 24 | #define ARM1156 0xb56 |
25 | #define ARM1176 0xb76 | 25 | #define ARM1176 0xb76 |
26 | #define ARM11MPCORE 0xb02 | 26 | #define ARM11MPCORE 0xb02 |
27 | #define CORTEX_A5 0xc05 | 27 | #define CORTEX_A5 0xc05 |
28 | #define CORTEX_A7 0xc07 | 28 | #define CORTEX_A7 0xc07 |
29 | #define CORTEX_A8 0xc08 | 29 | #define CORTEX_A8 0xc08 |
30 | #define CORTEX_A9 0xc09 | 30 | #define CORTEX_A9 0xc09 |
31 | #define CORTEX_A15 0xc0f | 31 | #define CORTEX_A15 0xc0f |
32 | #define SCORPION 0x00f | 32 | #define SCORPION 0x00f |
33 | #define SCORPIONMP 0x02d | 33 | #define SCORPIONMP 0x02d |
34 | #define KRAITSIM 0x049 | 34 | #define KRAITSIM 0x049 |
35 | #define KRAIT 0x04d | 35 | #define KRAIT 0x04d |
36 | #define AARCH64 0xd0f | ||
36 | 37 | ||
37 | /****************************************************************************** | 38 | /****************************************************************************** |
38 | * Filesystem | 39 | * Filesystem |
@@ -97,4 +98,6 @@ int gator_events_install(struct gator_interface *interface); | |||
97 | int gator_events_get_key(void); | 98 | int gator_events_get_key(void); |
98 | extern u32 gator_cpuid(void); | 99 | extern u32 gator_cpuid(void); |
99 | 100 | ||
101 | void gator_backtrace_handler(struct pt_regs * const regs); | ||
102 | |||
100 | #endif // GATOR_H_ | 103 | #endif // GATOR_H_ |
diff --git a/driver/gator_annotate.c b/driver/gator_annotate.c index b444789..928e252 100644 --- a/driver/gator_annotate.c +++ b/driver/gator_annotate.c | |||
@@ -38,26 +38,34 @@ static int annotate_copy(struct file *file, char const __user *buf, size_t count | |||
38 | 38 | ||
39 | static ssize_t annotate_write(struct file *file, char const __user *buf, size_t count_orig, loff_t *offset) | 39 | static ssize_t annotate_write(struct file *file, char const __user *buf, size_t count_orig, loff_t *offset) |
40 | { | 40 | { |
41 | int tid, cpu, header_size, available, contiguous, length1, length2, size, count = count_orig & 0x7fffffff; | 41 | int pid, cpu, header_size, available, contiguous, length1, length2, size, count = count_orig & 0x7fffffff; |
42 | 42 | ||
43 | if (*offset) | 43 | if (*offset) { |
44 | return -EINVAL; | 44 | return -EINVAL; |
45 | } | ||
46 | |||
47 | // Annotation is not supported in interrupt context | ||
48 | if (in_interrupt()) { | ||
49 | return -EINVAL; | ||
50 | } | ||
45 | 51 | ||
46 | if (!collect_annotations) | 52 | // synchronize between cores and with collect_annotations |
53 | spin_lock(&annotate_lock); | ||
54 | |||
55 | if (!collect_annotations) { | ||
47 | // Not collecting annotations, tell the caller everything was written | 56 | // Not collecting annotations, tell the caller everything was written |
48 | return count_orig; | 57 | size = count_orig; |
58 | goto annotate_write_out; | ||
59 | } | ||
49 | 60 | ||
50 | cpu = 0; // Annotation only uses a single per-cpu buffer as the data must be in order to the engine | 61 | cpu = 0; // Annotation only uses a single per-cpu buffer as the data must be in order to the engine |
51 | 62 | ||
52 | if (file == NULL) { | 63 | if (current == NULL) { |
53 | tid = -1; // set the thread id to the kernel thread | 64 | pid = 0; |
54 | } else { | 65 | } else { |
55 | tid = current->pid; | 66 | pid = current->pid; |
56 | } | 67 | } |
57 | 68 | ||
58 | // synchronize between cores | ||
59 | spin_lock(&annotate_lock); | ||
60 | |||
61 | // determine total size of the payload | 69 | // determine total size of the payload |
62 | header_size = MAXSIZE_PACK32 * 3 + MAXSIZE_PACK64; | 70 | header_size = MAXSIZE_PACK32 * 3 + MAXSIZE_PACK64; |
63 | available = buffer_bytes_available(cpu, ANNOTATE_BUF) - header_size; | 71 | available = buffer_bytes_available(cpu, ANNOTATE_BUF) - header_size; |
@@ -71,9 +79,9 @@ static ssize_t annotate_write(struct file *file, char const __user *buf, size_t | |||
71 | } | 79 | } |
72 | 80 | ||
73 | // synchronize shared variables annotateBuf and annotatePos | 81 | // synchronize shared variables annotateBuf and annotatePos |
74 | if (collect_annotations && per_cpu(gator_buffer, cpu)[ANNOTATE_BUF]) { | 82 | if (per_cpu(gator_buffer, cpu)[ANNOTATE_BUF]) { |
75 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id()); | 83 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id()); |
76 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, tid); | 84 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid); |
77 | gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, gator_get_time()); | 85 | gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, gator_get_time()); |
78 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, size); | 86 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, size); |
79 | 87 | ||
@@ -118,9 +126,9 @@ static int annotate_release(struct inode *inode, struct file *file) | |||
118 | spin_lock(&annotate_lock); | 126 | spin_lock(&annotate_lock); |
119 | 127 | ||
120 | if (per_cpu(gator_buffer, cpu)[ANNOTATE_BUF] && buffer_check_space(cpu, ANNOTATE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) { | 128 | if (per_cpu(gator_buffer, cpu)[ANNOTATE_BUF] && buffer_check_space(cpu, ANNOTATE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) { |
121 | uint32_t tid = current->pid; | 129 | uint32_t pid = current->pid; |
122 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id()); | 130 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id()); |
123 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, tid); | 131 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid); |
124 | gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time | 132 | gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time |
125 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size | 133 | gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size |
126 | } | 134 | } |
@@ -148,5 +156,8 @@ static int gator_annotate_start(void) | |||
148 | 156 | ||
149 | static void gator_annotate_stop(void) | 157 | static void gator_annotate_stop(void) |
150 | { | 158 | { |
159 | // the spinlock here will ensure that when this function exits, we are not in the middle of an annotation | ||
160 | spin_lock(&annotate_lock); | ||
151 | collect_annotations = false; | 161 | collect_annotations = false; |
162 | spin_unlock(&annotate_lock); | ||
152 | } | 163 | } |
diff --git a/driver/gator_annotate_kernel.c b/driver/gator_annotate_kernel.c index ffab087..bc68fa8 100644 --- a/driver/gator_annotate_kernel.c +++ b/driver/gator_annotate_kernel.c | |||
@@ -7,50 +7,83 @@ | |||
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | ||
10 | static void kannotate_write(char* ptr, unsigned int size) | 10 | #define ESCAPE_CODE 0x1c |
11 | #define STRING_ANNOTATION 0x03 | ||
12 | #define VISUAL_ANNOTATION 0x04 | ||
13 | #define MARKER_ANNOTATION 0x05 | ||
14 | |||
15 | static void kannotate_write(const char* ptr, unsigned int size) | ||
11 | { | 16 | { |
12 | int retval; | 17 | int retval; |
13 | int pos = 0; | 18 | int pos = 0; |
14 | loff_t offset = 0; | 19 | loff_t offset = 0; |
15 | while (pos < size) { | 20 | while (pos < size) { |
16 | retval = annotate_write(NULL, &ptr[pos], size - pos, &offset); | 21 | retval = annotate_write(NULL, &ptr[pos], size - pos, &offset); |
17 | if (retval < 0) { | 22 | if (retval < 0) { |
18 | printk(KERN_WARNING "gator: kannotate_write failed with return value %d\n", retval); | 23 | printk(KERN_WARNING "gator: kannotate_write failed with return value %d\n", retval); |
19 | return; | 24 | return; |
20 | } | 25 | } |
21 | pos += retval; | 26 | pos += retval; |
22 | } | 27 | } |
23 | } | 28 | } |
24 | 29 | ||
30 | static void gator_annotate_code(char code) | ||
31 | { | ||
32 | int header = ESCAPE_CODE | (code << 8); | ||
33 | kannotate_write((char*)&header, sizeof(header)); | ||
34 | } | ||
35 | |||
36 | static void gator_annotate_code_str(char code, const char* string) | ||
37 | { | ||
38 | int str_size = strlen(string) & 0xffff; | ||
39 | int header = ESCAPE_CODE | (code << 8) | (str_size << 16); | ||
40 | kannotate_write((char*)&header, sizeof(header)); | ||
41 | kannotate_write(string, str_size); | ||
42 | } | ||
43 | |||
44 | static void gator_annotate_code_color(char code, int color) | ||
45 | { | ||
46 | long long header = (ESCAPE_CODE | (code << 8) | 0x00040000 | ((long long)color << 32)); | ||
47 | kannotate_write((char*)&header, sizeof(header)); | ||
48 | } | ||
49 | |||
50 | static void gator_annotate_code_color_str(char code, int color, const char* string) | ||
51 | { | ||
52 | int str_size = (strlen(string) + 4) & 0xffff; | ||
53 | long long header = ESCAPE_CODE | (code << 8) | (str_size << 16) | ((long long)color << 32); | ||
54 | kannotate_write((char*)&header, sizeof(header)); | ||
55 | kannotate_write(string, str_size - 4); | ||
56 | } | ||
57 | |||
25 | // String annotation | 58 | // String annotation |
26 | void gator_annotate(char* string) | 59 | void gator_annotate(const char* string) |
27 | { | 60 | { |
28 | kannotate_write(string, strlen(string) + 1); | 61 | gator_annotate_code_str(STRING_ANNOTATION, string); |
29 | } | 62 | } |
30 | EXPORT_SYMBOL(gator_annotate); | 63 | EXPORT_SYMBOL(gator_annotate); |
31 | 64 | ||
32 | // String annotation with color | 65 | // String annotation with color |
33 | void gator_annotate_color(int color, char* string) | 66 | void gator_annotate_color(int color, const char* string) |
34 | { | 67 | { |
35 | kannotate_write((char*)&color, sizeof(color)); | 68 | gator_annotate_code_color_str(STRING_ANNOTATION, color, string); |
36 | kannotate_write(string, strlen(string) + 1); | ||
37 | } | 69 | } |
38 | EXPORT_SYMBOL(gator_annotate_color); | 70 | EXPORT_SYMBOL(gator_annotate_color); |
39 | 71 | ||
40 | // Terminate an annotation | 72 | // Terminate an annotation |
41 | void gator_annotate_end(void) | 73 | void gator_annotate_end(void) |
42 | { | 74 | { |
43 | char nul = 0; | 75 | gator_annotate_code(STRING_ANNOTATION); |
44 | kannotate_write(&nul, sizeof(nul)); | ||
45 | } | 76 | } |
46 | EXPORT_SYMBOL(gator_annotate_end); | 77 | EXPORT_SYMBOL(gator_annotate_end); |
47 | 78 | ||
48 | // Image annotation with optional string | 79 | // Image annotation with optional string |
49 | void gator_annotate_visual(char* data, unsigned int length, char* string) | 80 | void gator_annotate_visual(const char* data, unsigned int length, const char* string) |
50 | { | 81 | { |
51 | long long visual_annotation = 0x011c | (strlen(string) << 16) | ((long long)length << 32); | 82 | int str_size = strlen(string) & 0xffff; |
52 | kannotate_write((char*)&visual_annotation, 8); | 83 | int visual_annotation = ESCAPE_CODE | (VISUAL_ANNOTATION << 8) | (str_size << 16); |
53 | kannotate_write(string, strlen(string)); | 84 | kannotate_write((char*)&visual_annotation, sizeof(visual_annotation)); |
85 | kannotate_write(string, str_size); | ||
86 | kannotate_write((char*)&length, sizeof(length)); | ||
54 | kannotate_write(data, length); | 87 | kannotate_write(data, length); |
55 | } | 88 | } |
56 | EXPORT_SYMBOL(gator_annotate_visual); | 89 | EXPORT_SYMBOL(gator_annotate_visual); |
@@ -58,33 +91,27 @@ EXPORT_SYMBOL(gator_annotate_visual); | |||
58 | // Marker annotation | 91 | // Marker annotation |
59 | void gator_annotate_marker(void) | 92 | void gator_annotate_marker(void) |
60 | { | 93 | { |
61 | int marker_annotation = 0x00021c; | 94 | gator_annotate_code(MARKER_ANNOTATION); |
62 | kannotate_write((char*)&marker_annotation, 3); | ||
63 | } | 95 | } |
64 | EXPORT_SYMBOL(gator_annotate_marker); | 96 | EXPORT_SYMBOL(gator_annotate_marker); |
65 | 97 | ||
66 | // Marker annotation with a string | 98 | // Marker annotation with a string |
67 | void gator_annotate_marker_str(char* string) | 99 | void gator_annotate_marker_str(const char* string) |
68 | { | 100 | { |
69 | int marker_annotation = 0x021c; | 101 | gator_annotate_code_str(MARKER_ANNOTATION, string); |
70 | kannotate_write((char*)&marker_annotation, 2); | ||
71 | kannotate_write(string, strlen(string) + 1); | ||
72 | } | 102 | } |
73 | EXPORT_SYMBOL(gator_annotate_marker_str); | 103 | EXPORT_SYMBOL(gator_annotate_marker_str); |
74 | 104 | ||
75 | // Marker annotation with a color | 105 | // Marker annotation with a color |
76 | void gator_annotate_marker_color(int color) | 106 | void gator_annotate_marker_color(int color) |
77 | { | 107 | { |
78 | long long marker_annotation = (0x021c | ((long long)color << 16)) & 0x0000ffffffffffffLL; | 108 | gator_annotate_code_color(MARKER_ANNOTATION, color); |
79 | kannotate_write((char*)&marker_annotation, 7); | ||
80 | } | 109 | } |
81 | EXPORT_SYMBOL(gator_annotate_marker_color); | 110 | EXPORT_SYMBOL(gator_annotate_marker_color); |
82 | 111 | ||
83 | // Marker annotationw ith a string and color | 112 | // Marker annotation with a string and color |
84 | void gator_annotate_marker_color_str(int color, char* string) | 113 | void gator_annotate_marker_color_str(int color, const char* string) |
85 | { | 114 | { |
86 | long long marker_annotation = 0x021c | ((long long)color << 16); | 115 | gator_annotate_code_color_str(MARKER_ANNOTATION, color, string); |
87 | kannotate_write((char*)&marker_annotation, 6); | ||
88 | kannotate_write(string, strlen(string) + 1); | ||
89 | } | 116 | } |
90 | EXPORT_SYMBOL(gator_annotate_marker_color_str); | 117 | EXPORT_SYMBOL(gator_annotate_marker_color_str); |
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c index 50783d6..2173d8a 100644 --- a/driver/gator_backtrace.c +++ b/driver/gator_backtrace.c | |||
@@ -15,7 +15,7 @@ struct frame_tail_eabi { | |||
15 | unsigned long lr; | 15 | unsigned long lr; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | static void arm_backtrace_eabi(int cpu, int buftype, struct pt_regs * const regs, unsigned int depth) | 18 | static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth) |
19 | { | 19 | { |
20 | #if defined(__arm__) | 20 | #if defined(__arm__) |
21 | struct frame_tail_eabi *tail; | 21 | struct frame_tail_eabi *tail; |
@@ -32,7 +32,7 @@ static void arm_backtrace_eabi(int cpu, int buftype, struct pt_regs * const regs | |||
32 | } | 32 | } |
33 | 33 | ||
34 | /* entry preamble may not have executed */ | 34 | /* entry preamble may not have executed */ |
35 | gator_add_trace(cpu, buftype, lr); | 35 | gator_add_trace(cpu, lr); |
36 | 36 | ||
37 | /* check tail is valid */ | 37 | /* check tail is valid */ |
38 | if (fp == 0 || fp < sp) { | 38 | if (fp == 0 || fp < sp) { |
@@ -50,7 +50,7 @@ static void arm_backtrace_eabi(int cpu, int buftype, struct pt_regs * const regs | |||
50 | ptrtail = &buftail; | 50 | ptrtail = &buftail; |
51 | 51 | ||
52 | lr = ptrtail[0].lr; | 52 | lr = ptrtail[0].lr; |
53 | gator_add_trace(cpu, buftype, lr); | 53 | gator_add_trace(cpu, lr); |
54 | 54 | ||
55 | /* frame pointers should progress back up the stack, towards higher addresses */ | 55 | /* frame pointers should progress back up the stack, towards higher addresses */ |
56 | next = (struct frame_tail_eabi *)(lr - 4); | 56 | next = (struct frame_tail_eabi *)(lr - 4); |
@@ -69,16 +69,16 @@ static void arm_backtrace_eabi(int cpu, int buftype, struct pt_regs * const regs | |||
69 | } | 69 | } |
70 | 70 | ||
71 | #if defined(__arm__) | 71 | #if defined(__arm__) |
72 | static DEFINE_PER_CPU(int, backtrace_buffer); | ||
73 | static int report_trace(struct stackframe *frame, void *d) | 72 | static int report_trace(struct stackframe *frame, void *d) |
74 | { | 73 | { |
75 | struct module *mod; | 74 | struct module *mod; |
76 | unsigned int *depth = d, addr = frame->pc, cookie = NO_COOKIE, cpu = smp_processor_id(); | 75 | unsigned int *depth = d, cookie = NO_COOKIE, cpu = smp_processor_id(); |
76 | unsigned long addr = frame->pc; | ||
77 | 77 | ||
78 | if (*depth) { | 78 | if (*depth) { |
79 | mod = __module_address(addr); | 79 | mod = __module_address(addr); |
80 | if (mod) { | 80 | if (mod) { |
81 | cookie = get_cookie(cpu, per_cpu(backtrace_buffer, cpu), current, NULL, mod, true); | 81 | cookie = get_cookie(cpu, current, NULL, mod, true); |
82 | addr = addr - (unsigned long)mod->module_core; | 82 | addr = addr - (unsigned long)mod->module_core; |
83 | } | 83 | } |
84 | marshal_backtrace(addr & ~1, cookie); | 84 | marshal_backtrace(addr & ~1, cookie); |
@@ -91,7 +91,7 @@ static int report_trace(struct stackframe *frame, void *d) | |||
91 | 91 | ||
92 | // Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile | 92 | // Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile |
93 | // #define GATOR_KERNEL_STACK_UNWINDING | 93 | // #define GATOR_KERNEL_STACK_UNWINDING |
94 | static void kernel_backtrace(int cpu, int buftype, struct pt_regs * const regs) | 94 | static void kernel_backtrace(int cpu, struct pt_regs * const regs) |
95 | { | 95 | { |
96 | #if defined(__arm__) | 96 | #if defined(__arm__) |
97 | #ifdef GATOR_KERNEL_STACK_UNWINDING | 97 | #ifdef GATOR_KERNEL_STACK_UNWINDING |
@@ -106,7 +106,6 @@ static void kernel_backtrace(int cpu, int buftype, struct pt_regs * const regs) | |||
106 | frame.sp = regs->ARM_sp; | 106 | frame.sp = regs->ARM_sp; |
107 | frame.lr = regs->ARM_lr; | 107 | frame.lr = regs->ARM_lr; |
108 | frame.pc = regs->ARM_pc; | 108 | frame.pc = regs->ARM_pc; |
109 | per_cpu(backtrace_buffer, cpu) = buftype; | ||
110 | walk_stackframe(&frame, report_trace, &depth); | 109 | walk_stackframe(&frame, report_trace, &depth); |
111 | #else | 110 | #else |
112 | marshal_backtrace(PC_REG & ~1, NO_COOKIE); | 111 | marshal_backtrace(PC_REG & ~1, NO_COOKIE); |
diff --git a/driver/gator_cookies.c b/driver/gator_cookies.c index d7d8e84..21dc4eb 100644 --- a/driver/gator_cookies.c +++ b/driver/gator_cookies.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #define MAX_COLLISIONS 2 | 12 | #define MAX_COLLISIONS 2 |
13 | 13 | ||
14 | static uint32_t *gator_crc32_table; | 14 | static uint32_t *gator_crc32_table; |
15 | static uint32_t translate_buffer_mask; | 15 | static unsigned int translate_buffer_mask; |
16 | 16 | ||
17 | static DEFINE_PER_CPU(char *, translate_text); | 17 | static DEFINE_PER_CPU(char *, translate_text); |
18 | static DEFINE_PER_CPU(uint32_t, cookie_next_key); | 18 | static DEFINE_PER_CPU(uint32_t, cookie_next_key); |
@@ -20,9 +20,9 @@ static DEFINE_PER_CPU(uint64_t *, cookie_keys); | |||
20 | static DEFINE_PER_CPU(uint32_t *, cookie_values); | 20 | static DEFINE_PER_CPU(uint32_t *, cookie_values); |
21 | static DEFINE_PER_CPU(int, translate_buffer_read); | 21 | static DEFINE_PER_CPU(int, translate_buffer_read); |
22 | static DEFINE_PER_CPU(int, translate_buffer_write); | 22 | static DEFINE_PER_CPU(int, translate_buffer_write); |
23 | static DEFINE_PER_CPU(unsigned int *, translate_buffer); | 23 | static DEFINE_PER_CPU(void * *, translate_buffer); |
24 | 24 | ||
25 | static inline uint32_t get_cookie(int cpu, int buftype, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt); | 25 | static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt); |
26 | static void wq_cookie_handler(struct work_struct *unused); | 26 | static void wq_cookie_handler(struct work_struct *unused); |
27 | DECLARE_WORK(cookie_work, wq_cookie_handler); | 27 | DECLARE_WORK(cookie_work, wq_cookie_handler); |
28 | static struct timer_list app_process_wake_up_timer; | 28 | static struct timer_list app_process_wake_up_timer; |
@@ -40,16 +40,16 @@ static uint32_t cookiemap_code(uint64_t value64) { | |||
40 | 40 | ||
41 | static uint32_t gator_chksum_crc32(char *data) | 41 | static uint32_t gator_chksum_crc32(char *data) |
42 | { | 42 | { |
43 | register unsigned long crc; | 43 | register unsigned long crc; |
44 | unsigned char *block = data; | 44 | unsigned char *block = data; |
45 | int i, length = strlen(data); | 45 | int i, length = strlen(data); |
46 | 46 | ||
47 | crc = 0xFFFFFFFF; | 47 | crc = 0xFFFFFFFF; |
48 | for (i = 0; i < length; i++) { | 48 | for (i = 0; i < length; i++) { |
49 | crc = ((crc >> 8) & 0x00FFFFFF) ^ gator_crc32_table[(crc ^ *block++) & 0xFF]; | 49 | crc = ((crc >> 8) & 0x00FFFFFF) ^ gator_crc32_table[(crc ^ *block++) & 0xFF]; |
50 | } | 50 | } |
51 | 51 | ||
52 | return (crc ^ 0xFFFFFFFF); | 52 | return (crc ^ 0xFFFFFFFF); |
53 | } | 53 | } |
54 | 54 | ||
55 | /* | 55 | /* |
@@ -104,15 +104,15 @@ static void cookiemap_add(uint64_t key, uint32_t value) { | |||
104 | values[0] = value; | 104 | values[0] = value; |
105 | } | 105 | } |
106 | 106 | ||
107 | static void translate_buffer_write_int(int cpu, unsigned int x) | 107 | static void translate_buffer_write_ptr(int cpu, void * x) |
108 | { | 108 | { |
109 | per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x; | 109 | per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x; |
110 | per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask; | 110 | per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask; |
111 | } | 111 | } |
112 | 112 | ||
113 | static unsigned int translate_buffer_read_int(int cpu) | 113 | static void * translate_buffer_read_ptr(int cpu) |
114 | { | 114 | { |
115 | unsigned int value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++]; | 115 | void * value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++]; |
116 | per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask; | 116 | per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask; |
117 | return value; | 117 | return value; |
118 | } | 118 | } |
@@ -129,9 +129,9 @@ static void wq_cookie_handler(struct work_struct *unused) | |||
129 | if (gator_started != 0) { | 129 | if (gator_started != 0) { |
130 | commit = per_cpu(translate_buffer_write, cpu); | 130 | commit = per_cpu(translate_buffer_write, cpu); |
131 | while (per_cpu(translate_buffer_read, cpu) != commit) { | 131 | while (per_cpu(translate_buffer_read, cpu) != commit) { |
132 | task = (struct task_struct *)translate_buffer_read_int(cpu); | 132 | task = (struct task_struct *)translate_buffer_read_ptr(cpu); |
133 | vma = (struct vm_area_struct *)translate_buffer_read_int(cpu); | 133 | vma = (struct vm_area_struct *)translate_buffer_read_ptr(cpu); |
134 | cookie = get_cookie(cpu, BACKTRACE_BUF, task, vma, NULL, false); | 134 | cookie = get_cookie(cpu, task, vma, NULL, false); |
135 | } | 135 | } |
136 | } | 136 | } |
137 | 137 | ||
@@ -163,13 +163,13 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task | |||
163 | // Check if already in buffer | 163 | // Check if already in buffer |
164 | ptr = per_cpu(translate_buffer_read, cpu); | 164 | ptr = per_cpu(translate_buffer_read, cpu); |
165 | while (ptr != per_cpu(translate_buffer_write, cpu)) { | 165 | while (ptr != per_cpu(translate_buffer_write, cpu)) { |
166 | if (per_cpu(translate_buffer, cpu)[ptr] == (int)task) | 166 | if (per_cpu(translate_buffer, cpu)[ptr] == (void *)task) |
167 | goto out; | 167 | goto out; |
168 | ptr = (ptr + 2) & translate_buffer_mask; | 168 | ptr = (ptr + 2) & translate_buffer_mask; |
169 | } | 169 | } |
170 | 170 | ||
171 | translate_buffer_write_int(cpu, (unsigned int)task); | 171 | translate_buffer_write_ptr(cpu, (void *)task); |
172 | translate_buffer_write_int(cpu, (unsigned int)vma); | 172 | translate_buffer_write_ptr(cpu, (void *)vma); |
173 | 173 | ||
174 | mod_timer(&app_process_wake_up_timer, jiffies + 1); | 174 | mod_timer(&app_process_wake_up_timer, jiffies + 1); |
175 | goto out; | 175 | goto out; |
@@ -222,7 +222,7 @@ out: | |||
222 | return retval; | 222 | return retval; |
223 | } | 223 | } |
224 | 224 | ||
225 | static inline uint32_t get_cookie(int cpu, int buftype, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt) | 225 | static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt) |
226 | { | 226 | { |
227 | unsigned long flags, cookie; | 227 | unsigned long flags, cookie; |
228 | struct path *path; | 228 | struct path *path; |
@@ -232,10 +232,13 @@ static inline uint32_t get_cookie(int cpu, int buftype, struct task_struct *task | |||
232 | if (mod) { | 232 | if (mod) { |
233 | text = mod->name; | 233 | text = mod->name; |
234 | } else { | 234 | } else { |
235 | if (!vma || !vma->vm_file) { | 235 | if (vma && vma->vm_file) { |
236 | path = &vma->vm_file->f_path; | ||
237 | } else if (task && task->mm && task->mm->exe_file) { | ||
238 | path = &task->mm->exe_file->f_path; | ||
239 | } else { | ||
236 | return INVALID_COOKIE; | 240 | return INVALID_COOKIE; |
237 | } | 241 | } |
238 | path = &vma->vm_file->f_path; | ||
239 | if (!path || !path->dentry) { | 242 | if (!path || !path->dentry) { |
240 | return INVALID_COOKIE; | 243 | return INVALID_COOKIE; |
241 | } | 244 | } |
@@ -271,29 +274,21 @@ static inline uint32_t get_cookie(int cpu, int buftype, struct task_struct *task | |||
271 | return cookie; | 274 | return cookie; |
272 | } | 275 | } |
273 | 276 | ||
274 | static int get_exec_cookie(int cpu, int buftype, struct task_struct *task) | 277 | static int get_exec_cookie(int cpu, struct task_struct *task) |
275 | { | 278 | { |
276 | unsigned long cookie = NO_COOKIE; | 279 | unsigned long cookie = NO_COOKIE; |
277 | struct mm_struct *mm = task->mm; | 280 | struct mm_struct *mm = task->mm; |
278 | struct vm_area_struct *vma; | ||
279 | 281 | ||
280 | // kernel threads have no address space | 282 | // kernel threads have no address space |
281 | if (!mm) | 283 | if (!mm) |
282 | return cookie; | 284 | return cookie; |
283 | 285 | ||
284 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 286 | cookie = get_cookie(cpu, task, NULL, NULL, true); |
285 | if (!vma->vm_file) | ||
286 | continue; | ||
287 | if (!(vma->vm_flags & VM_EXECUTABLE)) | ||
288 | continue; | ||
289 | cookie = get_cookie(cpu, buftype, task, vma, NULL, true); | ||
290 | break; | ||
291 | } | ||
292 | 287 | ||
293 | return cookie; | 288 | return cookie; |
294 | } | 289 | } |
295 | 290 | ||
296 | static unsigned long get_address_cookie(int cpu, int buftype, struct task_struct *task, unsigned long addr, off_t *offset) | 291 | static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsigned long addr, off_t *offset) |
297 | { | 292 | { |
298 | unsigned long cookie = NO_COOKIE; | 293 | unsigned long cookie = NO_COOKIE; |
299 | struct mm_struct *mm = task->mm; | 294 | struct mm_struct *mm = task->mm; |
@@ -307,7 +302,7 @@ static unsigned long get_address_cookie(int cpu, int buftype, struct task_struct | |||
307 | continue; | 302 | continue; |
308 | 303 | ||
309 | if (vma->vm_file) { | 304 | if (vma->vm_file) { |
310 | cookie = get_cookie(cpu, buftype, task, vma, NULL, true); | 305 | cookie = get_cookie(cpu, task, vma, NULL, true); |
311 | *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; | 306 | *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; |
312 | } else { | 307 | } else { |
313 | /* must be an anonymous map */ | 308 | /* must be an anonymous map */ |
@@ -350,7 +345,7 @@ static int cookies_initialize(void) | |||
350 | } | 345 | } |
351 | memset(per_cpu(cookie_values, cpu), 0, size); | 346 | memset(per_cpu(cookie_values, cpu), 0, size); |
352 | 347 | ||
353 | per_cpu(translate_buffer, cpu) = (unsigned int *)kmalloc(translate_buffer_size, GFP_KERNEL); | 348 | per_cpu(translate_buffer, cpu) = (void * *)kmalloc(translate_buffer_size, GFP_KERNEL); |
354 | if (!per_cpu(translate_buffer, cpu)) { | 349 | if (!per_cpu(translate_buffer, cpu)) { |
355 | err = -ENOMEM; | 350 | err = -ENOMEM; |
356 | goto cookie_setup_error; | 351 | goto cookie_setup_error; |
diff --git a/driver/gator_ebs.c b/driver/gator_ebs.c deleted file mode 100644 index 6abdfa4..0000000 --- a/driver/gator_ebs.c +++ /dev/null | |||
@@ -1,156 +0,0 @@ | |||
1 | /** | ||
2 | * Copyright (C) ARM Limited 2012. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #if defined(__arm__) && (GATOR_PERF_PMU_SUPPORT) | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/irq.h> | ||
14 | |||
15 | #include <asm/pmu.h> | ||
16 | |||
17 | static DEFINE_MUTEX(perf_mutex); | ||
18 | |||
19 | extern int pmnc_counters; | ||
20 | extern int ccnt; | ||
21 | extern unsigned long pmnc_enabled[]; | ||
22 | extern unsigned long pmnc_event[]; | ||
23 | extern unsigned long pmnc_count[]; | ||
24 | extern unsigned long pmnc_key[]; | ||
25 | |||
26 | static DEFINE_PER_CPU(struct perf_event_attr *, pevent_attr); | ||
27 | static DEFINE_PER_CPU(int, key); | ||
28 | |||
29 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) | ||
30 | static void ebs_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs) | ||
31 | #else | ||
32 | static void ebs_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) | ||
33 | #endif | ||
34 | { | ||
35 | int cpu = smp_processor_id(); | ||
36 | |||
37 | if (event != per_cpu(pevent_ebs, cpu)) | ||
38 | return; | ||
39 | |||
40 | // Output backtrace | ||
41 | gator_add_sample(cpu, BACKTRACE_BUF, regs); | ||
42 | |||
43 | // Collect counters | ||
44 | collect_counters(); | ||
45 | } | ||
46 | |||
47 | static void gator_event_sampling_online_dispatch(int cpu) | ||
48 | { | ||
49 | struct perf_event * ev; | ||
50 | |||
51 | if (!event_based_sampling) | ||
52 | return; | ||
53 | |||
54 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) | ||
55 | ev = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu), cpu, 0, ebs_overflow_handler); | ||
56 | #else | ||
57 | ev = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu), cpu, 0, ebs_overflow_handler, 0); | ||
58 | #endif | ||
59 | |||
60 | if (IS_ERR(ev)) { | ||
61 | pr_err("gator: unable to start event-based-sampling"); | ||
62 | return; | ||
63 | } | ||
64 | |||
65 | if (ev->state != PERF_EVENT_STATE_ACTIVE) { | ||
66 | pr_err("gator: unable to start event-based-sampling"); | ||
67 | perf_event_release_kernel(ev); | ||
68 | return; | ||
69 | } | ||
70 | |||
71 | ev->pmu->read(ev); | ||
72 | per_cpu(pevent_ebs, cpu) = ev; | ||
73 | } | ||
74 | |||
75 | static void gator_event_sampling_offline_dispatch(int cpu) | ||
76 | { | ||
77 | struct perf_event * pe = NULL; | ||
78 | |||
79 | mutex_lock(&perf_mutex); | ||
80 | if (per_cpu(pevent_ebs, cpu)) { | ||
81 | pe = per_cpu(pevent_ebs, cpu); | ||
82 | per_cpu(pevent_ebs, cpu) = NULL; | ||
83 | } | ||
84 | mutex_unlock(&perf_mutex); | ||
85 | |||
86 | if (pe) { | ||
87 | perf_event_release_kernel(pe); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | static int gator_event_sampling_start(void) | ||
92 | { | ||
93 | int cnt, event = 0, count = 0, ebs_key = 0, cpu; | ||
94 | |||
95 | for_each_present_cpu(cpu) { | ||
96 | per_cpu(pevent_ebs, cpu) = NULL; | ||
97 | per_cpu(pevent_attr, cpu) = NULL; | ||
98 | } | ||
99 | |||
100 | event_based_sampling = false; | ||
101 | for (cnt = 0; cnt < pmnc_counters; cnt++) { | ||
102 | if (pmnc_count[cnt] > 0) { | ||
103 | event_based_sampling = true; | ||
104 | event = pmnc_event[cnt]; | ||
105 | count = pmnc_count[cnt]; | ||
106 | ebs_key = pmnc_key[cnt]; | ||
107 | break; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | if (!event_based_sampling) | ||
112 | return 0; | ||
113 | |||
114 | for_each_present_cpu(cpu) { | ||
115 | u32 size = sizeof(struct perf_event_attr); | ||
116 | per_cpu(pevent_attr, cpu) = kmalloc(size, GFP_KERNEL); | ||
117 | if (!per_cpu(pevent_attr, cpu)) | ||
118 | return -1; | ||
119 | |||
120 | memset(per_cpu(pevent_attr, cpu), 0, size); | ||
121 | per_cpu(pevent_attr, cpu)->type = PERF_TYPE_RAW; | ||
122 | per_cpu(pevent_attr, cpu)->size = size; | ||
123 | per_cpu(pevent_attr, cpu)->config = event; | ||
124 | per_cpu(pevent_attr, cpu)->sample_period = count; | ||
125 | per_cpu(pevent_attr, cpu)->pinned = 1; | ||
126 | |||
127 | // handle special case for ccnt | ||
128 | if (cnt == ccnt) { | ||
129 | per_cpu(pevent_attr, cpu)->type = PERF_TYPE_HARDWARE; | ||
130 | per_cpu(pevent_attr, cpu)->config = PERF_COUNT_HW_CPU_CYCLES; | ||
131 | } | ||
132 | |||
133 | per_cpu(key, cpu) = ebs_key; | ||
134 | } | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static void gator_event_sampling_stop(void) | ||
140 | { | ||
141 | int cpu; | ||
142 | |||
143 | for_each_present_cpu(cpu) { | ||
144 | if (per_cpu(pevent_attr, cpu)) { | ||
145 | kfree(per_cpu(pevent_attr, cpu)); | ||
146 | per_cpu(pevent_attr, cpu) = NULL; | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | #else | ||
152 | static void gator_event_sampling_online_dispatch(int cpu) {} | ||
153 | static void gator_event_sampling_offline_dispatch(int cpu) {} | ||
154 | static int gator_event_sampling_start(void) {return 0;} | ||
155 | static void gator_event_sampling_stop(void) {} | ||
156 | #endif | ||
diff --git a/driver/gator_events_block.c b/driver/gator_events_block.c index a8b8114..b18c3ca 100644 --- a/driver/gator_events_block.c +++ b/driver/gator_events_block.c | |||
@@ -25,15 +25,13 @@ static ulong block_rq_wr_enabled; | |||
25 | static ulong block_rq_rd_enabled; | 25 | static ulong block_rq_rd_enabled; |
26 | static ulong block_rq_wr_key; | 26 | static ulong block_rq_wr_key; |
27 | static ulong block_rq_rd_key; | 27 | static ulong block_rq_rd_key; |
28 | static DEFINE_PER_CPU(int[BLOCK_TOTAL], blockCnt); | 28 | static atomic_t blockCnt[BLOCK_TOTAL]; |
29 | static DEFINE_PER_CPU(int[BLOCK_TOTAL * 4], blockGet); | 29 | static int blockGet[BLOCK_TOTAL * 4]; |
30 | static DEFINE_PER_CPU(bool, new_data_avail); | ||
31 | 30 | ||
32 | GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct request *rq)) | 31 | GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct request *rq)) |
33 | { | 32 | { |
34 | unsigned long flags; | 33 | unsigned long flags; |
35 | int write, size; | 34 | int write, size; |
36 | int cpu = smp_processor_id(); | ||
37 | 35 | ||
38 | if (!rq) | 36 | if (!rq) |
39 | return; | 37 | return; |
@@ -47,13 +45,16 @@ GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct r | |||
47 | // disable interrupts to synchronize with gator_events_block_read() | 45 | // disable interrupts to synchronize with gator_events_block_read() |
48 | // spinlocks not needed since percpu buffers are used | 46 | // spinlocks not needed since percpu buffers are used |
49 | local_irq_save(flags); | 47 | local_irq_save(flags); |
50 | if (write) | 48 | if (write) { |
51 | per_cpu(blockCnt, cpu)[BLOCK_RQ_WR] += size; | 49 | if (block_rq_wr_enabled) { |
52 | else | 50 | atomic_add(size, &blockCnt[BLOCK_RQ_WR]); |
53 | per_cpu(blockCnt, cpu)[BLOCK_RQ_RD] += size; | 51 | } |
52 | } else { | ||
53 | if (block_rq_rd_enabled) { | ||
54 | atomic_add(size, &blockCnt[BLOCK_RQ_RD]); | ||
55 | } | ||
56 | } | ||
54 | local_irq_restore(flags); | 57 | local_irq_restore(flags); |
55 | |||
56 | per_cpu(new_data_avail, cpu) = true; | ||
57 | } | 58 | } |
58 | 59 | ||
59 | static int gator_events_block_create_files(struct super_block *sb, struct dentry *root) | 60 | static int gator_events_block_create_files(struct super_block *sb, struct dentry *root) |
@@ -81,11 +82,6 @@ static int gator_events_block_create_files(struct super_block *sb, struct dentry | |||
81 | 82 | ||
82 | static int gator_events_block_start(void) | 83 | static int gator_events_block_start(void) |
83 | { | 84 | { |
84 | int cpu; | ||
85 | |||
86 | for_each_present_cpu(cpu) | ||
87 | per_cpu(new_data_avail, cpu) = true; | ||
88 | |||
89 | // register tracepoints | 85 | // register tracepoints |
90 | if (block_rq_wr_enabled || block_rq_rd_enabled) | 86 | if (block_rq_wr_enabled || block_rq_rd_enabled) |
91 | if (GATOR_REGISTER_TRACE(block_rq_complete)) | 87 | if (GATOR_REGISTER_TRACE(block_rq_complete)) |
@@ -113,44 +109,32 @@ static void gator_events_block_stop(void) | |||
113 | 109 | ||
114 | static int gator_events_block_read(int **buffer) | 110 | static int gator_events_block_read(int **buffer) |
115 | { | 111 | { |
116 | unsigned long flags; | 112 | int len, value, data = 0; |
117 | int len, value, cpu, data = 0; | ||
118 | cpu = smp_processor_id(); | ||
119 | 113 | ||
120 | if (per_cpu(new_data_avail, cpu) == false) | 114 | if (smp_processor_id() != 0) { |
121 | return 0; | 115 | return 0; |
122 | 116 | } | |
123 | per_cpu(new_data_avail, cpu) = false; | ||
124 | 117 | ||
125 | len = 0; | 118 | len = 0; |
126 | if (block_rq_wr_enabled) { | 119 | if (block_rq_wr_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_WR])) > 0) { |
127 | local_irq_save(flags); | 120 | atomic_sub(value, &blockCnt[BLOCK_RQ_WR]); |
128 | value = per_cpu(blockCnt, cpu)[BLOCK_RQ_WR]; | 121 | blockGet[len++] = block_rq_wr_key; |
129 | per_cpu(blockCnt, cpu)[BLOCK_RQ_WR] = 0; | 122 | blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message |
130 | local_irq_restore(flags); | 123 | blockGet[len++] = block_rq_wr_key; |
131 | per_cpu(blockGet, cpu)[len++] = block_rq_wr_key; | 124 | blockGet[len++] = value; |
132 | per_cpu(blockGet, cpu)[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message | ||
133 | per_cpu(blockGet, cpu)[len++] = block_rq_wr_key; | ||
134 | per_cpu(blockGet, cpu)[len++] = value; | ||
135 | data += value; | 125 | data += value; |
136 | } | 126 | } |
137 | if (block_rq_rd_enabled) { | 127 | if (block_rq_rd_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_RD])) > 0) { |
138 | local_irq_save(flags); | 128 | atomic_sub(value, &blockCnt[BLOCK_RQ_RD]); |
139 | value = per_cpu(blockCnt, cpu)[BLOCK_RQ_RD]; | 129 | blockGet[len++] = block_rq_rd_key; |
140 | per_cpu(blockCnt, cpu)[BLOCK_RQ_RD] = 0; | 130 | blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message |
141 | local_irq_restore(flags); | 131 | blockGet[len++] = block_rq_rd_key; |
142 | per_cpu(blockGet, cpu)[len++] = block_rq_rd_key; | 132 | blockGet[len++] = value; |
143 | per_cpu(blockGet, cpu)[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message | ||
144 | per_cpu(blockGet, cpu)[len++] = block_rq_rd_key; | ||
145 | per_cpu(blockGet, cpu)[len++] = value; | ||
146 | data += value; | 133 | data += value; |
147 | } | 134 | } |
148 | 135 | ||
149 | if (data != 0) | ||
150 | per_cpu(new_data_avail, cpu) = true; | ||
151 | |||
152 | if (buffer) | 136 | if (buffer) |
153 | *buffer = per_cpu(blockGet, cpu); | 137 | *buffer = blockGet; |
154 | 138 | ||
155 | return len; | 139 | return len; |
156 | } | 140 | } |
diff --git a/driver/gator_events_mali_400.c b/driver/gator_events_mali_400.c index 38d5b3d..a44cd8e 100644 --- a/driver/gator_events_mali_400.c +++ b/driver/gator_events_mali_400.c | |||
@@ -393,7 +393,7 @@ static int create_files(struct super_block *sb, struct dentry *root) { | |||
393 | 393 | ||
394 | switch(event) { | 394 | switch(event) { |
395 | case COUNTER_FILMSTRIP: | 395 | case COUNTER_FILMSTRIP: |
396 | snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip", mali_name); | 396 | snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name); |
397 | break; | 397 | break; |
398 | 398 | ||
399 | case COUNTER_FREQUENCY: | 399 | case COUNTER_FREQUENCY: |
diff --git a/driver/gator_events_mali_400.h b/driver/gator_events_mali_400.h index b784ae9..a09757e 100644 --- a/driver/gator_events_mali_400.h +++ b/driver/gator_events_mali_400.h | |||
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /** |
2 | * This confidential and proprietary software may be used only as | 2 | * Copyright (C) ARM Limited 2011-2012. All rights reserved. |
3 | * authorised by a licensing agreement from ARM Limited | 3 | * |
4 | * (C) COPYRIGHT 2011-2012 ARM Limited | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * ALL RIGHTS RESERVED | 5 | * it under the terms of the GNU General Public License version 2 as |
6 | * The entire notice above must be reproduced on all authorised | 6 | * published by the Free Software Foundation. |
7 | * copies and copies may only be made to the extent permitted | 7 | * |
8 | * by a licensing agreement from ARM Limited. | ||
9 | */ | 8 | */ |
10 | 9 | ||
11 | /* | 10 | /* |
diff --git a/driver/gator_events_mali_common.c b/driver/gator_events_mali_common.c index 2dd9ad6..62e441c 100644 --- a/driver/gator_events_mali_common.c +++ b/driver/gator_events_mali_common.c | |||
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /** |
2 | * This confidential and proprietary software may be used only as | 2 | * Copyright (C) ARM Limited 2012. All rights reserved. |
3 | * authorised by a licensing agreement from ARM Limited | 3 | * |
4 | * (C) COPYRIGHT 2011-2012 ARM Limited | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * ALL RIGHTS RESERVED | 5 | * it under the terms of the GNU General Public License version 2 as |
6 | * The entire notice above must be reproduced on all authorised | 6 | * published by the Free Software Foundation. |
7 | * copies and copies may only be made to the extent permitted | 7 | * |
8 | * by a licensing agreement from ARM Limited. | ||
9 | */ | 8 | */ |
10 | #include "gator_events_mali_common.h" | 9 | #include "gator_events_mali_common.h" |
11 | 10 | ||
diff --git a/driver/gator_events_mali_common.h b/driver/gator_events_mali_common.h index cb851d5..2c9457f 100644 --- a/driver/gator_events_mali_common.h +++ b/driver/gator_events_mali_common.h | |||
@@ -1,12 +1,12 @@ | |||
1 | /* | 1 | /** |
2 | * This confidential and proprietary software may be used only as | 2 | * Copyright (C) ARM Limited 2012. All rights reserved. |
3 | * authorised by a licensing agreement from ARM Limited | 3 | * |
4 | * (C) COPYRIGHT 2011-2012 ARM Limited | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * ALL RIGHTS RESERVED | 5 | * it under the terms of the GNU General Public License version 2 as |
6 | * The entire notice above must be reproduced on all authorised | 6 | * published by the Free Software Foundation. |
7 | * copies and copies may only be made to the extent permitted | 7 | * |
8 | * by a licensing agreement from ARM Limited. | ||
9 | */ | 8 | */ |
9 | |||
10 | #if !defined(GATOR_EVENTS_MALI_COMMON_H) | 10 | #if !defined(GATOR_EVENTS_MALI_COMMON_H) |
11 | #define GATOR_EVENTS_MALI_COMMON_H | 11 | #define GATOR_EVENTS_MALI_COMMON_H |
12 | 12 | ||
@@ -39,6 +39,9 @@ typedef struct { | |||
39 | unsigned long enabled; /* counter enable state */ | 39 | unsigned long enabled; /* counter enable state */ |
40 | } mali_counter; | 40 | } mali_counter; |
41 | 41 | ||
42 | /* | ||
43 | * Mali-400 | ||
44 | */ | ||
42 | typedef void mali_profiling_set_event_type(unsigned int, unsigned int); | 45 | typedef void mali_profiling_set_event_type(unsigned int, unsigned int); |
43 | typedef void mali_osk_fb_control_set_type(unsigned int, unsigned int); | 46 | typedef void mali_osk_fb_control_set_type(unsigned int, unsigned int); |
44 | typedef void mali_profiling_control_type(unsigned int, unsigned int); | 47 | typedef void mali_profiling_control_type(unsigned int, unsigned int); |
diff --git a/driver/gator_events_mali_t6xx.c b/driver/gator_events_mali_t6xx.c index 79af764..f8f868e 100644 --- a/driver/gator_events_mali_t6xx.c +++ b/driver/gator_events_mali_t6xx.c | |||
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /** |
2 | * This confidential and proprietary software may be used only as | 2 | * Copyright (C) ARM Limited 2011-2012. All rights reserved. |
3 | * authorised by a licensing agreement from ARM Limited | 3 | * |
4 | * (C) COPYRIGHT 2011 ARM Limited | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * ALL RIGHTS RESERVED | 5 | * it under the terms of the GNU General Public License version 2 as |
6 | * The entire notice above must be reproduced on all authorised | 6 | * published by the Free Software Foundation. |
7 | * copies and copies may only be made to the extent permitted | 7 | * |
8 | * by a licensing agreement from ARM Limited. | ||
9 | */ | 8 | */ |
10 | 9 | ||
11 | #include "gator.h" | 10 | #include "gator.h" |
diff --git a/driver/gator_events_mali_t6xx_hw.c b/driver/gator_events_mali_t6xx_hw.c index 12ffebc..854d02d 100644 --- a/driver/gator_events_mali_t6xx_hw.c +++ b/driver/gator_events_mali_t6xx_hw.c | |||
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /** |
2 | * This confidential and proprietary software may be used only as | 2 | * Copyright (C) ARM Limited 2012. All rights reserved. |
3 | * authorised by a licensing agreement from ARM Limited | 3 | * |
4 | * (C) COPYRIGHT 2011-2012 ARM Limited | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * ALL RIGHTS RESERVED | 5 | * it under the terms of the GNU General Public License version 2 as |
6 | * The entire notice above must be reproduced on all authorised | 6 | * published by the Free Software Foundation. |
7 | * copies and copies may only be made to the extent permitted | 7 | * |
8 | * by a licensing agreement from ARM Limited. | ||
9 | */ | 8 | */ |
10 | 9 | ||
11 | #include "gator.h" | 10 | #include "gator.h" |
@@ -23,6 +22,39 @@ | |||
23 | 22 | ||
24 | #include "gator_events_mali_common.h" | 23 | #include "gator_events_mali_common.h" |
25 | 24 | ||
25 | /* | ||
26 | * Mali-T6xx | ||
27 | */ | ||
28 | typedef struct kbase_device *kbase_find_device_type(int); | ||
29 | typedef kbase_context *kbase_create_context_type(kbase_device*); | ||
30 | typedef void kbase_destroy_context_type(kbase_context *); | ||
31 | typedef void *kbase_va_alloc_type(kbase_context *, u32); | ||
32 | typedef void kbase_va_free_type(kbase_context *, void *); | ||
33 | typedef mali_error kbase_instr_hwcnt_enable_type(kbase_context *, kbase_uk_hwcnt_setup *); | ||
34 | typedef mali_error kbase_instr_hwcnt_disable_type(kbase_context *); | ||
35 | typedef mali_error kbase_instr_hwcnt_clear_type(kbase_context *); | ||
36 | typedef mali_error kbase_instr_hwcnt_dump_irq_type(kbase_context *); | ||
37 | typedef mali_bool kbase_instr_hwcnt_dump_complete_type(kbase_context *, mali_bool *); | ||
38 | |||
39 | static kbase_find_device_type * kbase_find_device_symbol; | ||
40 | static kbase_create_context_type * kbase_create_context_symbol; | ||
41 | static kbase_va_alloc_type * kbase_va_alloc_symbol; | ||
42 | static kbase_instr_hwcnt_enable_type * kbase_instr_hwcnt_enable_symbol; | ||
43 | static kbase_instr_hwcnt_clear_type * kbase_instr_hwcnt_clear_symbol; | ||
44 | static kbase_instr_hwcnt_dump_irq_type * kbase_instr_hwcnt_dump_irq_symbol; | ||
45 | static kbase_instr_hwcnt_dump_complete_type * kbase_instr_hwcnt_dump_complete_symbol; | ||
46 | static kbase_instr_hwcnt_disable_type * kbase_instr_hwcnt_disable_symbol; | ||
47 | static kbase_va_free_type * kbase_va_free_symbol; | ||
48 | static kbase_destroy_context_type * kbase_destroy_context_symbol; | ||
49 | |||
50 | /** The interval between reads, in ns. */ | ||
51 | static const int READ_INTERVAL_NSEC = 1000000; | ||
52 | |||
53 | |||
54 | #if GATOR_TEST | ||
55 | #include "gator_events_mali_t6xx_hw_test.c" | ||
56 | #endif | ||
57 | |||
26 | /* Blocks for HW counters */ | 58 | /* Blocks for HW counters */ |
27 | enum | 59 | enum |
28 | { | 60 | { |
@@ -322,7 +354,12 @@ static void *kernel_dump_buffer; | |||
322 | static kbase_context *kbcontext = NULL; | 354 | static kbase_context *kbcontext = NULL; |
323 | static struct kbase_device *kbdevice = NULL; | 355 | static struct kbase_device *kbdevice = NULL; |
324 | 356 | ||
325 | extern struct kbase_device *kbase_find_device(int minor); | 357 | /* |
358 | * The following function has no external prototype in older DDK revisions. When the DDK | ||
359 | * is updated then this should be removed. | ||
360 | */ | ||
361 | struct kbase_device *kbase_find_device(int minor); | ||
362 | |||
326 | static volatile bool kbase_device_busy = false; | 363 | static volatile bool kbase_device_busy = false; |
327 | static unsigned int num_hardware_counters_enabled; | 364 | static unsigned int num_hardware_counters_enabled; |
328 | 365 | ||
@@ -336,6 +373,96 @@ static mali_counter counters[NUMBER_OF_HARDWARE_COUNTERS]; | |||
336 | */ | 373 | */ |
337 | static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2]; | 374 | static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2]; |
338 | 375 | ||
376 | #define SYMBOL_GET(FUNCTION, ERROR_COUNT) \ | ||
377 | if(FUNCTION ## _symbol) \ | ||
378 | { \ | ||
379 | printk("gator: mali " #FUNCTION " symbol was already registered\n"); \ | ||
380 | (ERROR_COUNT)++; \ | ||
381 | } \ | ||
382 | else \ | ||
383 | { \ | ||
384 | FUNCTION ## _symbol = symbol_get(FUNCTION); \ | ||
385 | if(! FUNCTION ## _symbol) \ | ||
386 | { \ | ||
387 | printk("gator: mali online " #FUNCTION " symbol not found\n"); \ | ||
388 | (ERROR_COUNT)++; \ | ||
389 | } \ | ||
390 | } | ||
391 | |||
392 | #define SYMBOL_CLEANUP(FUNCTION) \ | ||
393 | if(FUNCTION ## _symbol) \ | ||
394 | { \ | ||
395 | symbol_put(FUNCTION); \ | ||
396 | FUNCTION ## _symbol = NULL; \ | ||
397 | } | ||
398 | |||
399 | /** | ||
400 | * Execute symbol_get for all the Mali symbols and check for success. | ||
401 | * @return the number of symbols not loaded. | ||
402 | */ | ||
403 | static int init_symbols(void) | ||
404 | { | ||
405 | int error_count = 0; | ||
406 | SYMBOL_GET(kbase_find_device, error_count); | ||
407 | SYMBOL_GET(kbase_create_context, error_count); | ||
408 | SYMBOL_GET(kbase_va_alloc, error_count); | ||
409 | SYMBOL_GET(kbase_instr_hwcnt_enable, error_count); | ||
410 | SYMBOL_GET(kbase_instr_hwcnt_clear, error_count); | ||
411 | SYMBOL_GET(kbase_instr_hwcnt_dump_irq, error_count); | ||
412 | SYMBOL_GET(kbase_instr_hwcnt_dump_complete, error_count); | ||
413 | SYMBOL_GET(kbase_instr_hwcnt_disable, error_count); | ||
414 | SYMBOL_GET(kbase_va_free, error_count); | ||
415 | SYMBOL_GET(kbase_destroy_context, error_count); | ||
416 | |||
417 | return error_count; | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * Execute symbol_put for all the registered Mali symbols. | ||
422 | */ | ||
423 | static void clean_symbols(void) | ||
424 | { | ||
425 | SYMBOL_CLEANUP(kbase_find_device); | ||
426 | SYMBOL_CLEANUP(kbase_create_context); | ||
427 | SYMBOL_CLEANUP(kbase_va_alloc); | ||
428 | SYMBOL_CLEANUP(kbase_instr_hwcnt_enable); | ||
429 | SYMBOL_CLEANUP(kbase_instr_hwcnt_clear); | ||
430 | SYMBOL_CLEANUP(kbase_instr_hwcnt_dump_irq); | ||
431 | SYMBOL_CLEANUP(kbase_instr_hwcnt_dump_complete); | ||
432 | SYMBOL_CLEANUP(kbase_instr_hwcnt_disable); | ||
433 | SYMBOL_CLEANUP(kbase_va_free); | ||
434 | SYMBOL_CLEANUP(kbase_destroy_context); | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * Determines whether a read should take place | ||
439 | * @param current_time The current time, obtained from getnstimeofday() | ||
440 | * @param prev_time_s The number of seconds at the previous read attempt. | ||
441 | * @param next_read_time_ns The time (in ns) when the next read should be allowed. | ||
442 | * | ||
443 | * Note that this function has been separated out here to allow it to be tested. | ||
444 | */ | ||
445 | static int is_read_scheduled(const struct timespec *current_time, u32* prev_time_s, s32* next_read_time_ns) | ||
446 | { | ||
447 | /* If the current ns count rolls over a second, roll the next read time too. */ | ||
448 | if(current_time->tv_sec != *prev_time_s) | ||
449 | { | ||
450 | *next_read_time_ns = *next_read_time_ns - NSEC_PER_SEC; | ||
451 | } | ||
452 | |||
453 | /* Abort the read if the next read time has not arrived. */ | ||
454 | if(current_time->tv_nsec < *next_read_time_ns) | ||
455 | { | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | /* Set the next read some fixed time after this one, and update the read timestamp. */ | ||
460 | *next_read_time_ns = current_time->tv_nsec + READ_INTERVAL_NSEC; | ||
461 | |||
462 | *prev_time_s = current_time->tv_sec; | ||
463 | return 1; | ||
464 | } | ||
465 | |||
339 | static int start(void) | 466 | static int start(void) |
340 | { | 467 | { |
341 | kbase_uk_hwcnt_setup setup; | 468 | kbase_uk_hwcnt_setup setup; |
@@ -368,12 +495,23 @@ static int start(void) | |||
368 | /* Create a kbase context for HW counters */ | 495 | /* Create a kbase context for HW counters */ |
369 | if (num_hardware_counters_enabled > 0) | 496 | if (num_hardware_counters_enabled > 0) |
370 | { | 497 | { |
371 | kbdevice = kbase_find_device(-1); | 498 | if(init_symbols() > 0) |
372 | 499 | { | |
373 | if (kbcontext) | 500 | clean_symbols(); |
374 | return -1; | 501 | /* No Mali driver code entrypoints found - not a fault. */ |
375 | 502 | return 0; | |
376 | kbcontext = kbase_create_context(kbdevice); | 503 | } |
504 | |||
505 | kbdevice = kbase_find_device_symbol(-1); | ||
506 | |||
507 | /* If we already got a context, fail */ | ||
508 | if (kbcontext) { | ||
509 | pr_debug("gator: Mali-T6xx: error context already present\n"); | ||
510 | goto out; | ||
511 | } | ||
512 | |||
513 | /* kbcontext will only be valid after all the Mali symbols are loaded successfully */ | ||
514 | kbcontext = kbase_create_context_symbol(kbdevice); | ||
377 | if (!kbcontext) | 515 | if (!kbcontext) |
378 | { | 516 | { |
379 | pr_debug("gator: Mali-T6xx: error creating kbase context\n"); | 517 | pr_debug("gator: Mali-T6xx: error creating kbase context\n"); |
@@ -388,7 +526,7 @@ static int start(void) | |||
388 | * * number of bytes per counter (always 4 in midgard) | 526 | * * number of bytes per counter (always 4 in midgard) |
389 | * For a Mali-T6xx with a single core group = 1 * 8 * 64 * 4 | 527 | * For a Mali-T6xx with a single core group = 1 * 8 * 64 * 4 |
390 | */ | 528 | */ |
391 | kernel_dump_buffer = kbase_va_alloc(kbcontext, 2048); | 529 | kernel_dump_buffer = kbase_va_alloc_symbol(kbcontext, 2048); |
392 | if (!kernel_dump_buffer) | 530 | if (!kernel_dump_buffer) |
393 | { | 531 | { |
394 | pr_debug("gator: Mali-T6xx: error trying to allocate va\n"); | 532 | pr_debug("gator: Mali-T6xx: error trying to allocate va\n"); |
@@ -404,14 +542,14 @@ static int start(void) | |||
404 | setup.l3_cache_bm = 0; | 542 | setup.l3_cache_bm = 0; |
405 | 543 | ||
406 | /* Use kbase API to enable hardware counters and provide dump buffer */ | 544 | /* Use kbase API to enable hardware counters and provide dump buffer */ |
407 | err = kbase_instr_hwcnt_enable(kbcontext, &setup); | 545 | err = kbase_instr_hwcnt_enable_symbol(kbcontext, &setup); |
408 | if (err != MALI_ERROR_NONE) | 546 | if (err != MALI_ERROR_NONE) |
409 | { | 547 | { |
410 | pr_debug("gator: Mali-T6xx: can't setup hardware counters\n"); | 548 | pr_debug("gator: Mali-T6xx: can't setup hardware counters\n"); |
411 | goto free_buffer; | 549 | goto free_buffer; |
412 | } | 550 | } |
413 | pr_debug("gator: Mali-T6xx: hardware counters enabled\n"); | 551 | pr_debug("gator: Mali-T6xx: hardware counters enabled\n"); |
414 | kbase_instr_hwcnt_clear(kbcontext); | 552 | kbase_instr_hwcnt_clear_symbol(kbcontext); |
415 | pr_debug("gator: Mali-T6xx: hardware counters cleared \n"); | 553 | pr_debug("gator: Mali-T6xx: hardware counters cleared \n"); |
416 | 554 | ||
417 | kbase_device_busy = false; | 555 | kbase_device_busy = false; |
@@ -420,10 +558,13 @@ static int start(void) | |||
420 | return 0; | 558 | return 0; |
421 | 559 | ||
422 | free_buffer: | 560 | free_buffer: |
423 | kbase_va_free(kbcontext, kernel_dump_buffer); | 561 | kbase_va_free_symbol(kbcontext, kernel_dump_buffer); |
562 | |||
424 | destroy_context: | 563 | destroy_context: |
425 | kbase_destroy_context(kbcontext); | 564 | kbase_destroy_context_symbol(kbcontext); |
565 | |||
426 | out: | 566 | out: |
567 | clean_symbols(); | ||
427 | return -1; | 568 | return -1; |
428 | } | 569 | } |
429 | 570 | ||
@@ -448,10 +589,13 @@ static void stop(void) { | |||
448 | temp_kbcontext = kbcontext; | 589 | temp_kbcontext = kbcontext; |
449 | kbcontext = NULL; | 590 | kbcontext = NULL; |
450 | 591 | ||
451 | kbase_instr_hwcnt_disable(temp_kbcontext); | 592 | kbase_instr_hwcnt_disable_symbol(temp_kbcontext); |
452 | kbase_va_free(temp_kbcontext, kernel_dump_buffer); | 593 | kbase_va_free_symbol(temp_kbcontext, kernel_dump_buffer); |
453 | kbase_destroy_context(temp_kbcontext); | 594 | kbase_destroy_context_symbol(temp_kbcontext); |
595 | |||
454 | pr_debug("gator: Mali-T6xx: hardware counters stopped\n"); | 596 | pr_debug("gator: Mali-T6xx: hardware counters stopped\n"); |
597 | |||
598 | clean_symbols(); | ||
455 | } | 599 | } |
456 | } | 600 | } |
457 | 601 | ||
@@ -461,11 +605,26 @@ static int read(int **buffer) { | |||
461 | u32 value = 0; | 605 | u32 value = 0; |
462 | mali_bool success; | 606 | mali_bool success; |
463 | 607 | ||
608 | struct timespec current_time; | ||
609 | static u32 prev_time_s = 0; | ||
610 | static s32 next_read_time_ns = 0; | ||
611 | |||
464 | if (smp_processor_id()!=0) | 612 | if (smp_processor_id()!=0) |
465 | { | 613 | { |
466 | return 0; | 614 | return 0; |
467 | } | 615 | } |
468 | 616 | ||
617 | getnstimeofday(¤t_time); | ||
618 | |||
619 | /* | ||
620 | * Discard reads unless a respectable time has passed. This reduces the load on the GPU without sacrificing | ||
621 | * accuracy on the Streamline display. | ||
622 | */ | ||
623 | if(!is_read_scheduled(¤t_time, &prev_time_s, &next_read_time_ns)) | ||
624 | { | ||
625 | return 0; | ||
626 | } | ||
627 | |||
469 | /* | 628 | /* |
470 | * Report the HW counters | 629 | * Report the HW counters |
471 | * Only process hardware counters if at least one of the hardware counters is enabled. | 630 | * Only process hardware counters if at least one of the hardware counters is enabled. |
@@ -484,8 +643,8 @@ static int read(int **buffer) { | |||
484 | return -1; | 643 | return -1; |
485 | } | 644 | } |
486 | 645 | ||
487 | // TODO: SYMBOL_GET (all kbase functions) | 646 | /* Mali symbols can be called safely since a kbcontext is valid */ |
488 | if (kbase_instr_hwcnt_dump_complete(kbcontext, &success) == MALI_TRUE) | 647 | if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE) |
489 | { | 648 | { |
490 | kbase_device_busy = false; | 649 | kbase_device_busy = false; |
491 | 650 | ||
@@ -520,7 +679,7 @@ static int read(int **buffer) { | |||
520 | if (! kbase_device_busy) | 679 | if (! kbase_device_busy) |
521 | { | 680 | { |
522 | kbase_device_busy = true; | 681 | kbase_device_busy = true; |
523 | kbase_instr_hwcnt_dump_irq(kbcontext); | 682 | kbase_instr_hwcnt_dump_irq_symbol(kbcontext); |
524 | } | 683 | } |
525 | } | 684 | } |
526 | 685 | ||
@@ -551,7 +710,6 @@ static int create_files(struct super_block *sb, struct dentry *root) | |||
551 | return 0; | 710 | return 0; |
552 | } | 711 | } |
553 | 712 | ||
554 | |||
555 | static struct gator_interface gator_events_mali_t6xx_interface = { | 713 | static struct gator_interface gator_events_mali_t6xx_interface = { |
556 | .create_files = create_files, | 714 | .create_files = create_files, |
557 | .start = start, | 715 | .start = start, |
@@ -563,6 +721,10 @@ int gator_events_mali_t6xx_hw_init(void) | |||
563 | { | 721 | { |
564 | pr_debug("gator: Mali-T6xx: sw_counters init\n"); | 722 | pr_debug("gator: Mali-T6xx: sw_counters init\n"); |
565 | 723 | ||
724 | #if GATOR_TEST | ||
725 | test_all_is_read_scheduled(); | ||
726 | #endif | ||
727 | |||
566 | gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS); | 728 | gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS); |
567 | 729 | ||
568 | return gator_events_install(&gator_events_mali_t6xx_interface); | 730 | return gator_events_install(&gator_events_mali_t6xx_interface); |
diff --git a/driver/gator_events_mali_t6xx_hw_test.c b/driver/gator_events_mali_t6xx_hw_test.c new file mode 100644 index 0000000..2a35e77 --- /dev/null +++ b/driver/gator_events_mali_t6xx_hw_test.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /** | ||
2 | * Copyright (C) ARM Limited 2012. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /** | ||
11 | * Test functions for mali_t600_hw code. | ||
12 | */ | ||
13 | |||
14 | static int is_read_scheduled(const struct timespec *current_time, u32* prev_time_s, s32* next_read_time_ns); | ||
15 | |||
16 | static int test_is_read_scheduled(u32 s, u32 ns, u32 prev_s, s32 next_ns, int expected_result, s32 expected_next_ns) | ||
17 | { | ||
18 | struct timespec current_time; | ||
19 | u32 prev_time_s = prev_s; | ||
20 | s32 next_read_time_ns = next_ns; | ||
21 | |||
22 | current_time.tv_sec = s; | ||
23 | current_time.tv_nsec = ns; | ||
24 | |||
25 | if(is_read_scheduled(¤t_time, &prev_time_s, &next_read_time_ns) != expected_result) | ||
26 | { | ||
27 | printk("Failed do_read(%u, %u, %u, %d): expected %d\n", s, ns, prev_s, next_ns, expected_result); | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | if(next_read_time_ns != expected_next_ns) | ||
32 | { | ||
33 | printk("Failed: next_read_ns expected=%d, actual=%d\n", expected_next_ns, next_read_time_ns); | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | return 1; | ||
38 | } | ||
39 | |||
40 | static void test_all_is_read_scheduled(void) | ||
41 | { | ||
42 | const int HIGHEST_NS = 999999999; | ||
43 | int n_tests_passed = 0; | ||
44 | |||
45 | printk("gator: running tests on %s\n", __FILE__); | ||
46 | |||
47 | n_tests_passed += test_is_read_scheduled(0,0,0,0, 1, READ_INTERVAL_NSEC); /* Null time */ | ||
48 | n_tests_passed += test_is_read_scheduled(100,1000,0,0, 1, READ_INTERVAL_NSEC + 1000); /* Initial values */ | ||
49 | |||
50 | n_tests_passed += test_is_read_scheduled(100, HIGHEST_NS, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500); | ||
51 | n_tests_passed += test_is_read_scheduled(101, 0001, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500 - NSEC_PER_SEC); | ||
52 | n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500 - NSEC_PER_SEC, 1, 600 + READ_INTERVAL_NSEC); | ||
53 | |||
54 | n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500, 1, 600 + READ_INTERVAL_NSEC); | ||
55 | |||
56 | printk("gator: %d tests passed\n", n_tests_passed); | ||
57 | } | ||
diff --git a/driver/gator_events_mmaped.c b/driver/gator_events_mmaped.c index f81c402..1be6e66 100644 --- a/driver/gator_events_mmaped.c +++ b/driver/gator_events_mmaped.c | |||
@@ -11,12 +11,8 @@ | |||
11 | * To add them to the events.xml, create an events-mmap.xml with the | 11 | * To add them to the events.xml, create an events-mmap.xml with the |
12 | * following contents and rebuild gatord: | 12 | * following contents and rebuild gatord: |
13 | * | 13 | * |
14 | * <counter_set name="mmaped_cntX"> | 14 | * <counter_set name="mmaped_cnt" count="3"/> |
15 | * <counter name="mmaped_cnt0"/> | 15 | * <category name="mmaped" counter_set="mmaped_cnt" per_cpu="no"> |
16 | * <counter name="mmaped_cnt1"/> | ||
17 | * <counter name="mmaped_cnt2"/> | ||
18 | * </counter_set> | ||
19 | * <category name="mmaped" counter_set="mmaped_cntX" per_cpu="no"> | ||
20 | * <event event="0x0" title="Simulated" name="Sine" display="maximum" average_selection="yes" description="Sort-of-sine"/> | 16 | * <event event="0x0" title="Simulated" name="Sine" display="maximum" average_selection="yes" description="Sort-of-sine"/> |
21 | * <event event="0x1" title="Simulated" name="Triangle" display="maximum" average_selection="yes" description="Triangular wave"/> | 17 | * <event event="0x1" title="Simulated" name="Triangle" display="maximum" average_selection="yes" description="Triangular wave"/> |
22 | * <event event="0x2" title="Simulated" name="PWM" display="maximum" average_selection="yes" description="PWM Signal"/> | 18 | * <event event="0x2" title="Simulated" name="PWM" display="maximum" average_selection="yes" description="PWM Signal"/> |
diff --git a/driver/gator_events_net.c b/driver/gator_events_net.c index 11282b5..31cc3ef 100644 --- a/driver/gator_events_net.c +++ b/driver/gator_events_net.c | |||
@@ -95,7 +95,11 @@ static int gator_events_net_start(void) | |||
95 | get_network_stats(0); | 95 | get_network_stats(0); |
96 | netPrev[NETRX] = rx_total; | 96 | netPrev[NETRX] = rx_total; |
97 | netPrev[NETTX] = tx_total; | 97 | netPrev[NETTX] = tx_total; |
98 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) | ||
98 | setup_timer(&net_wake_up_timer, net_wake_up_handler, 0); | 99 | setup_timer(&net_wake_up_timer, net_wake_up_handler, 0); |
100 | #else | ||
101 | setup_deferrable_timer_on_stack(&net_wake_up_timer, net_wake_up_handler, 0); | ||
102 | #endif | ||
99 | return 0; | 103 | return 0; |
100 | } | 104 | } |
101 | 105 | ||
diff --git a/driver/gator_events_perf_pmu.c b/driver/gator_events_perf_pmu.c index 9d78b46..e025155 100644 --- a/driver/gator_events_perf_pmu.c +++ b/driver/gator_events_perf_pmu.c | |||
@@ -32,7 +32,6 @@ static DEFINE_PER_CPU(int[CNTMAX], perfPrevDelta); | |||
32 | static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt); | 32 | static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt); |
33 | static DEFINE_PER_CPU(struct perf_event *[CNTMAX], pevent); | 33 | static DEFINE_PER_CPU(struct perf_event *[CNTMAX], pevent); |
34 | static DEFINE_PER_CPU(struct perf_event_attr *[CNTMAX], pevent_attr); | 34 | static DEFINE_PER_CPU(struct perf_event_attr *[CNTMAX], pevent_attr); |
35 | extern DEFINE_PER_CPU(struct perf_event *, pevent_ebs); | ||
36 | 35 | ||
37 | static void gator_events_perf_pmu_stop(void); | 36 | static void gator_events_perf_pmu_stop(void); |
38 | 37 | ||
@@ -64,6 +63,15 @@ static int gator_events_perf_pmu_create_files(struct super_block *sb, struct den | |||
64 | } | 63 | } |
65 | 64 | ||
66 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) | 65 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) |
66 | static void ebs_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs) | ||
67 | #else | ||
68 | static void ebs_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) | ||
69 | #endif | ||
70 | { | ||
71 | gator_backtrace_handler(regs); | ||
72 | } | ||
73 | |||
74 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) | ||
67 | static void dummy_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs) | 75 | static void dummy_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs) |
68 | #else | 76 | #else |
69 | static void dummy_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) | 77 | static void dummy_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) |
@@ -75,15 +83,10 @@ static void dummy_handler(struct perf_event *event, struct perf_sample_data *dat | |||
75 | static int gator_events_perf_pmu_online(int** buffer) | 83 | static int gator_events_perf_pmu_online(int** buffer) |
76 | { | 84 | { |
77 | int cnt, len = 0, cpu = smp_processor_id(); | 85 | int cnt, len = 0, cpu = smp_processor_id(); |
78 | struct perf_event * ev; | ||
79 | 86 | ||
80 | // read the counters and toss the invalid data, return zero instead | 87 | // read the counters and toss the invalid data, return zero instead |
81 | for (cnt = 0; cnt < pmnc_counters; cnt++) { | 88 | for (cnt = 0; cnt < pmnc_counters; cnt++) { |
82 | if (pmnc_count[cnt] > 0) { | 89 | struct perf_event * ev = per_cpu(pevent, cpu)[cnt]; |
83 | ev = per_cpu(pevent_ebs, cpu); // special case for EBS | ||
84 | } else { | ||
85 | ev = per_cpu(pevent, cpu)[cnt]; | ||
86 | } | ||
87 | if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) { | 90 | if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) { |
88 | ev->pmu->read(ev); | 91 | ev->pmu->read(ev); |
89 | per_cpu(perfPrev, cpu)[cnt] = per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count); | 92 | per_cpu(perfPrev, cpu)[cnt] = per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count); |
@@ -102,18 +105,22 @@ static int gator_events_perf_pmu_online(int** buffer) | |||
102 | static void gator_events_perf_pmu_online_dispatch(int cpu) | 105 | static void gator_events_perf_pmu_online_dispatch(int cpu) |
103 | { | 106 | { |
104 | int cnt; | 107 | int cnt; |
108 | perf_overflow_handler_t handler; | ||
105 | 109 | ||
106 | for (cnt = 0; cnt < pmnc_counters; cnt++) { | 110 | for (cnt = 0; cnt < pmnc_counters; cnt++) { |
107 | if (per_cpu(pevent, cpu)[cnt] != NULL || per_cpu(pevent_attr, cpu)[cnt] == 0) | 111 | if (per_cpu(pevent, cpu)[cnt] != NULL || per_cpu(pevent_attr, cpu)[cnt] == 0) |
108 | continue; | 112 | continue; |
109 | 113 | ||
110 | if (pmnc_count[cnt] > 0) | 114 | if (pmnc_count[cnt] > 0) { |
111 | continue; // skip the EBS counter | 115 | handler = ebs_overflow_handler; |
116 | } else { | ||
117 | handler = dummy_handler; | ||
118 | } | ||
112 | 119 | ||
113 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) | 120 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) |
114 | per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, dummy_handler); | 121 | per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, handler); |
115 | #else | 122 | #else |
116 | per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, dummy_handler, 0); | 123 | per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, handler, 0); |
117 | #endif | 124 | #endif |
118 | if (IS_ERR(per_cpu(pevent, cpu)[cnt])) { | 125 | if (IS_ERR(per_cpu(pevent, cpu)[cnt])) { |
119 | pr_debug("gator: unable to online a counter on cpu %d\n", cpu); | 126 | pr_debug("gator: unable to online a counter on cpu %d\n", cpu); |
@@ -154,6 +161,18 @@ static int gator_events_perf_pmu_start(void) | |||
154 | { | 161 | { |
155 | int cnt, cpu; | 162 | int cnt, cpu; |
156 | u32 size = sizeof(struct perf_event_attr); | 163 | u32 size = sizeof(struct perf_event_attr); |
164 | int found_ebs = false; | ||
165 | |||
166 | for (cnt = 0; cnt < pmnc_counters; cnt++) { | ||
167 | if (pmnc_count[cnt] > 0) { | ||
168 | if (!found_ebs) { | ||
169 | found_ebs = true; | ||
170 | } else { | ||
171 | // Only one ebs counter is allowed | ||
172 | return -1; | ||
173 | } | ||
174 | } | ||
175 | } | ||
157 | 176 | ||
158 | for_each_present_cpu(cpu) { | 177 | for_each_present_cpu(cpu) { |
159 | for (cnt = 0; cnt < pmnc_counters; cnt++) { | 178 | for (cnt = 0; cnt < pmnc_counters; cnt++) { |
@@ -174,7 +193,7 @@ static int gator_events_perf_pmu_start(void) | |||
174 | per_cpu(pevent_attr, cpu)[cnt]->type = PERF_TYPE_RAW; | 193 | per_cpu(pevent_attr, cpu)[cnt]->type = PERF_TYPE_RAW; |
175 | per_cpu(pevent_attr, cpu)[cnt]->size = size; | 194 | per_cpu(pevent_attr, cpu)[cnt]->size = size; |
176 | per_cpu(pevent_attr, cpu)[cnt]->config = pmnc_event[cnt]; | 195 | per_cpu(pevent_attr, cpu)[cnt]->config = pmnc_event[cnt]; |
177 | per_cpu(pevent_attr, cpu)[cnt]->sample_period = 0; | 196 | per_cpu(pevent_attr, cpu)[cnt]->sample_period = pmnc_count[cnt]; |
178 | per_cpu(pevent_attr, cpu)[cnt]->pinned = 1; | 197 | per_cpu(pevent_attr, cpu)[cnt]->pinned = 1; |
179 | 198 | ||
180 | // handle special case for ccnt | 199 | // handle special case for ccnt |
@@ -212,14 +231,9 @@ static int gator_events_perf_pmu_read(int **buffer) | |||
212 | { | 231 | { |
213 | int cnt, delta, len = 0; | 232 | int cnt, delta, len = 0; |
214 | int cpu = smp_processor_id(); | 233 | int cpu = smp_processor_id(); |
215 | struct perf_event * ev; | ||
216 | 234 | ||
217 | for (cnt = 0; cnt < pmnc_counters; cnt++) { | 235 | for (cnt = 0; cnt < pmnc_counters; cnt++) { |
218 | if (pmnc_count[cnt] > 0) { | 236 | struct perf_event * ev = per_cpu(pevent, cpu)[cnt]; |
219 | ev = per_cpu(pevent_ebs, cpu); // special case for EBS | ||
220 | } else { | ||
221 | ev = per_cpu(pevent, cpu)[cnt]; | ||
222 | } | ||
223 | if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) { | 237 | if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) { |
224 | ev->pmu->read(ev); | 238 | ev->pmu->read(ev); |
225 | per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count); | 239 | per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count); |
@@ -300,6 +314,11 @@ int gator_events_perf_pmu_init(void) | |||
300 | pmnc_name = "Krait"; | 314 | pmnc_name = "Krait"; |
301 | pmnc_counters = 4; | 315 | pmnc_counters = 4; |
302 | break; | 316 | break; |
317 | case AARCH64: | ||
318 | pmnc_name = "ARM_AArch64"; | ||
319 | // Copied from A15, get the correct number | ||
320 | pmnc_counters = 6; | ||
321 | break; | ||
303 | default: | 322 | default: |
304 | return -1; | 323 | return -1; |
305 | } | 324 | } |
diff --git a/driver/gator_main.c b/driver/gator_main.c index f6c1135..a2d8ef0 100644 --- a/driver/gator_main.c +++ b/driver/gator_main.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | ||
10 | static unsigned long gator_protocol_version = 10; | 10 | static unsigned long gator_protocol_version = 11; |
11 | 11 | ||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/cpu.h> | 13 | #include <linux/cpu.h> |
@@ -57,41 +57,65 @@ static unsigned long gator_protocol_version = 10; | |||
57 | /****************************************************************************** | 57 | /****************************************************************************** |
58 | * DEFINES | 58 | * DEFINES |
59 | ******************************************************************************/ | 59 | ******************************************************************************/ |
60 | #define BACKTRACE_BUFFER_SIZE (128*1024) | 60 | #define SUMMARY_BUFFER_SIZE (1*1024) |
61 | #define COUNTER_BUFFER_SIZE (128*1024) | 61 | #define BACKTRACE_BUFFER_SIZE (128*1024) |
62 | #define ANNOTATE_BUFFER_SIZE (64*1024) // annotate counters have the core as part of the data and the core value in the frame header may be discarded | 62 | #define NAME_BUFFER_SIZE (64*1024) |
63 | #define SCHED_TRACE_BUFFER_SIZE (128*1024) | 63 | #define COUNTER_BUFFER_SIZE (64*1024) // counters have the core as part of the data and the core value in the frame header may be discarded |
64 | #define GPU_TRACE_BUFFER_SIZE (64*1024) | 64 | #define BLOCK_COUNTER_BUFFER_SIZE (128*1024) |
65 | #define COUNTER2_BUFFER_SIZE (64*1024) // counters2 counters have the core as part of the data and the core value in the frame header may be discarded | 65 | #define ANNOTATE_BUFFER_SIZE (64*1024) // annotate counters have the core as part of the data and the core value in the frame header may be discarded |
66 | #define WFI_BUFFER_SIZE (32*1024) // wfi counters have the core as part of the data and the core value in the frame header may be discarded | 66 | #define SCHED_TRACE_BUFFER_SIZE (128*1024) |
67 | 67 | #define GPU_TRACE_BUFFER_SIZE (64*1024) // gpu trace counters have the core as part of the data and the core value in the frame header may be discarded | |
68 | #define NO_COOKIE 0UL | 68 | #define IDLE_BUFFER_SIZE (32*1024) // idle counters have the core as part of the data and the core value in the frame header may be discarded |
69 | #define INVALID_COOKIE ~0UL | 69 | |
70 | 70 | #define NO_COOKIE 0U | |
71 | #define FRAME_BACKTRACE 1 | 71 | #define INVALID_COOKIE ~0U |
72 | #define FRAME_COUNTER 2 | 72 | |
73 | #define FRAME_ANNOTATE 3 | 73 | #define FRAME_SUMMARY 1 |
74 | #define FRAME_SCHED_TRACE 4 | 74 | #define FRAME_BACKTRACE 2 |
75 | #define FRAME_GPU_TRACE 5 | 75 | #define FRAME_NAME 3 |
76 | #define FRAME_COUNTER2 6 | 76 | #define FRAME_COUNTER 4 |
77 | #define FRAME_WFI 7 | 77 | #define FRAME_BLOCK_COUNTER 5 |
78 | 78 | #define FRAME_ANNOTATE 6 | |
79 | #define MESSAGE_COOKIE 1 | 79 | #define FRAME_SCHED_TRACE 7 |
80 | #define MESSAGE_START_BACKTRACE 5 | 80 | #define FRAME_GPU_TRACE 8 |
81 | #define MESSAGE_END_BACKTRACE 7 | 81 | #define FRAME_IDLE 9 |
82 | #define MESSAGE_SUMMARY 9 | 82 | |
83 | #define MESSAGE_PID_NAME 11 | 83 | #define MESSAGE_END_BACKTRACE 1 |
84 | 84 | ||
85 | #define MAXSIZE_PACK32 5 | 85 | #define MESSAGE_COOKIE 1 |
86 | #define MAXSIZE_PACK64 9 | 86 | #define MESSAGE_THREAD_NAME 2 |
87 | #define HRTIMER_CORE_NAME 3 | ||
88 | |||
89 | #define MESSAGE_GPU_START 1 | ||
90 | #define MESSAGE_GPU_STOP 2 | ||
91 | |||
92 | #define MESSAGE_SCHED_SWITCH 1 | ||
93 | #define MESSAGE_SCHED_EXIT 2 | ||
94 | |||
95 | #define MAXSIZE_PACK32 5 | ||
96 | #define MAXSIZE_PACK64 10 | ||
97 | #define MAXSIZE_CORE_NAME 32 | ||
87 | 98 | ||
88 | #if defined(__arm__) | 99 | #if defined(__arm__) |
89 | #define PC_REG regs->ARM_pc | 100 | #define PC_REG regs->ARM_pc |
101 | #elif defined(__aarch64__) | ||
102 | #define PC_REG regs->pc | ||
90 | #else | 103 | #else |
91 | #define PC_REG regs->ip | 104 | #define PC_REG regs->ip |
92 | #endif | 105 | #endif |
93 | 106 | ||
94 | enum {BACKTRACE_BUF, COUNTER_BUF, SCHED_TRACE_BUF, GPU_TRACE_BUF, ANNOTATE_BUF, COUNTER2_BUF, WFI_BUF, NUM_GATOR_BUFS}; | 107 | enum { |
108 | SUMMARY_BUF, | ||
109 | BACKTRACE_BUF, | ||
110 | NAME_BUF, | ||
111 | COUNTER_BUF, | ||
112 | BLOCK_COUNTER_BUF, | ||
113 | ANNOTATE_BUF, | ||
114 | SCHED_TRACE_BUF, | ||
115 | GPU_TRACE_BUF, | ||
116 | IDLE_BUF, | ||
117 | NUM_GATOR_BUFS | ||
118 | }; | ||
95 | 119 | ||
96 | /****************************************************************************** | 120 | /****************************************************************************** |
97 | * Globals | 121 | * Globals |
@@ -101,17 +125,13 @@ static unsigned long userspace_buffer_size; | |||
101 | static unsigned long gator_backtrace_depth; | 125 | static unsigned long gator_backtrace_depth; |
102 | 126 | ||
103 | static unsigned long gator_started; | 127 | static unsigned long gator_started; |
128 | static uint64_t monotonic_started; | ||
104 | static unsigned long gator_buffer_opened; | 129 | static unsigned long gator_buffer_opened; |
105 | static unsigned long gator_timer_count; | 130 | static unsigned long gator_timer_count; |
106 | static unsigned long gator_response_type; | 131 | static unsigned long gator_response_type; |
107 | static DEFINE_MUTEX(start_mutex); | 132 | static DEFINE_MUTEX(start_mutex); |
108 | static DEFINE_MUTEX(gator_buffer_mutex); | 133 | static DEFINE_MUTEX(gator_buffer_mutex); |
109 | 134 | ||
110 | bool event_based_sampling; | ||
111 | #if defined(__arm__) && (GATOR_PERF_PMU_SUPPORT) | ||
112 | DEFINE_PER_CPU(struct perf_event *, pevent_ebs); | ||
113 | #endif | ||
114 | |||
115 | static DECLARE_WAIT_QUEUE_HEAD(gator_buffer_wait); | 135 | static DECLARE_WAIT_QUEUE_HEAD(gator_buffer_wait); |
116 | static struct timer_list gator_buffer_wake_up_timer; | 136 | static struct timer_list gator_buffer_wake_up_timer; |
117 | static LIST_HEAD(gator_events); | 137 | static LIST_HEAD(gator_events); |
@@ -125,10 +145,10 @@ static bool buffer_check_space(int cpu, int buftype, int bytes); | |||
125 | static int contiguous_space_available(int cpu, int bufytpe); | 145 | static int contiguous_space_available(int cpu, int bufytpe); |
126 | static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x); | 146 | static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x); |
127 | static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long long x); | 147 | static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long long x); |
128 | static void gator_buffer_write_bytes(int cpu, int buftype, char *x, int len); | 148 | static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len); |
129 | static void gator_buffer_write_string(int cpu, int buftype, char *x); | 149 | static void gator_buffer_write_string(int cpu, int buftype, const char *x); |
130 | static void gator_add_trace(int cpu, int buftype, unsigned int address); | 150 | static void gator_add_trace(int cpu, unsigned long address); |
131 | static void gator_add_sample(int cpu, int buftype, struct pt_regs * const regs); | 151 | static void gator_add_sample(int cpu, struct pt_regs * const regs); |
132 | static uint64_t gator_get_time(void); | 152 | static uint64_t gator_get_time(void); |
133 | 153 | ||
134 | static uint32_t gator_buffer_size[NUM_GATOR_BUFS]; | 154 | static uint32_t gator_buffer_size[NUM_GATOR_BUFS]; |
@@ -152,17 +172,20 @@ static DEFINE_PER_CPU(char *[NUM_GATOR_BUFS], gator_buffer); | |||
152 | #include "gator_backtrace.c" | 172 | #include "gator_backtrace.c" |
153 | #include "gator_annotate.c" | 173 | #include "gator_annotate.c" |
154 | #include "gator_fs.c" | 174 | #include "gator_fs.c" |
155 | #include "gator_ebs.c" | ||
156 | #include "gator_pack.c" | 175 | #include "gator_pack.c" |
157 | 176 | ||
158 | /****************************************************************************** | 177 | /****************************************************************************** |
159 | * Misc | 178 | * Misc |
160 | ******************************************************************************/ | 179 | ******************************************************************************/ |
161 | #if defined(__arm__) | 180 | #if defined(__arm__) || defined(__aarch64__) |
162 | u32 gator_cpuid(void) | 181 | u32 gator_cpuid(void) |
163 | { | 182 | { |
164 | u32 val; | 183 | u32 val; |
184 | #if !defined(__aarch64__) | ||
165 | asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (val)); | 185 | asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (val)); |
186 | #else | ||
187 | asm volatile("mrs %0, midr_el1" : "=r" (val)); | ||
188 | #endif | ||
166 | return (val >> 4) & 0xfff; | 189 | return (val >> 4) & 0xfff; |
167 | } | 190 | } |
168 | #endif | 191 | #endif |
@@ -237,7 +260,7 @@ static bool buffer_check_space(int cpu, int buftype, int bytes) | |||
237 | return per_cpu(buffer_space_available, cpu)[buftype]; | 260 | return per_cpu(buffer_space_available, cpu)[buftype]; |
238 | } | 261 | } |
239 | 262 | ||
240 | static void gator_buffer_write_bytes(int cpu, int buftype, char *x, int len) | 263 | static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len) |
241 | { | 264 | { |
242 | int i; | 265 | int i; |
243 | u32 write = per_cpu(gator_buffer_write, cpu)[buftype]; | 266 | u32 write = per_cpu(gator_buffer_write, cpu)[buftype]; |
@@ -252,7 +275,7 @@ static void gator_buffer_write_bytes(int cpu, int buftype, char *x, int len) | |||
252 | per_cpu(gator_buffer_write, cpu)[buftype] = write; | 275 | per_cpu(gator_buffer_write, cpu)[buftype] = write; |
253 | } | 276 | } |
254 | 277 | ||
255 | static void gator_buffer_write_string(int cpu, int buftype, char *x) | 278 | static void gator_buffer_write_string(int cpu, int buftype, const char *x) |
256 | { | 279 | { |
257 | int len = strlen(x); | 280 | int len = strlen(x); |
258 | gator_buffer_write_packed_int(cpu, buftype, len); | 281 | gator_buffer_write_packed_int(cpu, buftype, len); |
@@ -263,22 +286,38 @@ static void gator_buffer_header(int cpu, int buftype) | |||
263 | { | 286 | { |
264 | int frame; | 287 | int frame; |
265 | 288 | ||
266 | if (buftype == BACKTRACE_BUF) | 289 | switch (buftype) { |
290 | case SUMMARY_BUF: | ||
291 | frame = FRAME_SUMMARY; | ||
292 | break; | ||
293 | case BACKTRACE_BUF: | ||
267 | frame = FRAME_BACKTRACE; | 294 | frame = FRAME_BACKTRACE; |
268 | else if (buftype == COUNTER_BUF) | 295 | break; |
296 | case NAME_BUF: | ||
297 | frame = FRAME_NAME; | ||
298 | break; | ||
299 | case COUNTER_BUF: | ||
269 | frame = FRAME_COUNTER; | 300 | frame = FRAME_COUNTER; |
270 | else if (buftype == ANNOTATE_BUF) | 301 | break; |
302 | case BLOCK_COUNTER_BUF: | ||
303 | frame = FRAME_BLOCK_COUNTER; | ||
304 | break; | ||
305 | case ANNOTATE_BUF: | ||
271 | frame = FRAME_ANNOTATE; | 306 | frame = FRAME_ANNOTATE; |
272 | else if (buftype == SCHED_TRACE_BUF) | 307 | break; |
308 | case SCHED_TRACE_BUF: | ||
273 | frame = FRAME_SCHED_TRACE; | 309 | frame = FRAME_SCHED_TRACE; |
274 | else if (buftype == GPU_TRACE_BUF) | 310 | break; |
311 | case GPU_TRACE_BUF: | ||
275 | frame = FRAME_GPU_TRACE; | 312 | frame = FRAME_GPU_TRACE; |
276 | else if (buftype == COUNTER2_BUF) | 313 | break; |
277 | frame = FRAME_COUNTER2; | 314 | case IDLE_BUF: |
278 | else if (buftype == WFI_BUF) | 315 | frame = FRAME_IDLE; |
279 | frame = FRAME_WFI; | 316 | break; |
280 | else | 317 | default: |
281 | frame = -1; | 318 | frame = -1; |
319 | break; | ||
320 | } | ||
282 | 321 | ||
283 | if (per_cpu(gator_buffer, cpu)[buftype]) { | 322 | if (per_cpu(gator_buffer, cpu)[buftype]) { |
284 | marshal_frame(cpu, buftype, frame); | 323 | marshal_frame(cpu, buftype, frame); |
@@ -308,10 +347,10 @@ static void buffer_check(int cpu, int buftype) | |||
308 | } | 347 | } |
309 | } | 348 | } |
310 | 349 | ||
311 | static void gator_add_trace(int cpu, int buftype, unsigned int address) | 350 | static void gator_add_trace(int cpu, unsigned long address) |
312 | { | 351 | { |
313 | off_t offset = 0; | 352 | off_t offset = 0; |
314 | unsigned long cookie = get_address_cookie(cpu, buftype, current, address & ~1, &offset); | 353 | unsigned long cookie = get_address_cookie(cpu, current, address & ~1, &offset); |
315 | 354 | ||
316 | if (cookie == NO_COOKIE || cookie == INVALID_COOKIE) { | 355 | if (cookie == NO_COOKIE || cookie == INVALID_COOKIE) { |
317 | offset = address; | 356 | offset = address; |
@@ -320,26 +359,29 @@ static void gator_add_trace(int cpu, int buftype, unsigned int address) | |||
320 | marshal_backtrace(offset & ~1, cookie); | 359 | marshal_backtrace(offset & ~1, cookie); |
321 | } | 360 | } |
322 | 361 | ||
323 | static void gator_add_sample(int cpu, int buftype, struct pt_regs * const regs) | 362 | static void gator_add_sample(int cpu, struct pt_regs * const regs) |
324 | { | 363 | { |
325 | int inKernel = regs ? !user_mode(regs) : 1; | 364 | bool inKernel; |
326 | unsigned long exec_cookie = inKernel ? NO_COOKIE : get_exec_cookie(cpu, buftype, current); | 365 | unsigned long exec_cookie; |
327 | 366 | ||
328 | if (!regs) | 367 | if (!regs) |
329 | return; | 368 | return; |
330 | 369 | ||
370 | inKernel = !user_mode(regs); | ||
371 | exec_cookie = get_exec_cookie(cpu, current); | ||
372 | |||
331 | if (!marshal_backtrace_header(exec_cookie, current->tgid, current->pid, inKernel)) | 373 | if (!marshal_backtrace_header(exec_cookie, current->tgid, current->pid, inKernel)) |
332 | return; | 374 | return; |
333 | 375 | ||
334 | if (inKernel) { | 376 | if (inKernel) { |
335 | kernel_backtrace(cpu, buftype, regs); | 377 | kernel_backtrace(cpu, regs); |
336 | } else { | 378 | } else { |
337 | // Cookie+PC | 379 | // Cookie+PC |
338 | gator_add_trace(cpu, buftype, PC_REG); | 380 | gator_add_trace(cpu, PC_REG); |
339 | 381 | ||
340 | // Backtrace | 382 | // Backtrace |
341 | if (gator_backtrace_depth) | 383 | if (gator_backtrace_depth) |
342 | arm_backtrace_eabi(cpu, buftype, regs, gator_backtrace_depth); | 384 | arm_backtrace_eabi(cpu, regs, gator_backtrace_depth); |
343 | } | 385 | } |
344 | 386 | ||
345 | marshal_backtrace_footer(); | 387 | marshal_backtrace_footer(); |
@@ -351,13 +393,20 @@ static void gator_add_sample(int cpu, int buftype, struct pt_regs * const regs) | |||
351 | static void gator_timer_interrupt(void) | 393 | static void gator_timer_interrupt(void) |
352 | { | 394 | { |
353 | struct pt_regs * const regs = get_irq_regs(); | 395 | struct pt_regs * const regs = get_irq_regs(); |
396 | gator_backtrace_handler(regs); | ||
397 | } | ||
398 | |||
399 | void gator_backtrace_handler(struct pt_regs * const regs) | ||
400 | { | ||
354 | int cpu = smp_processor_id(); | 401 | int cpu = smp_processor_id(); |
355 | 402 | ||
356 | // Output backtrace | 403 | // Output backtrace |
357 | gator_add_sample(cpu, BACKTRACE_BUF, regs); | 404 | gator_add_sample(cpu, regs); |
358 | 405 | ||
359 | // Collect counters | 406 | // Collect counters |
360 | collect_counters(); | 407 | if (!per_cpu(collecting, cpu)) { |
408 | collect_counters(); | ||
409 | } | ||
361 | } | 410 | } |
362 | 411 | ||
363 | static int gator_running; | 412 | static int gator_running; |
@@ -397,8 +446,6 @@ static void gator_timer_offline_dispatch(int cpu) | |||
397 | list_for_each_entry(gi, &gator_events, list) | 446 | list_for_each_entry(gi, &gator_events, list) |
398 | if (gi->offline_dispatch) | 447 | if (gi->offline_dispatch) |
399 | gi->offline_dispatch(cpu); | 448 | gi->offline_dispatch(cpu); |
400 | |||
401 | gator_event_sampling_offline_dispatch(cpu); | ||
402 | } | 449 | } |
403 | 450 | ||
404 | static void gator_timer_stop(void) | 451 | static void gator_timer_stop(void) |
@@ -436,6 +483,32 @@ static void gator_timer_online(void* unused) | |||
436 | } | 483 | } |
437 | 484 | ||
438 | gator_hrtimer_online(cpu); | 485 | gator_hrtimer_online(cpu); |
486 | #if defined(__arm__) || defined(__aarch64__) | ||
487 | { | ||
488 | const char * core_name = NULL; | ||
489 | |||
490 | // String lengths must be less than MAXSIZE_CORE_NAME | ||
491 | switch (gator_cpuid()) { | ||
492 | case ARM1136: core_name = "ARM1136"; break; | ||
493 | case ARM1156: core_name = "ARM1156"; break; | ||
494 | case ARM1176: core_name = "ARM1176"; break; | ||
495 | case ARM11MPCORE: core_name = "ARM11MPCore"; break; | ||
496 | case CORTEX_A5: core_name = "Cortex-A5"; break; | ||
497 | case CORTEX_A7: core_name = "Cortex-A7"; break; | ||
498 | case CORTEX_A8: core_name = "Cortex-A8"; break; | ||
499 | case CORTEX_A9: core_name = "Cortex-A9"; break; | ||
500 | case CORTEX_A15: core_name = "Cortex-A15"; break; | ||
501 | case SCORPION: core_name = "Scorpion"; break; | ||
502 | case SCORPIONMP: core_name = "ScorpionMP"; break; | ||
503 | case KRAITSIM: core_name = "KraitSIM"; break; | ||
504 | case KRAIT: core_name = "Krait"; break; | ||
505 | case AARCH64: core_name = "AArch64"; break; | ||
506 | default: core_name = "Unknown"; break; | ||
507 | } | ||
508 | |||
509 | marshal_core_name(core_name); | ||
510 | } | ||
511 | #endif | ||
439 | } | 512 | } |
440 | 513 | ||
441 | // This function runs in interrupt context and may be running on a core other than core 'cpu' | 514 | // This function runs in interrupt context and may be running on a core other than core 'cpu' |
@@ -446,8 +519,6 @@ static void gator_timer_online_dispatch(int cpu) | |||
446 | list_for_each_entry(gi, &gator_events, list) | 519 | list_for_each_entry(gi, &gator_events, list) |
447 | if (gi->online_dispatch) | 520 | if (gi->online_dispatch) |
448 | gi->online_dispatch(cpu); | 521 | gi->online_dispatch(cpu); |
449 | |||
450 | gator_event_sampling_online_dispatch(cpu); | ||
451 | } | 522 | } |
452 | 523 | ||
453 | int gator_timer_start(unsigned long sample_rate) | 524 | int gator_timer_start(unsigned long sample_rate) |
@@ -461,10 +532,6 @@ int gator_timer_start(unsigned long sample_rate) | |||
461 | 532 | ||
462 | gator_running = 1; | 533 | gator_running = 1; |
463 | 534 | ||
464 | // event based sampling trumps hr timer based sampling | ||
465 | if (event_based_sampling) | ||
466 | sample_rate = 0; | ||
467 | |||
468 | if (gator_hrtimer_init(sample_rate, gator_timer_interrupt) == -1) | 535 | if (gator_hrtimer_init(sample_rate, gator_timer_interrupt) == -1) |
469 | return -1; | 536 | return -1; |
470 | 537 | ||
@@ -481,8 +548,9 @@ static uint64_t gator_get_time(void) | |||
481 | struct timespec ts; | 548 | struct timespec ts; |
482 | uint64_t timestamp; | 549 | uint64_t timestamp; |
483 | 550 | ||
484 | getnstimeofday(&ts); | 551 | //getnstimeofday(&ts); |
485 | timestamp = timespec_to_ns(&ts); | 552 | do_posix_clock_monotonic_gettime(&ts); |
553 | timestamp = timespec_to_ns(&ts) - monotonic_started; | ||
486 | 554 | ||
487 | return timestamp; | 555 | return timestamp; |
488 | } | 556 | } |
@@ -568,20 +636,15 @@ static void gator_notifier_stop(void) | |||
568 | ******************************************************************************/ | 636 | ******************************************************************************/ |
569 | static void gator_summary(void) | 637 | static void gator_summary(void) |
570 | { | 638 | { |
571 | uint64_t timestamp, uptime = 0; | 639 | uint64_t timestamp; |
572 | struct timespec uptime_ts; | 640 | struct timespec uptime_ts; |
573 | void (*m2b)(struct timespec *ts); | ||
574 | 641 | ||
575 | timestamp = gator_get_time(); | 642 | timestamp = gator_get_time(); |
576 | 643 | ||
577 | do_posix_clock_monotonic_gettime(&uptime_ts); | 644 | do_posix_clock_monotonic_gettime(&uptime_ts); |
578 | m2b = symbol_get(monotonic_to_bootbased); | 645 | monotonic_started = timespec_to_ns(&uptime_ts); |
579 | if (m2b) { | ||
580 | m2b(&uptime_ts); | ||
581 | uptime = (long long)uptime_ts.tv_sec * 1000000000 + uptime_ts.tv_nsec; | ||
582 | } | ||
583 | 646 | ||
584 | marshal_summary(timestamp, uptime); | 647 | marshal_summary(timestamp, monotonic_started); |
585 | } | 648 | } |
586 | 649 | ||
587 | int gator_events_install(struct gator_interface *interface) | 650 | int gator_events_install(struct gator_interface *interface) |
@@ -656,8 +719,6 @@ static int gator_start(void) | |||
656 | goto power_failure; | 719 | goto power_failure; |
657 | if (gator_trace_gpu_start()) | 720 | if (gator_trace_gpu_start()) |
658 | goto gpu_failure; | 721 | goto gpu_failure; |
659 | if (gator_event_sampling_start()) | ||
660 | goto event_sampling_failure; | ||
661 | if (gator_timer_start(gator_timer_count)) | 722 | if (gator_timer_start(gator_timer_count)) |
662 | goto timer_failure; | 723 | goto timer_failure; |
663 | if (gator_notifier_start()) | 724 | if (gator_notifier_start()) |
@@ -668,8 +729,6 @@ static int gator_start(void) | |||
668 | notifier_failure: | 729 | notifier_failure: |
669 | gator_timer_stop(); | 730 | gator_timer_stop(); |
670 | timer_failure: | 731 | timer_failure: |
671 | gator_event_sampling_stop(); | ||
672 | event_sampling_failure: | ||
673 | gator_trace_gpu_stop(); | 732 | gator_trace_gpu_stop(); |