diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-30 14:12:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-30 14:12:00 -0400 |
commit | 65a50c951a38e9827dd9655b6e686bde912e799b (patch) | |
tree | cce85e74511741d52069977fee6984ce66c9277c /tools/perf/util | |
parent | 42fe55ce905212542426fa6407a76534a5fb696a (diff) | |
parent | 59cd358a7a5b2f6b61faa01dae6cfda3830ac62a (diff) |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar.
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (21 commits)
perf ui browser: Stop using 'self'
perf annotate browser: Read perf config file for settings
perf config: Allow '_' in config file variable names
perf annotate browser: Make feature toggles global
perf annotate browser: The idx_asm field should be used in asm only view
perf tools: Convert critical messages to ui__error()
perf ui: Make --stdio default when TUI is not supported
tools lib traceevent: Silence compiler warning on 32bit build
perf record: Fix branch_stack type in perf_record_opts
perf tools: Reconstruct event with modifiers from perf_event_attr
perf top: Fix counter name fixup when fallbacking to cpu-clock
perf tools: fix thread_map__new_by_pid_str() memory leak in error path
perf tools: Do not use _FORTIFY_SOURCE when DEBUG=1 is specified
tools lib traceevent: Fix signature of create_arg_item()
tools lib traceevent: Use proper function parameter type
tools lib traceevent: Fix freeing arg on process_dynamic_array()
tools lib traceevent: Fix a possibly wrong memory dereference
tools lib traceevent: Fix a possible memory leak
tools lib traceevent: Allow expressions in __print_symbolic() fields
perf evlist: Explicititely initialize input_name
...
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/config.c | 2 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 90 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 3 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 27 | ||||
-rw-r--r-- | tools/perf/util/thread_map.c | 21 |
5 files changed, 115 insertions, 28 deletions
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 0deac6a14b65..6faa3a18bfbd 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c | |||
@@ -120,7 +120,7 @@ static char *parse_value(void) | |||
120 | 120 | ||
121 | static inline int iskeychar(int c) | 121 | static inline int iskeychar(int c) |
122 | { | 122 | { |
123 | return isalnum(c) || c == '-'; | 123 | return isalnum(c) || c == '-' || c == '_'; |
124 | } | 124 | } |
125 | 125 | ||
126 | static int get_value(config_fn_t fn, void *data, char *name, unsigned int len) | 126 | static int get_value(config_fn_t fn, void *data, char *name, unsigned int len) |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 57e4ce57bbcc..91d19138f3ec 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "cpumap.h" | 15 | #include "cpumap.h" |
16 | #include "thread_map.h" | 16 | #include "thread_map.h" |
17 | #include "target.h" | 17 | #include "target.h" |
18 | #include "../../include/linux/perf_event.h" | ||
18 | 19 | ||
19 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 20 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
20 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) | 21 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) |
@@ -64,6 +65,95 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) | |||
64 | return evsel; | 65 | return evsel; |
65 | } | 66 | } |
66 | 67 | ||
68 | static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { | ||
69 | "cycles", | ||
70 | "instructions", | ||
71 | "cache-references", | ||
72 | "cache-misses", | ||
73 | "branches", | ||
74 | "branch-misses", | ||
75 | "bus-cycles", | ||
76 | "stalled-cycles-frontend", | ||
77 | "stalled-cycles-backend", | ||
78 | "ref-cycles", | ||
79 | }; | ||
80 | |||
81 | const char *__perf_evsel__hw_name(u64 config) | ||
82 | { | ||
83 | if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config]) | ||
84 | return perf_evsel__hw_names[config]; | ||
85 | |||
86 | return "unknown-hardware"; | ||
87 | } | ||
88 | |||
89 | static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) | ||
90 | { | ||
91 | int colon = 0; | ||
92 | struct perf_event_attr *attr = &evsel->attr; | ||
93 | int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(attr->config)); | ||
94 | bool exclude_guest_default = false; | ||
95 | |||
96 | #define MOD_PRINT(context, mod) do { \ | ||
97 | if (!attr->exclude_##context) { \ | ||
98 | if (!colon) colon = r++; \ | ||
99 | r += scnprintf(bf + r, size - r, "%c", mod); \ | ||
100 | } } while(0) | ||
101 | |||
102 | if (attr->exclude_kernel || attr->exclude_user || attr->exclude_hv) { | ||
103 | MOD_PRINT(kernel, 'k'); | ||
104 | MOD_PRINT(user, 'u'); | ||
105 | MOD_PRINT(hv, 'h'); | ||
106 | exclude_guest_default = true; | ||
107 | } | ||
108 | |||
109 | if (attr->precise_ip) { | ||
110 | if (!colon) | ||
111 | colon = r++; | ||
112 | r += scnprintf(bf + r, size - r, "%.*s", attr->precise_ip, "ppp"); | ||
113 | exclude_guest_default = true; | ||
114 | } | ||
115 | |||
116 | if (attr->exclude_host || attr->exclude_guest == exclude_guest_default) { | ||
117 | MOD_PRINT(host, 'H'); | ||
118 | MOD_PRINT(guest, 'G'); | ||
119 | } | ||
120 | #undef MOD_PRINT | ||
121 | if (colon) | ||
122 | bf[colon] = ':'; | ||
123 | return r; | ||
124 | } | ||
125 | |||
126 | int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) | ||
127 | { | ||
128 | int ret; | ||
129 | |||
130 | switch (evsel->attr.type) { | ||
131 | case PERF_TYPE_RAW: | ||
132 | ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); | ||
133 | break; | ||
134 | |||
135 | case PERF_TYPE_HARDWARE: | ||
136 | ret = perf_evsel__hw_name(evsel, bf, size); | ||
137 | break; | ||
138 | default: | ||
139 | /* | ||
140 | * FIXME | ||
141 | * | ||
142 | * This is the minimal perf_evsel__name so that we can | ||
143 | * reconstruct event names taking into account event modifiers. | ||
144 | * | ||
145 | * The old event_name uses it now for raw anr hw events, so that | ||
146 | * we don't drag all the parsing stuff into the python binding. | ||
147 | * | ||
148 | * On the next devel cycle the rest of the event naming will be | ||
149 | * brought here. | ||
150 | */ | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | return ret; | ||
155 | } | ||
156 | |||
67 | void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, | 157 | void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, |
68 | struct perf_evsel *first) | 158 | struct perf_evsel *first) |
69 | { | 159 | { |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 3d6b3e4cb66b..4ba8b564e6f4 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -83,6 +83,9 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
83 | struct perf_record_opts *opts, | 83 | struct perf_record_opts *opts, |
84 | struct perf_evsel *first); | 84 | struct perf_evsel *first); |
85 | 85 | ||
86 | const char* __perf_evsel__hw_name(u64 config); | ||
87 | int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size); | ||
88 | |||
86 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); | 89 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); |
87 | int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); | 90 | int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); |
88 | int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus); | 91 | int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus); |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index fac7d59309b8..05dbc8b3c767 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -62,19 +62,6 @@ static struct event_symbol event_symbols[] = { | |||
62 | #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) | 62 | #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) |
63 | #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) | 63 | #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) |
64 | 64 | ||
65 | static const char *hw_event_names[PERF_COUNT_HW_MAX] = { | ||
66 | "cycles", | ||
67 | "instructions", | ||
68 | "cache-references", | ||
69 | "cache-misses", | ||
70 | "branches", | ||
71 | "branch-misses", | ||
72 | "bus-cycles", | ||
73 | "stalled-cycles-frontend", | ||
74 | "stalled-cycles-backend", | ||
75 | "ref-cycles", | ||
76 | }; | ||
77 | |||
78 | static const char *sw_event_names[PERF_COUNT_SW_MAX] = { | 65 | static const char *sw_event_names[PERF_COUNT_SW_MAX] = { |
79 | "cpu-clock", | 66 | "cpu-clock", |
80 | "task-clock", | 67 | "task-clock", |
@@ -300,6 +287,16 @@ const char *event_name(struct perf_evsel *evsel) | |||
300 | u64 config = evsel->attr.config; | 287 | u64 config = evsel->attr.config; |
301 | int type = evsel->attr.type; | 288 | int type = evsel->attr.type; |
302 | 289 | ||
290 | if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE) { | ||
291 | /* | ||
292 | * XXX minimal fix, see comment on perf_evsen__name, this static buffer | ||
293 | * will go away together with event_name in the next devel cycle. | ||
294 | */ | ||
295 | static char bf[128]; | ||
296 | perf_evsel__name(evsel, bf, sizeof(bf)); | ||
297 | return bf; | ||
298 | } | ||
299 | |||
303 | if (evsel->name) | 300 | if (evsel->name) |
304 | return evsel->name; | 301 | return evsel->name; |
305 | 302 | ||
@@ -317,9 +314,7 @@ const char *__event_name(int type, u64 config) | |||
317 | 314 | ||
318 | switch (type) { | 315 | switch (type) { |
319 | case PERF_TYPE_HARDWARE: | 316 | case PERF_TYPE_HARDWARE: |
320 | if (config < PERF_COUNT_HW_MAX && hw_event_names[config]) | 317 | return __perf_evsel__hw_name(config); |
321 | return hw_event_names[config]; | ||
322 | return "unknown-hardware"; | ||
323 | 318 | ||
324 | case PERF_TYPE_HW_CACHE: { | 319 | case PERF_TYPE_HW_CACHE: { |
325 | u8 cache_type, cache_op, cache_result; | 320 | u8 cache_type, cache_op, cache_result; |
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 84d9bd782004..9b5f856cc280 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c | |||
@@ -188,28 +188,27 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) | |||
188 | nt = realloc(threads, (sizeof(*threads) + | 188 | nt = realloc(threads, (sizeof(*threads) + |
189 | sizeof(pid_t) * total_tasks)); | 189 | sizeof(pid_t) * total_tasks)); |
190 | if (nt == NULL) | 190 | if (nt == NULL) |
191 | goto out_free_threads; | 191 | goto out_free_namelist; |
192 | 192 | ||
193 | threads = nt; | 193 | threads = nt; |
194 | 194 | ||
195 | if (threads) { | 195 | for (i = 0; i < items; i++) { |
196 | for (i = 0; i < items; i++) | 196 | threads->map[j++] = atoi(namelist[i]->d_name); |
197 | threads->map[j++] = atoi(namelist[i]->d_name); | ||
198 | threads->nr = total_tasks; | ||
199 | } | ||
200 | |||
201 | for (i = 0; i < items; i++) | ||
202 | free(namelist[i]); | 197 | free(namelist[i]); |
198 | } | ||
199 | threads->nr = total_tasks; | ||
203 | free(namelist); | 200 | free(namelist); |
204 | |||
205 | if (!threads) | ||
206 | break; | ||
207 | } | 201 | } |
208 | 202 | ||
209 | out: | 203 | out: |
210 | strlist__delete(slist); | 204 | strlist__delete(slist); |
211 | return threads; | 205 | return threads; |
212 | 206 | ||
207 | out_free_namelist: | ||
208 | for (i = 0; i < items; i++) | ||
209 | free(namelist[i]); | ||
210 | free(namelist); | ||
211 | |||
213 | out_free_threads: | 212 | out_free_threads: |
214 | free(threads); | 213 | free(threads); |
215 | threads = NULL; | 214 | threads = NULL; |