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

+116 -54
+1 -1
tools/perf/builtin-record.c
··· 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 }
+1 -1
tools/perf/builtin-test.c
··· 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) {
+4 -4
tools/perf/builtin-top.c
··· 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 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)
+107 -46
tools/perf/util/evlist.c
··· 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; ··· 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; ··· 273 267 274 268 perf_evlist__add_pollfd(evlist, fd); 275 269 return 0; 270 + } 271 + 272 + static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask) 273 + { 274 + struct perf_evsel *evsel; 275 + int cpu, thread; 276 + 277 + for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 278 + int output = -1; 279 + 280 + for (thread = 0; thread < evlist->threads->nr; thread++) { 281 + list_for_each_entry(evsel, &evlist->entries, node) { 282 + int fd = FD(evsel, cpu, thread); 283 + 284 + if (output == -1) { 285 + output = fd; 286 + if (__perf_evlist__mmap(evlist, evsel, cpu, 287 + prot, mask, output) < 0) 288 + goto out_unmap; 289 + } else { 290 + if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0) 291 + goto out_unmap; 292 + } 293 + 294 + if ((evsel->attr.read_format & PERF_FORMAT_ID) && 295 + perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) 296 + goto out_unmap; 297 + } 298 + } 299 + } 300 + 301 + return 0; 302 + 303 + out_unmap: 304 + for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 305 + if (evlist->mmap[cpu].base != NULL) { 306 + munmap(evlist->mmap[cpu].base, evlist->mmap_len); 307 + evlist->mmap[cpu].base = NULL; 308 + } 309 + } 310 + return -1; 311 + } 312 + 313 + static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask) 314 + { 315 + struct perf_evsel *evsel; 316 + int thread; 317 + 318 + for (thread = 0; thread < evlist->threads->nr; thread++) { 319 + int output = -1; 320 + 321 + list_for_each_entry(evsel, &evlist->entries, node) { 322 + int fd = FD(evsel, 0, thread); 323 + 324 + if (output == -1) { 325 + output = fd; 326 + if (__perf_evlist__mmap(evlist, evsel, thread, 327 + prot, mask, output) < 0) 328 + goto out_unmap; 329 + } else { 330 + if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0) 331 + goto out_unmap; 332 + } 333 + 334 + if ((evsel->attr.read_format & PERF_FORMAT_ID) && 335 + perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0) 336 + goto out_unmap; 337 + } 338 + } 339 + 340 + return 0; 341 + 342 + out_unmap: 343 + for (thread = 0; thread < evlist->threads->nr; thread++) { 344 + if (evlist->mmap[thread].base != NULL) { 345 + munmap(evlist->mmap[thread].base, evlist->mmap_len); 346 + evlist->mmap[thread].base = NULL; 347 + } 348 + } 349 + return -1; 276 350 } 277 351 278 352 /** perf_evlist__mmap - Create per cpu maps to receive events ··· 373 287 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) 374 288 { 375 289 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 376 - int mask = pages * page_size - 1, cpu; 377 - struct perf_evsel *first_evsel, *evsel; 290 + int mask = pages * page_size - 1; 291 + struct perf_evsel *evsel; 378 292 const struct cpu_map *cpus = evlist->cpus; 379 293 const struct thread_map *threads = evlist->threads; 380 - int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); 294 + int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); 381 295 382 296 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) 383 297 return -ENOMEM; ··· 387 301 388 302 evlist->overwrite = overwrite; 389 303 evlist->mmap_len = (pages + 1) * page_size; 390 - first_evsel = list_entry(evlist->entries.next, struct perf_evsel, node); 391 304 392 305 list_for_each_entry(evsel, &evlist->entries, node) { 393 306 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 394 307 evsel->sample_id == NULL && 395 308 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0) 396 309 return -ENOMEM; 397 - 398 - for (cpu = 0; cpu < cpus->nr; cpu++) { 399 - for (thread = 0; thread < threads->nr; thread++) { 400 - int fd = FD(evsel, cpu, thread); 401 - 402 - if (evsel->idx || thread) { 403 - if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, 404 - FD(first_evsel, cpu, 0)) != 0) 405 - goto out_unmap; 406 - } else if (__perf_evlist__mmap(evlist, evsel, cpu, 407 - prot, mask, fd) < 0) 408 - goto out_unmap; 409 - 410 - if ((evsel->attr.read_format & PERF_FORMAT_ID) && 411 - perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) 412 - goto out_unmap; 413 - } 414 - } 415 310 } 416 311 417 - return 0; 312 + if (evlist->cpus->map[0] == -1) 313 + return perf_evlist__mmap_per_thread(evlist, prot, mask); 418 314 419 - out_unmap: 420 - for (cpu = 0; cpu < cpus->nr; cpu++) { 421 - if (evlist->mmap[cpu].base != NULL) { 422 - munmap(evlist->mmap[cpu].base, evlist->mmap_len); 423 - evlist->mmap[cpu].base = NULL; 424 - } 425 - } 426 - return -1; 315 + return perf_evlist__mmap_per_cpu(evlist, prot, mask); 427 316 } 428 317 429 318 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, ··· 409 348 if (evlist->threads == NULL) 410 349 return -1; 411 350 412 - if (target_tid != -1) 351 + if (cpu_list == NULL && target_tid != -1) 413 352 evlist->cpus = cpu_map__dummy_new(); 414 353 else 415 354 evlist->cpus = cpu_map__new(cpu_list);
+2 -1
tools/perf/util/evlist.h
··· 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; ··· 47 46 48 47 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); 49 48 50 - union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *self, int cpu); 49 + union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); 51 50 52 51 int perf_evlist__alloc_mmap(struct perf_evlist *evlist); 53 52 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);
+1 -1
tools/perf/util/python.c
··· 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);