Commit 52004ea7ca4c52a219362f973bfd1eb86ff668ce

Authored by Ingo Molnar

Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/acme…

…/linux-2.6 into perf/urgent

Showing 6 changed files Side-by-side Diff

tools/perf/builtin-record.c
... ... @@ -427,7 +427,7 @@
427 427 {
428 428 int i;
429 429  
430   - for (i = 0; i < evsel_list->cpus->nr; i++) {
  430 + for (i = 0; i < evsel_list->nr_mmaps; i++) {
431 431 if (evsel_list->mmap[i].base)
432 432 mmap_read(&evsel_list->mmap[i]);
433 433 }
tools/perf/builtin-test.c
... ... @@ -549,7 +549,7 @@
549 549 ++foo;
550 550 }
551 551  
552   - while ((event = perf_evlist__read_on_cpu(evlist, 0)) != NULL) {
  552 + while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
553 553 struct perf_sample sample;
554 554  
555 555 if (event->header.type != PERF_RECORD_SAMPLE) {
tools/perf/builtin-top.c
... ... @@ -801,12 +801,12 @@
801 801 }
802 802 }
803 803  
804   -static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu)
  804 +static void perf_session__mmap_read_idx(struct perf_session *self, int idx)
805 805 {
806 806 struct perf_sample sample;
807 807 union perf_event *event;
808 808  
809   - while ((event = perf_evlist__read_on_cpu(top.evlist, cpu)) != NULL) {
  809 + while ((event = perf_evlist__mmap_read(top.evlist, idx)) != NULL) {
810 810 perf_session__parse_sample(self, event, &sample);
811 811  
812 812 if (event->header.type == PERF_RECORD_SAMPLE)
... ... @@ -820,8 +820,8 @@
820 820 {
821 821 int i;
822 822  
823   - for (i = 0; i < top.evlist->cpus->nr; i++)
824   - perf_session__mmap_read_cpu(self, i);
  823 + for (i = 0; i < top.evlist->nr_mmaps; i++)
  824 + perf_session__mmap_read_idx(self, i);
825 825 }
826 826  
827 827 static void start_counters(struct perf_evlist *evlist)
tools/perf/util/evlist.c
... ... @@ -166,11 +166,11 @@
166 166 return NULL;
167 167 }
168 168  
169   -union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu)
  169 +union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
170 170 {
171 171 /* XXX Move this to perf.c, making it generally available */
172 172 unsigned int page_size = sysconf(_SC_PAGE_SIZE);
173   - struct perf_mmap *md = &evlist->mmap[cpu];
  173 + struct perf_mmap *md = &evlist->mmap[idx];
174 174 unsigned int head = perf_mmap__read_head(md);
175 175 unsigned int old = md->prev;
176 176 unsigned char *data = md->base + page_size;
177 177  
178 178  
179 179  
180 180  
181 181  
182 182  
... ... @@ -235,31 +235,37 @@
235 235  
236 236 void perf_evlist__munmap(struct perf_evlist *evlist)
237 237 {
238   - int cpu;
  238 + int i;
239 239  
240   - for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
241   - if (evlist->mmap[cpu].base != NULL) {
242   - munmap(evlist->mmap[cpu].base, evlist->mmap_len);
243   - evlist->mmap[cpu].base = NULL;
  240 + for (i = 0; i < evlist->nr_mmaps; i++) {
  241 + if (evlist->mmap[i].base != NULL) {
  242 + munmap(evlist->mmap[i].base, evlist->mmap_len);
  243 + evlist->mmap[i].base = NULL;
244 244 }
245 245 }
  246 +
  247 + free(evlist->mmap);
  248 + evlist->mmap = NULL;
246 249 }
247 250  
248 251 int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
249 252 {
250   - evlist->mmap = zalloc(evlist->cpus->nr * sizeof(struct perf_mmap));
  253 + evlist->nr_mmaps = evlist->cpus->nr;
  254 + if (evlist->cpus->map[0] == -1)
  255 + evlist->nr_mmaps = evlist->threads->nr;
  256 + evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
251 257 return evlist->mmap != NULL ? 0 : -ENOMEM;
252 258 }
253 259  
254 260 static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel,
255   - int cpu, int prot, int mask, int fd)
  261 + int idx, int prot, int mask, int fd)
256 262 {
257   - evlist->mmap[cpu].prev = 0;
258   - evlist->mmap[cpu].mask = mask;
259   - evlist->mmap[cpu].base = mmap(NULL, evlist->mmap_len, prot,
  263 + evlist->mmap[idx].prev = 0;
  264 + evlist->mmap[idx].mask = mask;
  265 + evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
260 266 MAP_SHARED, fd, 0);
261   - if (evlist->mmap[cpu].base == MAP_FAILED) {
262   - if (evlist->cpus->map[cpu] == -1 && evsel->attr.inherit)
  267 + if (evlist->mmap[idx].base == MAP_FAILED) {
  268 + if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit)
263 269 ui__warning("Inherit is not allowed on per-task "
264 270 "events using mmap.\n");
265 271 return -1;
... ... @@ -269,6 +275,86 @@
269 275 return 0;
270 276 }
271 277  
  278 +static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask)
  279 +{
  280 + struct perf_evsel *evsel;
  281 + int cpu, thread;
  282 +
  283 + for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
  284 + int output = -1;
  285 +
  286 + for (thread = 0; thread < evlist->threads->nr; thread++) {
  287 + list_for_each_entry(evsel, &evlist->entries, node) {
  288 + int fd = FD(evsel, cpu, thread);
  289 +
  290 + if (output == -1) {
  291 + output = fd;
  292 + if (__perf_evlist__mmap(evlist, evsel, cpu,
  293 + prot, mask, output) < 0)
  294 + goto out_unmap;
  295 + } else {
  296 + if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
  297 + goto out_unmap;
  298 + }
  299 +
  300 + if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
  301 + perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
  302 + goto out_unmap;
  303 + }
  304 + }
  305 + }
  306 +
  307 + return 0;
  308 +
  309 +out_unmap:
  310 + for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
  311 + if (evlist->mmap[cpu].base != NULL) {
  312 + munmap(evlist->mmap[cpu].base, evlist->mmap_len);
  313 + evlist->mmap[cpu].base = NULL;
  314 + }
  315 + }
  316 + return -1;
  317 +}
  318 +
  319 +static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask)
  320 +{
  321 + struct perf_evsel *evsel;
  322 + int thread;
  323 +
  324 + for (thread = 0; thread < evlist->threads->nr; thread++) {
  325 + int output = -1;
  326 +
  327 + list_for_each_entry(evsel, &evlist->entries, node) {
  328 + int fd = FD(evsel, 0, thread);
  329 +
  330 + if (output == -1) {
  331 + output = fd;
  332 + if (__perf_evlist__mmap(evlist, evsel, thread,
  333 + prot, mask, output) < 0)
  334 + goto out_unmap;
  335 + } else {
  336 + if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
  337 + goto out_unmap;
  338 + }
  339 +
  340 + if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
  341 + perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0)
  342 + goto out_unmap;
  343 + }
  344 + }
  345 +
  346 + return 0;
  347 +
  348 +out_unmap:
  349 + for (thread = 0; thread < evlist->threads->nr; thread++) {
  350 + if (evlist->mmap[thread].base != NULL) {
  351 + munmap(evlist->mmap[thread].base, evlist->mmap_len);
  352 + evlist->mmap[thread].base = NULL;
  353 + }
  354 + }
  355 + return -1;
  356 +}
  357 +
