gator: Version 5.19
[firefly-linux-kernel-4.4.55.git] / tools / gator / daemon / KMod.cpp
1 /**
2  * Copyright (C) ARM Limited 2013-2014. 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 #include "KMod.h"
10
11 #include <sys/types.h>
12 #include <dirent.h>
13 #include <unistd.h>
14
15 #include "ConfigurationXML.h"
16 #include "Counter.h"
17 #include "DriverSource.h"
18 #include "Logging.h"
19
20 // Claim all the counters in /dev/gator/events
21 bool KMod::claimCounter(const Counter &counter) const {
22         char text[128];
23         snprintf(text, sizeof(text), "/dev/gator/events/%s", counter.getType());
24         return access(text, F_OK) == 0;
25 }
26
27 void KMod::resetCounters() {
28         char base[128];
29         char text[128];
30
31         // Initialize all perf counters in the driver, i.e. set enabled to zero
32         struct dirent *ent;
33         DIR* dir = opendir("/dev/gator/events");
34         if (dir) {
35                 while ((ent = readdir(dir)) != NULL) {
36                         // skip hidden files, current dir, and parent dir
37                         if (ent->d_name[0] == '.')
38                                 continue;
39                         snprintf(base, sizeof(base), "/dev/gator/events/%s", ent->d_name);
40                         snprintf(text, sizeof(text), "%s/enabled", base);
41                         DriverSource::writeDriver(text, 0);
42                         snprintf(text, sizeof(text), "%s/count", base);
43                         DriverSource::writeDriver(text, 0);
44                 }
45                 closedir(dir);
46         }
47 }
48
49 void KMod::setupCounter(Counter &counter) {
50         char base[128];
51         char text[128];
52         snprintf(base, sizeof(base), "/dev/gator/events/%s", counter.getType());
53
54         snprintf(text, sizeof(text), "%s/enabled", base);
55         int enabled = true;
56         if (DriverSource::writeReadDriver(text, &enabled) || !enabled) {
57                 counter.setEnabled(false);
58                 return;
59         }
60
61         int value = 0;
62         snprintf(text, sizeof(text), "%s/key", base);
63         DriverSource::readIntDriver(text, &value);
64         counter.setKey(value);
65
66         snprintf(text, sizeof(text), "%s/cores", base);
67         if (DriverSource::readIntDriver(text, &value) == 0) {
68                 counter.setCores(value);
69         }
70
71         snprintf(text, sizeof(text), "%s/event", base);
72         DriverSource::writeDriver(text, counter.getEvent());
73         snprintf(text, sizeof(text), "%s/count", base);
74         if (access(text, F_OK) == 0) {
75                 int count = counter.getCount();
76                 if (DriverSource::writeReadDriver(text, &count) && counter.getCount() > 0) {
77                         logg->logError(__FILE__, __LINE__, "Cannot enable EBS for %s:%i with a count of %d\n", counter.getType(), counter.getEvent(), counter.getCount());
78                         handleException();
79                 }
80                 counter.setCount(count);
81         } else if (counter.getCount() > 0) {
82                 ConfigurationXML::remove();
83                 logg->logError(__FILE__, __LINE__, "Event Based Sampling is only supported with kernel versions 3.0.0 and higher with CONFIG_PERF_EVENTS=y, and CONFIG_HW_PERF_EVENTS=y. The invalid configuration.xml has been removed.\n");
84                 handleException();
85         }
86 }
87
88 int KMod::writeCounters(mxml_node_t *root) const {
89         struct dirent *ent;
90         mxml_node_t *counter;
91
92         // counters.xml is simply a file listing of /dev/gator/events
93         DIR* dir = opendir("/dev/gator/events");
94         if (dir == NULL) {
95                 return 0;
96         }
97
98         int count = 0;
99         while ((ent = readdir(dir)) != NULL) {
100                 // skip hidden files, current dir, and parent dir
101                 if (ent->d_name[0] == '.')
102                         continue;
103                 counter = mxmlNewElement(root, "counter");
104                 mxmlElementSetAttr(counter, "name", ent->d_name);
105                 ++count;
106         }
107         closedir(dir);
108
109         return count;
110 }