diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-06-06 03:58:57 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-06 05:37:22 -0400 |
commit | a21ca2cac582886a3e95c8bb84ff7c52d4d15e54 (patch) | |
tree | d110005d81e46b1afb3204fbaacc132d0ec946ee /Documentation/perf_counter/builtin-record.c | |
parent | 2f335a02b3c816e77e7df1d15b12e3bbb8f4c8f0 (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/builtin-record.c')
-rw-r--r-- | Documentation/perf_counter/builtin-record.c | 105 |
1 files changed, 47 insertions, 58 deletions
diff --git a/Documentation/perf_counter/builtin-record.c b/Documentation/perf_counter/builtin-record.c index c22ea0c7472a..130fd88266bb 100644 --- a/Documentation/perf_counter/builtin-record.c +++ b/Documentation/perf_counter/builtin-record.c | |||
@@ -20,10 +20,10 @@ | |||
20 | #define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) | 20 | #define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) |
21 | #define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) | 21 | #define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) |
22 | 22 | ||
23 | static long default_interval = 100000; | ||
24 | static long event_count[MAX_COUNTERS]; | ||
25 | |||
26 | static int fd[MAX_NR_CPUS][MAX_COUNTERS]; | 23 | static int fd[MAX_NR_CPUS][MAX_COUNTERS]; |
24 | |||
25 | static long default_interval = 100000; | ||
26 | |||
27 | static int nr_cpus = 0; | 27 | static int nr_cpus = 0; |
28 | static unsigned int page_size; | 28 | static unsigned int page_size; |
29 | static unsigned int mmap_pages = 128; | 29 | static unsigned int mmap_pages = 128; |
@@ -38,22 +38,44 @@ static int inherit = 1; | |||
38 | static int force = 0; | 38 | static int force = 0; |
39 | static int append_file = 0; | 39 | static int append_file = 0; |
40 | 40 | ||
41 | const unsigned int default_count[] = { | 41 | static long samples; |
42 | 1000000, | 42 | static struct timeval last_read; |
43 | 1000000, | 43 | static struct timeval this_read; |
44 | 10000, | 44 | |
45 | 10000, | 45 | static __u64 bytes_written; |
46 | 1000000, | 46 | |
47 | 10000, | 47 | static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; |
48 | |||
49 | static int nr_poll; | ||
50 | static int nr_cpu; | ||
51 | |||
52 | struct mmap_event { | ||
53 | struct perf_event_header header; | ||
54 | __u32 pid; | ||
55 | __u32 tid; | ||
56 | __u64 start; | ||
57 | __u64 len; | ||
58 | __u64 pgoff; | ||
59 | char filename[PATH_MAX]; | ||
60 | }; | ||
61 | |||
62 | struct comm_event { | ||
63 | struct perf_event_header header; | ||
64 | __u32 pid; | ||
65 | __u32 tid; | ||
66 | char comm[16]; | ||
48 | }; | 67 | }; |
49 | 68 | ||
69 | |||
50 | struct mmap_data { | 70 | struct mmap_data { |
51 | int counter; | 71 | int counter; |
52 | void *base; | 72 | void *base; |
53 | unsigned int mask; | 73 | unsigned int mask; |
54 | unsigned int prev; | 74 | unsigned int prev; |
55 | }; | 75 | }; |
56 | 76 | ||
77 | static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; | ||
78 | |||
57 | static unsigned int mmap_read_head(struct mmap_data *md) | 79 | static unsigned int mmap_read_head(struct mmap_data *md) |
58 | { | 80 | { |
59 | struct perf_counter_mmap_page *pc = md->base; | 81 | struct perf_counter_mmap_page *pc = md->base; |
@@ -65,11 +87,6 @@ static unsigned int mmap_read_head(struct mmap_data *md) | |||
65 | return head; | 87 | return head; |
66 | } | 88 | } |
67 | 89 | ||
68 | static long samples; | ||
69 | static struct timeval last_read, this_read; | ||
70 | |||
71 | static __u64 bytes_written; | ||
72 | |||
73 | static void mmap_read(struct mmap_data *md) | 90 | static void mmap_read(struct mmap_data *md) |
74 | { | 91 | { |
75 | unsigned int head = mmap_read_head(md); | 92 | unsigned int head = mmap_read_head(md); |
@@ -157,29 +174,6 @@ static void sig_handler(int sig) | |||
157 | done = 1; | 174 | done = 1; |
158 | } | 175 | } |
159 | 176 | ||
160 | static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; | ||
161 | static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; | ||
162 | |||
163 | static int nr_poll; | ||
164 | static int nr_cpu; | ||
165 | |||
166 | struct mmap_event { | ||
167 | struct perf_event_header header; | ||
168 | __u32 pid; | ||
169 | __u32 tid; | ||
170 | __u64 start; | ||
171 | __u64 len; | ||
172 | __u64 pgoff; | ||
173 | char filename[PATH_MAX]; | ||
174 | }; | ||
175 | |||
176 | struct comm_event { | ||
177 | struct perf_event_header header; | ||
178 | __u32 pid; | ||
179 | __u32 tid; | ||
180 | char comm[16]; | ||
181 | }; | ||
182 | |||
183 | static void pid_synthesize_comm_event(pid_t pid, int full) | 177 | static void pid_synthesize_comm_event(pid_t pid, int full) |
184 | { | 178 | { |
185 | struct comm_event comm_ev; | 179 | struct comm_event comm_ev; |
@@ -341,24 +335,21 @@ static int group_fd; | |||
341 | 335 | ||
342 | static void create_counter(int counter, int cpu, pid_t pid) | 336 | static void create_counter(int counter, int cpu, pid_t pid) |
343 | { | 337 | { |
344 | struct perf_counter_attr attr; | 338 | struct perf_counter_attr *attr = attrs + counter; |
345 | int track = 1; | 339 | int track = 1; |
346 | 340 | ||
347 | memset(&attr, 0, sizeof(attr)); | 341 | attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_PERIOD; |
348 | attr.config = event_id[counter]; | ||
349 | attr.sample_period = event_count[counter]; | ||
350 | attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_PERIOD; | ||
351 | if (freq) { | 342 | if (freq) { |
352 | attr.freq = 1; | 343 | attr->freq = 1; |
353 | attr.sample_freq = freq; | 344 | attr->sample_freq = freq; |
354 | } | 345 | } |
355 | attr.mmap = track; | 346 | attr->mmap = track; |
356 | attr.comm = track; | 347 | attr->comm = track; |
357 | attr.inherit = (cpu < 0) && inherit; | 348 | attr->inherit = (cpu < 0) && inherit; |
358 | 349 | ||
359 | track = 0; /* only the first counter needs these */ | 350 | track = 0; /* only the first counter needs these */ |
360 | 351 | ||
361 | fd[nr_cpu][counter] = sys_perf_counter_open(&attr, pid, cpu, group_fd, 0); | 352 | fd[nr_cpu][counter] = sys_perf_counter_open(attr, pid, cpu, group_fd, 0); |
362 | 353 | ||
363 | if (fd[nr_cpu][counter] < 0) { | 354 | if (fd[nr_cpu][counter] < 0) { |
364 | int err = errno; | 355 | int err = errno; |
@@ -542,16 +533,14 @@ int cmd_record(int argc, const char **argv, const char *prefix) | |||
542 | if (!argc && target_pid == -1 && !system_wide) | 533 | if (!argc && target_pid == -1 && !system_wide) |
543 | usage_with_options(record_usage, options); | 534 | usage_with_options(record_usage, options); |
544 | 535 | ||
545 | if (!nr_counters) { | 536 | if (!nr_counters) |
546 | nr_counters = 1; | 537 | nr_counters = 1; |
547 | event_id[0] = 0; | ||
548 | } | ||
549 | 538 | ||
550 | for (counter = 0; counter < nr_counters; counter++) { | 539 | for (counter = 0; counter < nr_counters; counter++) { |
551 | if (event_count[counter]) | 540 | if (attrs[counter].sample_period) |
552 | continue; | 541 | continue; |
553 | 542 | ||
554 | event_count[counter] = default_interval; | 543 | attrs[counter].sample_period = default_interval; |
555 | } | 544 | } |
556 | 545 | ||
557 | return __cmd_record(argc, argv); | 546 | return __cmd_record(argc, argv); |