272 358 /** perf_evlist__mmap - Create per cpu maps to receive events
273 359 *
274 360 * @evlist - list of events
275 361  
... ... @@ -287,11 +373,11 @@
287 373 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite)
288 374 {
289 375 unsigned int page_size = sysconf(_SC_PAGE_SIZE);
290   - int mask = pages * page_size - 1, cpu;
291   - struct perf_evsel *first_evsel, *evsel;
  376 + int mask = pages * page_size - 1;
  377 + struct perf_evsel *evsel;
292 378 const struct cpu_map *cpus = evlist->cpus;
293 379 const struct thread_map *threads = evlist->threads;
294   - int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE);
  380 + int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE);
295 381  
296 382 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
297 383 return -ENOMEM;
298 384  
299 385  
300 386  
... ... @@ -301,43 +387,18 @@
301 387  
302 388 evlist->overwrite = overwrite;
303 389 evlist->mmap_len = (pages + 1) * page_size;
304   - first_evsel = list_entry(evlist->entries.next, struct perf_evsel, node);
305 390  
306 391 list_for_each_entry(evsel, &evlist->entries, node) {
307 392 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
308 393 evsel->sample_id == NULL &&
309 394 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0)
310 395 return -ENOMEM;
311   -
312   - for (cpu = 0; cpu < cpus->nr; cpu++) {
313   - for (thread = 0; thread < threads->nr; thread++) {
314   - int fd = FD(evsel, cpu, thread);
315   -
316   - if (evsel->idx || thread) {
317   - if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT,
318   - FD(first_evsel, cpu, 0)) != 0)
319   - goto out_unmap;
320   - } else if (__perf_evlist__mmap(evlist, evsel, cpu,
321   - prot, mask, fd) < 0)
322   - goto out_unmap;
323   -
324   - if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
325   - perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
326   - goto out_unmap;
327   - }
328   - }
329 396 }
330 397  
331   - return 0;
  398 + if (evlist->cpus->map[0] == -1)
  399 + return perf_evlist__mmap_per_thread(evlist, prot, mask);
332 400  
333   -out_unmap:
334   - for (cpu = 0; cpu < cpus->nr; cpu++) {
335   - if (evlist->mmap[cpu].base != NULL) {
336   - munmap(evlist->mmap[cpu].base, evlist->mmap_len);
337   - evlist->mmap[cpu].base = NULL;
338   - }
339   - }
340   - return -1;
  401 + return perf_evlist__mmap_per_cpu(evlist, prot, mask);
341 402 }
342 403  
343 404 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
... ... @@ -348,7 +409,7 @@
348 409 if (evlist->threads == NULL)
349 410 return -1;
350 411  
351   - if (target_tid != -1)
  412 + if (cpu_list == NULL && target_tid != -1)
352 413 evlist->cpus = cpu_map__dummy_new();
353 414 else
354 415 evlist->cpus = cpu_map__new(cpu_list);
tools/perf/util/evlist.h
... ... @@ -17,6 +17,7 @@
17 17 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
18 18 int nr_entries;
19 19 int nr_fds;
  20 + int nr_mmaps;
20 21 int mmap_len;
21 22 bool overwrite;
22 23 union perf_event event_copy;
... ... @@ -46,7 +47,7 @@
46 47  
47 48 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
48 49  
49   -union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *self, int cpu);
  50 +union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
50 51  
51 52 int perf_evlist__alloc_mmap(struct perf_evlist *evlist);
52 53 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);
tools/perf/util/python.c
... ... @@ -680,7 +680,7 @@
680 680 &cpu, &sample_id_all))
681 681 return NULL;
682 682  
683   - event = perf_evlist__read_on_cpu(evlist, cpu);
  683 + event = perf_evlist__mmap_read(evlist, cpu);
684 684 if (event != NULL) {
685 685 struct perf_evsel *first;
686 686 PyObject *pyevent = pyrf_event__new(event);