···427427{428428 int i;429429430430- for (i = 0; i < evsel_list->cpus->nr; i++) {430430+ for (i = 0; i < evsel_list->nr_mmaps; i++) {431431 if (evsel_list->mmap[i].base)432432 mmap_read(&evsel_list->mmap[i]);433433 }
+1-1
tools/perf/builtin-test.c
···549549 ++foo;550550 }551551552552- while ((event = perf_evlist__read_on_cpu(evlist, 0)) != NULL) {552552+ while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {553553 struct perf_sample sample;554554555555 if (event->header.type != PERF_RECORD_SAMPLE) {
+4-4
tools/perf/builtin-top.c
···801801 }802802}803803804804-static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu)804804+static void perf_session__mmap_read_idx(struct perf_session *self, int idx)805805{806806 struct perf_sample sample;807807 union perf_event *event;808808809809- while ((event = perf_evlist__read_on_cpu(top.evlist, cpu)) != NULL) {809809+ while ((event = perf_evlist__mmap_read(top.evlist, idx)) != NULL) {810810 perf_session__parse_sample(self, event, &sample);811811812812 if (event->header.type == PERF_RECORD_SAMPLE)···820820{821821 int i;822822823823- for (i = 0; i < top.evlist->cpus->nr; i++)824824- perf_session__mmap_read_cpu(self, i);823823+ for (i = 0; i < top.evlist->nr_mmaps; i++)824824+ perf_session__mmap_read_idx(self, i);825825}826826827827static void start_counters(struct perf_evlist *evlist)
+107-46
tools/perf/util/evlist.c
···166166 return NULL;167167}168168169169-union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu)169169+union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)170170{171171 /* XXX Move this to perf.c, making it generally available */172172 unsigned int page_size = sysconf(_SC_PAGE_SIZE);173173- struct perf_mmap *md = &evlist->mmap[cpu];173173+ struct perf_mmap *md = &evlist->mmap[idx];174174 unsigned int head = perf_mmap__read_head(md);175175 unsigned int old = md->prev;176176 unsigned char *data = md->base + page_size;···235235236236void perf_evlist__munmap(struct perf_evlist *evlist)237237{238238- int cpu;238238+ int i;239239240240- for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {241241- if (evlist->mmap[cpu].base != NULL) {242242- munmap(evlist->mmap[cpu].base, evlist->mmap_len);243243- evlist->mmap[cpu].base = NULL;240240+ for (i = 0; i < evlist->nr_mmaps; i++) {241241+ if (evlist->mmap[i].base != NULL) {242242+ munmap(evlist->mmap[i].base, evlist->mmap_len);243243+ evlist->mmap[i].base = NULL;244244 }245245 }246246+247247+ free(evlist->mmap);248248+ evlist->mmap = NULL;246249}247250248251int perf_evlist__alloc_mmap(struct perf_evlist *evlist)249252{250250- evlist->mmap = zalloc(evlist->cpus->nr * sizeof(struct perf_mmap));253253+ evlist->nr_mmaps = evlist->cpus->nr;254254+ if (evlist->cpus->map[0] == -1)255255+ evlist->nr_mmaps = evlist->threads->nr;256256+ evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));251257 return evlist->mmap != NULL ? 0 : -ENOMEM;252258}253259254260static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel,255255- int cpu, int prot, int mask, int fd)261261+ int idx, int prot, int mask, int fd)256262{257257- evlist->mmap[cpu].prev = 0;258258- evlist->mmap[cpu].mask = mask;259259- evlist->mmap[cpu].base = mmap(NULL, evlist->mmap_len, prot,263263+ evlist->mmap[idx].prev = 0;264264+ evlist->mmap[idx].mask = mask;265265+ evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,260266 MAP_SHARED, fd, 0);261261- if (evlist->mmap[cpu].base == MAP_FAILED) {262262- if (evlist->cpus->map[cpu] == -1 && evsel->attr.inherit)267267+ if (evlist->mmap[idx].base == MAP_FAILED) {268268+ if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit)263269 ui__warning("Inherit is not allowed on per-task "264270 "events using mmap.\n");265271 return -1;···273267274268 perf_evlist__add_pollfd(evlist, fd);275269 return 0;270270+}271271+272272+static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask)273273+{274274+ struct perf_evsel *evsel;275275+ int cpu, thread;276276+277277+ for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {278278+ int output = -1;279279+280280+ for (thread = 0; thread < evlist->threads->nr; thread++) {281281+ list_for_each_entry(evsel, &evlist->entries, node) {282282+ int fd = FD(evsel, cpu, thread);283283+284284+ if (output == -1) {285285+ output = fd;286286+ if (__perf_evlist__mmap(evlist, evsel, cpu,287287+ prot, mask, output) < 0)288288+ goto out_unmap;289289+ } else {290290+ if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)291291+ goto out_unmap;292292+ }293293+294294+ if ((evsel->attr.read_format & PERF_FORMAT_ID) &&295295+ perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)296296+ goto out_unmap;297297+ }298298+ }299299+ }300300+301301+ return 0;302302+303303+out_unmap:304304+ for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {305305+ if (evlist->mmap[cpu].base != NULL) {306306+ munmap(evlist->mmap[cpu].base, evlist->mmap_len);307307+ evlist->mmap[cpu].base = NULL;308308+ }309309+ }310310+ return -1;311311+}312312+313313+static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask)314314+{315315+ struct perf_evsel *evsel;316316+ int thread;317317+318318+ for (thread = 0; thread < evlist->threads->nr; thread++) {319319+ int output = -1;320320+321321+ list_for_each_entry(evsel, &evlist->entries, node) {322322+ int fd = FD(evsel, 0, thread);323323+324324+ if (output == -1) {325325+ output = fd;326326+ if (__perf_evlist__mmap(evlist, evsel, thread,327327+ prot, mask, output) < 0)328328+ goto out_unmap;329329+ } else {330330+ if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)331331+ goto out_unmap;332332+ }333333+334334+ if ((evsel->attr.read_format & PERF_FORMAT_ID) &&335335+ perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0)336336+ goto out_unmap;337337+ }338338+ }339339+340340+ return 0;341341+342342+out_unmap:343343+ for (thread = 0; thread < evlist->threads->nr; thread++) {344344+ if (evlist->mmap[thread].base != NULL) {345345+ munmap(evlist->mmap[thread].base, evlist->mmap_len);346346+ evlist->mmap[thread].base = NULL;347347+ }348348+ }349349+ return -1;276350}277351278352/** perf_evlist__mmap - Create per cpu maps to receive events···373287int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite)374288{375289 unsigned int page_size = sysconf(_SC_PAGE_SIZE);376376- int mask = pages * page_size - 1, cpu;377377- struct perf_evsel *first_evsel, *evsel;290290+ int mask = pages * page_size - 1;291291+ struct perf_evsel *evsel;378292 const struct cpu_map *cpus = evlist->cpus;379293 const struct thread_map *threads = evlist->threads;380380- int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE);294294+ int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE);381295382296 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)383297 return -ENOMEM;···387301388302 evlist->overwrite = overwrite;389303 evlist->mmap_len = (pages + 1) * page_size;390390- first_evsel = list_entry(evlist->entries.next, struct perf_evsel, node);391304392305 list_for_each_entry(evsel, &evlist->entries, node) {393306 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&394307 evsel->sample_id == NULL &&395308 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0)396309 return -ENOMEM;397397-398398- for (cpu = 0; cpu < cpus->nr; cpu++) {399399- for (thread = 0; thread < threads->nr; thread++) {400400- int fd = FD(evsel, cpu, thread);401401-402402- if (evsel->idx || thread) {403403- if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT,404404- FD(first_evsel, cpu, 0)) != 0)405405- goto out_unmap;406406- } else if (__perf_evlist__mmap(evlist, evsel, cpu,407407- prot, mask, fd) < 0)408408- goto out_unmap;409409-410410- if ((evsel->attr.read_format & PERF_FORMAT_ID) &&411411- perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)412412- goto out_unmap;413413- }414414- }415310 }416311417417- return 0;312312+ if (evlist->cpus->map[0] == -1)313313+ return perf_evlist__mmap_per_thread(evlist, prot, mask);418314419419-out_unmap:420420- for (cpu = 0; cpu < cpus->nr; cpu++) {421421- if (evlist->mmap[cpu].base != NULL) {422422- munmap(evlist->mmap[cpu].base, evlist->mmap_len);423423- evlist->mmap[cpu].base = NULL;424424- }425425- }426426- return -1;315315+ return perf_evlist__mmap_per_cpu(evlist, prot, mask);427316}428317429318int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,···409348 if (evlist->threads == NULL)410349 return -1;411350412412- if (target_tid != -1)351351+ if (cpu_list == NULL && target_tid != -1)413352 evlist->cpus = cpu_map__dummy_new();414353 else415354 evlist->cpus = cpu_map__new(cpu_list);
+2-1
tools/perf/util/evlist.h
···1717 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];1818 int nr_entries;1919 int nr_fds;2020+ int nr_mmaps;2021 int mmap_len;2122 bool overwrite;2223 union perf_event event_copy;···47464847struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);49485050-union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *self, int cpu);4949+union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);51505251int perf_evlist__alloc_mmap(struct perf_evlist *evlist);5352int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);