aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/oprofile/oprofile/0001-Allow-ppc64-events-to-be-specified-with-or-without-_.patch
blob: d19948a4f89fc3da7d6cf4a71b3c075905638f58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
Upstream-Status: Accepted

From 36028035555297695f52e856f21920012fd64f79 Mon Sep 17 00:00:00 2001
From: Maynard Johnson <maynardj@us.ibm.com>
Date: Fri, 11 Jan 2013 13:29:57 -0600
Subject: [PATCH] Allow ppc64 events to be specified with or without _GRP<n>
 suffix

All events for IBM PowerPC server processors (except CYCLES) have
a _GRP<n> suffix.  This is because the legacy opcontrol profiler
can only profile events in the same group (i.e., having the same
_GRP<n> suffix).  But operf has no such restriction because it
can multiplex events; thus, so we should allow the user to pass
event names without the _GRP<n> suffix.

Signed-off-by: Maynard Johnson <maynardj@us.ibm.com>
---
 doc/operf.1.in         |    6 +++
 doc/oprofile.xml       |   12 +++++-
 pe_profiling/operf.cpp |  107 ++++++++++++++++++++++++++++++++++++++++++++++++
 utils/ophelp.c         |    4 ++
 4 files changed, 127 insertions(+), 2 deletions(-)

diff --git a/doc/operf.1.in b/doc/operf.1.in
index b109324..03027ca 100644
--- a/doc/operf.1.in
+++ b/doc/operf.1.in
@@ -110,6 +110,12 @@ be specified using the symbolic name.  If no unit mask is specified, 0x0 will be
 used as the default.
 .P
 .RS
+On IBM PowerPC systems, events may be specified with or without the
+.I _GRP<n>
+suffix.  If no group number suffix is given, one will be automatically
+assigned; thus, OProfile post-processing tools will always show real event
+names that include the group number suffix.
+.P
 When no event specification is given, the default event for the running
 processor type will be used for profiling.
 Use
diff --git a/doc/oprofile.xml b/doc/oprofile.xml
index 0ae2b0b..0f74726 100644
--- a/doc/oprofile.xml
+++ b/doc/oprofile.xml
@@ -1106,10 +1106,18 @@ shown by the output of <command>ophelp</command>.  Unit masks with "extra:" para
 specified using the symbolic name.
 </para>
 <note><para>
-When using legacy mode <command>opcontrol</command> on PowerPC platforms, all events specified must be in the same group;
+When using legacy mode <command>opcontrol</command> on IBM PowerPC platforms, all events specified must be in the same group;
 i.e., the group number appended to the event name (e.g. <constant>&lt;<emphasis>some-event-name</emphasis>&gt;_GRP9
 </constant>) must be the same.
-</para></note>
+</para>
+<para>
+When profiling with <command>operf</command> on IBM PowerPC platforms, the above restriction
+regarding the same group number does not apply, and events may be
+specified with or without the group number suffix.   If no group number suffix is given, one will be automatically
+assigned; thus, OProfile post-processing tools will always show real event
+names that include the group number suffix.
+</para>
+</note>
 <para>
 If OProfile is using timer-interrupt mode, there is no event configuration possible.
 </para>
diff --git a/pe_profiling/operf.cpp b/pe_profiling/operf.cpp
index 4416b29..a776e71 100644
--- a/pe_profiling/operf.cpp
+++ b/pe_profiling/operf.cpp
@@ -1146,6 +1146,108 @@ static void _get_event_code(operf_event_t * event)
 	event->evt_code = config;
 }
 
