aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter/util/parse-events.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-06-06 03:58:57 -0400
committerIngo Molnar <mingo@elte.hu>2009-06-06 05:37:22 -0400
commita21ca2cac582886a3e95c8bb84ff7c52d4d15e54 (patch)
treed110005d81e46b1afb3204fbaacc132d0ec946ee /Documentation/perf_counter/util/parse-events.c
parent2f335a02b3c816e77e7df1d15b12e3bbb8f4c8f0 (diff)
perf_counter: Separate out attr->type from attr->config
Counter type is a frequently used value and we do a lot of bit juggling by encoding and decoding it from attr->config. Clean this up by creating a separate attr->type field. Also clean up the various similarly complex user-space bits all around counter attribute management. The net improvement is significant, and it will be easier to add a new major type (which is what triggered this cleanup). (This changes the ABI, all tools are adapted.) (PowerPC build-tested.) Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Marcelo Tosatti <mtosatti@redhat.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation/perf_counter/util/parse-events.c')
-rw-r--r--Documentation/perf_counter/util/parse-events.c120
1 files changed, 66 insertions, 54 deletions
diff --git a/Documentation/perf_counter/util/parse-events.c b/Documentation/perf_counter/util/parse-events.c
index 2fdfd1d923f2..eb56bd996573 100644
--- a/Documentation/perf_counter/util/parse-events.c
+++ b/Documentation/perf_counter/util/parse-events.c
@@ -6,37 +6,39 @@
6#include "exec_cmd.h" 6#include "exec_cmd.h"
7#include "string.h" 7#include "string.h"
8 8
9int nr_counters; 9int nr_counters;
10 10
11__u64 event_id[MAX_COUNTERS] = { }; 11struct perf_counter_attr attrs[MAX_COUNTERS];
12int event_mask[MAX_COUNTERS];
13 12
14struct event_symbol { 13struct event_symbol {
15 __u64 event; 14 __u8 type;
16 char *symbol; 15 __u64 config;
16 char *symbol;
17}; 17};
18 18
19#define C(x, y) .type = PERF_TYPE_##x, .config = PERF_COUNT_##y
20
19static struct event_symbol event_symbols[] = { 21static struct event_symbol event_symbols[] = {
20 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cpu-cycles", }, 22 { C(HARDWARE, CPU_CYCLES), "cpu-cycles", },
21 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cycles", }, 23 { C(HARDWARE, CPU_CYCLES), "cycles", },
22 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), "instructions", }, 24 { C(HARDWARE, INSTRUCTIONS), "instructions", },
23 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), "cache-references", }, 25 { C(HARDWARE, CACHE_REFERENCES), "cache-references", },
24 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), "cache-misses", }, 26 { C(HARDWARE, CACHE_MISSES), "cache-misses", },
25 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branch-instructions", }, 27 { C(HARDWARE, BRANCH_INSTRUCTIONS), "branch-instructions", },
26 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branches", }, 28 { C(HARDWARE, BRANCH_INSTRUCTIONS), "branches", },
27 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_MISSES), "branch-misses", }, 29 { C(HARDWARE, BRANCH_MISSES), "branch-misses", },
28 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BUS_CYCLES), "bus-cycles", }, 30 { C(HARDWARE, BUS_CYCLES), "bus-cycles", },
29 31
30 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK), "cpu-clock", }, 32 { C(SOFTWARE, CPU_CLOCK), "cpu-clock", },
31 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), "task-clock", }, 33 { C(SOFTWARE, TASK_CLOCK), "task-clock", },
32 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "page-faults", }, 34 { C(SOFTWARE, PAGE_FAULTS), "page-faults", },
33 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "faults", }, 35 { C(SOFTWARE, PAGE_FAULTS), "faults", },
34 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MIN), "minor-faults", }, 36 { C(SOFTWARE, PAGE_FAULTS_MIN), "minor-faults", },
35 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MAJ), "major-faults", }, 37 { C(SOFTWARE, PAGE_FAULTS_MAJ), "major-faults", },
36 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "context-switches", }, 38 { C(SOFTWARE, CONTEXT_SWITCHES), "context-switches", },
37 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "cs", }, 39 { C(SOFTWARE, CONTEXT_SWITCHES), "cs", },
38 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "cpu-migrations", }, 40 { C(SOFTWARE, CPU_MIGRATIONS), "cpu-migrations", },
39 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "migrations", }, 41 { C(SOFTWARE, CPU_MIGRATIONS), "migrations", },
40}; 42};
41 43
42#define __PERF_COUNTER_FIELD(config, name) \ 44#define __PERF_COUNTER_FIELD(config, name) \
@@ -67,27 +69,26 @@ static char *sw_event_names[] = {
67 "major faults", 69 "major faults",
68}; 70};
69 71
70char *event_name(int ctr) 72char *event_name(int counter)
71{ 73{
72 __u64 config = event_id[ctr]; 74 __u64 config = attrs[counter].config;
73 int type = PERF_COUNTER_TYPE(config); 75 int type = attrs[counter].type;
74 int id = PERF_COUNTER_ID(config);
75 static char buf[32]; 76 static char buf[32];
76 77
77 if (PERF_COUNTER_RAW(config)) { 78 if (attrs[counter].type == PERF_TYPE_RAW) {
78 sprintf(buf, "raw 0x%llx", PERF_COUNTER_CONFIG(config)); 79 sprintf(buf, "raw 0x%llx", config);
79 return buf; 80 return buf;
80 } 81 }
81 82
82 switch (type) { 83 switch (type) {
83 case PERF_TYPE_HARDWARE: 84 case PERF_TYPE_HARDWARE:
84 if (id < PERF_HW_EVENTS_MAX) 85 if (config < PERF_HW_EVENTS_MAX)
85 return hw_event_names[id]; 86 return hw_event_names[config];
86 return "unknown-hardware"; 87 return "unknown-hardware";
87 88
88 case PERF_TYPE_SOFTWARE: 89 case PERF_TYPE_SOFTWARE:
89 if (id < PERF_SW_EVENTS_MAX) 90 if (config < PERF_SW_EVENTS_MAX)
90 return sw_event_names[id]; 91 return sw_event_names[config];
91 return "unknown-software"; 92 return "unknown-software";
92 93
93 default: 94 default:
@@ -101,15 +102,19 @@ char *event_name(int ctr)
101 * Each event can have multiple symbolic names. 102 * Each event can have multiple symbolic names.
102 * Symbolic names are (almost) exactly matched. 103 * Symbolic names are (almost) exactly matched.
103 */ 104 */
104static __u64 match_event_symbols(const char *str) 105static int match_event_symbols(const char *str, struct perf_counter_attr *attr)
105{ 106{
106 __u64 config, id; 107 __u64 config, id;
107 int type; 108 int type;
108 unsigned int i; 109 unsigned int i;
109 const char *sep, *pstr; 110 const char *sep, *pstr;
110 111
111 if (str[0] == 'r' && hex2u64(str + 1, &config) > 0) 112 if (str[0] == 'r' && hex2u64(str + 1, &config) > 0) {
112 return config | PERF_COUNTER_RAW_MASK; 113 attr->type = PERF_TYPE_RAW;
114 attr->config = config;
115
116 return 0;
117 }
113 118
114 pstr = str; 119 pstr = str;
115 sep = strchr(pstr, ':'); 120 sep = strchr(pstr, ':');
@@ -121,35 +126,45 @@ static __u64 match_event_symbols(const char *str)
121 if (sep) { 126 if (sep) {
122 pstr = sep + 1; 127 pstr = sep + 1;
123 if (strchr(pstr, 'k')) 128 if (strchr(pstr, 'k'))
124 event_mask[nr_counters] |= EVENT_MASK_USER; 129 attr->exclude_user = 1;
125 if (strchr(pstr, 'u')) 130 if (strchr(pstr, 'u'))
126 event_mask[nr_counters] |= EVENT_MASK_KERNEL; 131 attr->exclude_kernel = 1;
127 } 132 }
128 return EID(type, id); 133 attr->type = type;
134 attr->config = id;
135
136 return 0;
129 } 137 }
130 138
131 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { 139 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
132 if (!strncmp(str, event_symbols[i].symbol, 140 if (!strncmp(str, event_symbols[i].symbol,
133 strlen(event_symbols[i].symbol))) 141 strlen(event_symbols[i].symbol))) {
134 return event_symbols[i].event; 142
143 attr->type = event_symbols[i].type;
144 attr->config = event_symbols[i].config;
145
146 return 0;
147 }
135 } 148 }
136 149
137 return ~0ULL; 150 return -EINVAL;
138} 151}
139 152
140int parse_events(const struct option *opt, const char *str, int unset) 153int parse_events(const struct option *opt, const char *str, int unset)
141{ 154{
142 __u64 config; 155 struct perf_counter_attr attr;
156 int ret;
143 157
158 memset(&attr, 0, sizeof(attr));
144again: 159again:
145 if (nr_counters == MAX_COUNTERS) 160 if (nr_counters == MAX_COUNTERS)
146 return -1; 161 return -1;
147 162
148 config = match_event_symbols(str); 163 ret = match_event_symbols(str, &attr);
149 if (config == ~0ULL) 164 if (ret < 0)
150 return -1; 165 return ret;
151 166
152 event_id[nr_counters] = config; 167 attrs[nr_counters] = attr;
153 nr_counters++; 168 nr_counters++;
154 169
155 str = strstr(str, ","); 170 str = strstr(str, ",");
@@ -168,7 +183,6 @@ void create_events_help(char *events_help_msg)
168{ 183{
169 unsigned int i; 184 unsigned int i;
170 char *str; 185 char *str;
171 __u64 e;
172 186
173 str = events_help_msg; 187 str = events_help_msg;
174 188
@@ -178,9 +192,8 @@ void create_events_help(char *events_help_msg)
178 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { 192 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
179 int type, id; 193 int type, id;
180 194
181 e = event_symbols[i].event; 195 type = event_symbols[i].type;
182 type = PERF_COUNTER_TYPE(e); 196 id = event_symbols[i].config;
183 id = PERF_COUNTER_ID(e);
184 197
185 if (i) 198 if (i)
186 str += sprintf(str, "|"); 199 str += sprintf(str, "|");
@@ -191,4 +204,3 @@ void create_events_help(char *events_help_msg)
191 204
192 str += sprintf(str, "|rNNN]"); 205 str += sprintf(str, "|rNNN]");
193} 206}
194