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 { 428 int i; 429 430 - for (i = 0; i < evsel_list->cpus->nr; i++) { 431 if (evsel_list->mmap[i].base) 432 mmap_read(&evsel_list->mmap[i]); 433 }
··· 427 { 428 int i; 429 430 + for (i = 0; i < evsel_list->nr_mmaps; i++) { 431 if (evsel_list->mmap[i].base) 432 mmap_read(&evsel_list->mmap[i]); 433 }
+1 -1
tools/perf/builtin-test.c
··· 549 ++foo; 550 } 551 552 - while ((event = perf_evlist__read_on_cpu(evlist, 0)) != NULL) { 553 struct perf_sample sample; 554 555 if (event->header.type != PERF_RECORD_SAMPLE) {
··· 549 ++foo; 550 } 551 552 + while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { 553 struct perf_sample sample; 554 555 if (event->header.type != PERF_RECORD_SAMPLE) {
+4 -4
tools/perf/builtin-top.c
··· 801 } 802 } 803 804 - static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu) 805 { 806 struct perf_sample sample; 807 union perf_event *event; 808 809 - while ((event = perf_evlist__read_on_cpu(top.evlist, cpu)) != NULL) { 810 perf_session__parse_sample(self, event, &sample); 811 812 if (event->header.type == PERF_RECORD_SAMPLE) ··· 820 { 821 int i; 822 823 - for (i = 0; i < top.evlist->cpus->nr; i++) 824 - perf_session__mmap_read_cpu(self, i); 825 } 826 827 static void start_counters(struct perf_evlist *evlist)
··· 801 } 802 } 803 804 + static void perf_session__mmap_read_idx(struct perf_session *self, int idx) 805 { 806 struct perf_sample sample; 807 union perf_event *event; 808 809 + while ((event = perf_evlist__mmap_read(top.evlist, idx)) != NULL) { 810 perf_session__parse_sample(self, event, &sample); 811 812 if (event->header.type == PERF_RECORD_SAMPLE) ··· 820 { 821 int i; 822 823 + for (i = 0; i < top.evlist->nr_mmaps; i++) 824 + perf_session__mmap_read_idx(self, i); 825 } 826 827 static void start_counters(struct perf_evlist *evlist)
+107 -46
tools/perf/util/evlist.c
··· 166 return NULL; 167 } 168 169 - union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu) 170 { 171 /* XXX Move this to perf.c, making it generally available */ 172 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 173 - struct perf_mmap *md = &evlist->mmap[cpu]; 174 unsigned int head = perf_mmap__read_head(md); 175 unsigned int old = md->prev; 176 unsigned char *data = md->base + page_size; ··· 235 236 void perf_evlist__munmap(struct perf_evlist *evlist) 237 { 238 - int cpu; 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; 244 } 245 } 246 } 247 248 int perf_evlist__alloc_mmap(struct perf_evlist *evlist) 249 { 250 - evlist->mmap = zalloc(evlist->cpus->nr * sizeof(struct perf_mmap)); 251 return evlist->mmap != NULL ? 0 : -ENOMEM; 252 } 253 254 static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel, 255 - int cpu, int prot, int mask, int fd) 256 { 257 - evlist->mmap[cpu].prev = 0; 258 - evlist->mmap[cpu].mask = mask; 259 - evlist->mmap[cpu].base = mmap(NULL, evlist->mmap_len, prot, 260 MAP_SHARED, fd, 0); 261 - if (evlist->mmap[cpu].base == MAP_FAILED) { 262 - if (evlist->cpus->map[cpu] == -1 && evsel->attr.inherit) 263 ui__warning("Inherit is not allowed on per-task " 264 "events using mmap.\n"); 265 return -1; ··· 273 274 perf_evlist__add_pollfd(evlist, fd); 275 return 0; 276 } 277 278 /** perf_evlist__mmap - Create per cpu maps to receive events ··· 373 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) 374 { 375 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 376 - int mask = pages * page_size - 1, cpu; 377 - struct perf_evsel *first_evsel, *evsel; 378 const struct cpu_map *cpus = evlist->cpus; 379 const struct thread_map *threads = evlist->threads; 380 - int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); 381 382 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) 383 return -ENOMEM; ··· 387 388 evlist->overwrite = overwrite; 389 evlist->mmap_len = (pages + 1) * page_size; 390 - first_evsel = list_entry(evlist->entries.next, struct perf_evsel, node); 391 392 list_for_each_entry(evsel, &evlist->entries, node) { 393 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 394 evsel->sample_id == NULL && 395 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0) 396 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 } 416 417 - return 0; 418 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; 427 } 428 429 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, ··· 409 if (evlist->threads == NULL) 410 return -1; 411 412 - if (target_tid != -1) 413 evlist->cpus = cpu_map__dummy_new(); 414 else 415 evlist->cpus = cpu_map__new(cpu_list);
··· 166 return NULL; 167 } 168 169 + union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) 170 { 171 /* XXX Move this to perf.c, making it generally available */ 172 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 173 + struct perf_mmap *md = &evlist->mmap[idx]; 174 unsigned int head = perf_mmap__read_head(md); 175 unsigned int old = md->prev; 176 unsigned char *data = md->base + page_size; ··· 235 236 void perf_evlist__munmap(struct perf_evlist *evlist) 237 { 238 + int i; 239 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 } 245 } 246 + 247 + free(evlist->mmap); 248 + evlist->mmap = NULL; 249 } 250 251 int perf_evlist__alloc_mmap(struct perf_evlist *evlist) 252 { 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)); 257 return evlist->mmap != NULL ? 0 : -ENOMEM; 258 } 259 260 static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel, 261 + int idx, int prot, int mask, int fd) 262 { 263 + evlist->mmap[idx].prev = 0; 264 + evlist->mmap[idx].mask = mask; 265 + evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot, 266 MAP_SHARED, fd, 0); 267 + if (evlist->mmap[idx].base == MAP_FAILED) { 268 + if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit) 269 ui__warning("Inherit is not allowed on per-task " 270 "events using mmap.\n"); 271 return -1; ··· 267 268 perf_evlist__add_pollfd(evlist, fd); 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; 350 } 351 352 /** perf_evlist__mmap - Create per cpu maps to receive events ··· 287 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) 288 { 289 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 290 + int mask = pages * page_size - 1; 291 + struct perf_evsel *evsel; 292 const struct cpu_map *cpus = evlist->cpus; 293 const struct thread_map *threads = evlist->threads; 294 + int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); 295 296 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) 297 return -ENOMEM; ··· 301 302 evlist->overwrite = overwrite; 303 evlist->mmap_len = (pages + 1) * page_size; 304 305 list_for_each_entry(evsel, &evlist->entries, node) { 306 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 307 evsel->sample_id == NULL && 308 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0) 309 return -ENOMEM; 310 } 311 312 + if (evlist->cpus->map[0] == -1) 313 + return perf_evlist__mmap_per_thread(evlist, prot, mask); 314 315 + return perf_evlist__mmap_per_cpu(evlist, prot, mask); 316 } 317 318 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, ··· 348 if (evlist->threads == NULL) 349 return -1; 350 351 + if (cpu_list == NULL && target_tid != -1) 352 evlist->cpus = cpu_map__dummy_new(); 353 else 354 evlist->cpus = cpu_map__new(cpu_list);
+2 -1
tools/perf/util/evlist.h
··· 17 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; 18 int nr_entries; 19 int nr_fds; 20 int mmap_len; 21 bool overwrite; 22 union perf_event event_copy; ··· 47 48 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); 49 50 - union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *self, int cpu); 51 52 int perf_evlist__alloc_mmap(struct perf_evlist *evlist); 53 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);
··· 17 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; 18 int nr_entries; 19 int nr_fds; 20 + int nr_mmaps; 21 int mmap_len; 22 bool overwrite; 23 union perf_event event_copy; ··· 46 47 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); 48 49 + union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); 50 51 int perf_evlist__alloc_mmap(struct perf_evlist *evlist); 52 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);
+1 -1
tools/perf/util/python.c
··· 680 &cpu, &sample_id_all)) 681 return NULL; 682 683 - event = perf_evlist__read_on_cpu(evlist, cpu); 684 if (event != NULL) { 685 struct perf_evsel *first; 686 PyObject *pyevent = pyrf_event__new(event);
··· 680 &cpu, &sample_id_all)) 681 return NULL; 682 683 + event = perf_evlist__mmap_read(evlist, cpu); 684 if (event != NULL) { 685 struct perf_evsel *first; 686 PyObject *pyevent = pyrf_event__new(event);