+#if (defined(__powerpc__) || defined(__powerpc64__))
+/* All ppc64 events (except CYCLES) have a _GRP<n> suffix.  This is
+ * because the legacy opcontrol profiler can only profile events in
+ * the same group (i.e., having the same _GRP<n> suffix).  But operf
+ * can multiplex events, so we should allow the user to pass event
+ * names without the _GRP<n> suffix.
+ *
+ * If event name is not CYCLES or does not have a _GRP<n> suffix,
+ * we'll call ophelp and scan the list of events, searching for one
+ * that matches up to the _GRP<n> suffix.  If we don't find a match,
+ * then we'll exit with the expected error message for invalid event name.
+ */
+static string _handle_powerpc_event_spec(string event_spec)
+{
+	FILE * fp;
+	char line[MAX_INPUT];
+	size_t grp_pos;
+	string evt, retval, err_msg;
+	size_t evt_name_len;
+	bool first_non_cyc_evt_found = false;
+	bool event_found = false;
+	char event_name[OP_MAX_EVT_NAME_LEN], event_spec_str[OP_MAX_EVT_NAME_LEN + 20], * count_str;
+	string cmd = OP_BINDIR;
+	cmd += "/ophelp";
+
+	strncpy(event_spec_str, event_spec.c_str(), event_spec.length() + 1);
+
+	strncpy(event_name, strtok(event_spec_str, ":"), OP_MAX_EVT_NAME_LEN);
+	count_str = strtok(NULL, ":");
+	if (!count_str) {
+		err_msg = "Invalid count for event ";
+		goto out;
+	}
+
+	if (!strcmp("CYCLES", event_name)) {
+		event_found = true;
+		goto out;
+	}
+
+	evt = event_name;
+	// Need to make sure the event name truly has a _GRP<n> suffix.
+	grp_pos = evt.rfind("_GRP");
+	if ((grp_pos != string::npos) && ((evt = evt.substr(grp_pos, string::npos))).length() > 4) {
+		unsigned long value;
+		char * end;
+		value = strtoul(evt.substr(4, string::npos).c_str(), &end, 0);
+		if (end && (*end == '\0')) {
+		// Valid group number found after _GRP, so we can skip to the end.
+			event_found = true;
+			goto out;
+		}
+	}
+
+	// If we get here, it implies the user passed a non-CYCLES event without a GRP suffix.
+	// Lets try to find a valid suffix for it.
+	fp = popen(cmd.c_str(), "r");
+	if (fp == NULL) {
+		cerr << "Unable to execute ophelp to get info for event "
+		     << event_spec << endl;
+		exit(EXIT_FAILURE);
+	}
+	evt_name_len = strlen(event_name);
+	err_msg = "Cannot find event ";
+	while (fgets(line, MAX_INPUT, fp)) {
+		if (!first_non_cyc_evt_found) {
+			if (!strncmp(line, "PM_", 3))
+				first_non_cyc_evt_found = true;
+			else
+				continue;
+		}
+		if (line[0] == ' ' || line[0] == '\t')
+			continue;
+		if (!strncmp(line, event_name, evt_name_len)) {
+			// Found a potential match.  Check if it's a perfect match.
+			string save_event_name = event_name;
+			size_t full_evt_len = index(line, ':') - line;
+			memset(event_name, '\0', OP_MAX_EVT_NAME_LEN);
+			strncpy(event_name, line, full_evt_len);
+			string candidate = event_name;
+			if (candidate.rfind("_GRP") == evt_name_len) {
+				event_found = true;
+				break;
+			} else {
+				memset(event_name, '\0', OP_MAX_EVT_NAME_LEN);
+				strncpy(event_name, save_event_name.c_str(), evt_name_len);
+			}
+		}
+	}
+	pclose(fp);
+
+out:
+	if (!event_found) {
+		cerr << err_msg << event_name << endl;
+		cerr << "Error retrieving info for event "
+				<< event_spec << endl;
+		exit(EXIT_FAILURE);
+	}
+	retval = event_name;
+	return retval + ":" + count_str;
+}
+#endif
+
 static void _process_events_list(void)
 {
 	string cmd = OP_BINDIR;
@@ -1154,6 +1256,11 @@ static void _process_events_list(void)
 		FILE * fp;
 		string full_cmd = cmd;
 		string event_spec = operf_options::evts[i];
+
+#if (defined(__powerpc__) || defined(__powerpc64__))
+		event_spec = _handle_powerpc_event_spec(event_spec);
+#endif
+
 		if (operf_options::callgraph) {
 			full_cmd += " --callgraph=1 ";
 		}
diff --git a/utils/ophelp.c b/utils/ophelp.c
index 53a5dde..63895c8 100644
--- a/utils/ophelp.c
+++ b/utils/ophelp.c
@@ -652,6 +652,10 @@ int main(int argc, char const * argv[])
 	case CPU_PPC64_POWER7:
 	case CPU_PPC64_IBM_COMPAT_V1:
 		event_doc =
+			"When using operf, events may be specified without a '_GRP<n>' suffix.\n"
+			"If _GRP<n> (i.e., group number) is not specified, one will be automatically\n"
+			"selected for use by the profiler.  OProfile post-processing tools will\n"
+			"always show real event names that include the group number suffix.\n\n"
 			"Documentation for IBM POWER7 can be obtained at:\n"
 			"http://www.power.org/events/Power7/\n"
 			"No public performance monitoring doc available for older processors.\n";
-- 
1.7.9.7