Loading tools/perf/tests/sw-clock.c +14 −4 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) .disabled = 1, .freq = 1, }; struct cpu_map *cpus; struct thread_map *threads; attr.sample_freq = 500; Loading @@ -50,14 +52,19 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) } perf_evlist__add(evlist, evsel); evlist->cpus = cpu_map__dummy_new(); evlist->threads = thread_map__new_by_tid(getpid()); if (!evlist->cpus || !evlist->threads) { cpus = cpu_map__dummy_new(); threads = thread_map__new_by_tid(getpid()); if (!cpus || !threads) { err = -ENOMEM; pr_debug("Not enough memory to create thread/cpu maps\n"); goto out_delete_evlist; goto out_free_maps; } perf_evlist__set_maps(evlist, cpus, threads); cpus = NULL; threads = NULL; if (perf_evlist__open(evlist)) { const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate"; Loading Loading @@ -107,6 +114,9 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) err = -1; } out_free_maps: cpu_map__put(cpus); thread_map__put(threads); out_delete_evlist: perf_evlist__delete(evlist); return err; Loading tools/perf/tests/task-exit.c +14 −4 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ int test__task_exit(void) }; const char *argv[] = { "true", NULL }; char sbuf[STRERR_BUFSIZE]; struct cpu_map *cpus; struct thread_map *threads; signal(SIGCHLD, sig_handler); Loading @@ -58,14 +60,19 @@ int test__task_exit(void) * perf_evlist__prepare_workload we'll fill in the only thread * we're monitoring, the one forked there. */ evlist->cpus = cpu_map__dummy_new(); evlist->threads = thread_map__new_by_tid(-1); if (!evlist->cpus || !evlist->threads) { cpus = cpu_map__dummy_new(); threads = thread_map__new_by_tid(-1); if (!cpus || !threads) { err = -ENOMEM; pr_debug("Not enough memory to create thread/cpu maps\n"); goto out_delete_evlist; goto out_free_maps; } perf_evlist__set_maps(evlist, cpus, threads); cpus = NULL; threads = NULL; err = perf_evlist__prepare_workload(evlist, &target, argv, false, workload_exec_failed_signal); if (err < 0) { Loading Loading @@ -114,6 +121,9 @@ int test__task_exit(void) err = -1; } out_free_maps: cpu_map__put(cpus); thread_map__put(threads); out_delete_evlist: perf_evlist__delete(evlist); return err; Loading tools/perf/ui/browsers/hists.c +11 −1 Original line number Diff line number Diff line Loading @@ -2017,7 +2017,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, &options[nr_options], dso); nr_options += add_map_opt(browser, &actions[nr_options], &options[nr_options], browser->selection->map); browser->selection ? browser->selection->map : NULL); nr_options += add_socket_opt(browser, &actions[nr_options], &options[nr_options], socked_id); Loading @@ -2027,6 +2028,15 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, &actions[nr_options], &options[nr_options], thread, NULL); /* * Note that browser->selection != NULL * when browser->he_selection is not NULL, * so we don't need to check browser->selection * before fetching browser->selection->sym like what * we do before fetching browser->selection->map. * * See hist_browser__show_entry. */ nr_options += add_script_opt(browser, &actions[nr_options], &options[nr_options], Loading tools/perf/util/evlist.c +76 −62 Original line number Diff line number Diff line Loading @@ -125,6 +125,33 @@ void perf_evlist__delete(struct perf_evlist *evlist) free(evlist); } static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, struct perf_evsel *evsel) { /* * We already have cpus for evsel (via PMU sysfs) so * keep it, if there's no target cpu list defined. */ if (!evsel->own_cpus || evlist->has_user_cpus) { cpu_map__put(evsel->cpus); evsel->cpus = cpu_map__get(evlist->cpus); } else if (evsel->cpus != evsel->own_cpus) { cpu_map__put(evsel->cpus); evsel->cpus = cpu_map__get(evsel->own_cpus); } thread_map__put(evsel->threads); evsel->threads = thread_map__get(evlist->threads); } static void perf_evlist__propagate_maps(struct perf_evlist *evlist) { struct perf_evsel *evsel; evlist__for_each(evlist, evsel) __perf_evlist__propagate_maps(evlist, evsel); } void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) { entry->evlist = evlist; Loading @@ -134,18 +161,19 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) if (!evlist->nr_entries++) perf_evlist__set_id_pos(evlist); __perf_evlist__propagate_maps(evlist, entry); } void perf_evlist__splice_list_tail(struct perf_evlist *evlist, struct list_head *list, int nr_entries) struct list_head *list) { bool set_id_pos = !evlist->nr_entries; struct perf_evsel *evsel, *temp; list_splice_tail(list, &evlist->entries); evlist->nr_entries += nr_entries; if (set_id_pos) perf_evlist__set_id_pos(evlist); __evlist__for_each_safe(list, temp, evsel) { list_del_init(&evsel->node); perf_evlist__add(evlist, evsel); } } void __perf_evlist__set_leader(struct list_head *list) Loading Loading @@ -211,7 +239,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist, list_add_tail(&evsel->node, &head); } perf_evlist__splice_list_tail(evlist, &head, nr_attrs); perf_evlist__splice_list_tail(evlist, &head); return 0; Loading Loading @@ -1104,71 +1132,56 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false); } static int perf_evlist__propagate_maps(struct perf_evlist *evlist, bool has_user_cpus) { struct perf_evsel *evsel; evlist__for_each(evlist, evsel) { /* * We already have cpus for evsel (via PMU sysfs) so * keep it, if there's no target cpu list defined. */ if (evsel->cpus && has_user_cpus) cpu_map__put(evsel->cpus); if (!evsel->cpus || has_user_cpus) evsel->cpus = cpu_map__get(evlist->cpus); evsel->threads = thread_map__get(evlist->threads); if ((evlist->cpus && !evsel->cpus) || (evlist->threads && !evsel->threads)) return -ENOMEM; } return 0; } int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) { evlist->threads = thread_map__new_str(target->pid, target->tid, target->uid); struct cpu_map *cpus; struct thread_map *threads; threads = thread_map__new_str(target->pid, target->tid, target->uid); if (evlist->threads == NULL) if (!threads) return -1; if (target__uses_dummy_map(target)) evlist->cpus = cpu_map__dummy_new(); cpus = cpu_map__dummy_new(); else evlist->cpus = cpu_map__new(target->cpu_list); cpus = cpu_map__new(target->cpu_list); if (evlist->cpus == NULL) if (!cpus) goto out_delete_threads; return perf_evlist__propagate_maps(evlist, !!target->cpu_list); evlist->has_user_cpus = !!target->cpu_list; perf_evlist__set_maps(evlist, cpus, threads); return 0; out_delete_threads: thread_map__put(evlist->threads); evlist->threads = NULL; thread_map__put(threads); return -1; } int perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, struct thread_map *threads) { if (evlist->cpus) /* * Allow for the possibility that one or another of the maps isn't being * changed i.e. don't put it. Note we are assuming the maps that are * being applied are brand new and evlist is taking ownership of the * original reference count of 1. If that is not the case it is up to * the caller to increase the reference count. */ if (cpus != evlist->cpus) { cpu_map__put(evlist->cpus); evlist->cpus = cpus; } if (evlist->threads) if (threads != evlist->threads) { thread_map__put(evlist->threads); evlist->threads = threads; } return perf_evlist__propagate_maps(evlist, false); perf_evlist__propagate_maps(evlist); } int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel) Loading Loading @@ -1388,6 +1401,8 @@ void perf_evlist__close(struct perf_evlist *evlist) static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) { struct cpu_map *cpus; struct thread_map *threads; int err = -ENOMEM; /* Loading @@ -1399,20 +1414,19 @@ static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) * error, and we may not want to do that fallback to a * default cpu identity map :-\ */ evlist->cpus = cpu_map__new(NULL); if (evlist->cpus == NULL) cpus = cpu_map__new(NULL); if (!cpus) goto out; evlist->threads = thread_map__new_dummy(); if (evlist->threads == NULL) goto out_free_cpus; threads = thread_map__new_dummy(); if (!threads) goto out_put; err = 0; perf_evlist__set_maps(evlist, cpus, threads); out: return err; out_free_cpus: cpu_map__put(evlist->cpus); evlist->cpus = NULL; out_put: cpu_map__put(cpus); goto out; } Loading tools/perf/util/evlist.h +4 −5 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ struct perf_evlist { int nr_mmaps; bool overwrite; bool enabled; bool has_user_cpus; size_t mmap_len; int id_pos; int is_pos; Loading Loading @@ -155,8 +156,7 @@ int perf_evlist__enable_event_idx(struct perf_evlist *evlist, void perf_evlist__set_selected(struct perf_evlist *evlist, struct perf_evsel *evsel); int perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, struct thread_map *threads); int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel); Loading @@ -179,8 +179,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist); bool perf_evlist__valid_read_format(struct perf_evlist *evlist); void perf_evlist__splice_list_tail(struct perf_evlist *evlist, struct list_head *list, int nr_entries); struct list_head *list); static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) { Loading Loading
tools/perf/tests/sw-clock.c +14 −4 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) .disabled = 1, .freq = 1, }; struct cpu_map *cpus; struct thread_map *threads; attr.sample_freq = 500; Loading @@ -50,14 +52,19 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) } perf_evlist__add(evlist, evsel); evlist->cpus = cpu_map__dummy_new(); evlist->threads = thread_map__new_by_tid(getpid()); if (!evlist->cpus || !evlist->threads) { cpus = cpu_map__dummy_new(); threads = thread_map__new_by_tid(getpid()); if (!cpus || !threads) { err = -ENOMEM; pr_debug("Not enough memory to create thread/cpu maps\n"); goto out_delete_evlist; goto out_free_maps; } perf_evlist__set_maps(evlist, cpus, threads); cpus = NULL; threads = NULL; if (perf_evlist__open(evlist)) { const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate"; Loading Loading @@ -107,6 +114,9 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) err = -1; } out_free_maps: cpu_map__put(cpus); thread_map__put(threads); out_delete_evlist: perf_evlist__delete(evlist); return err; Loading
tools/perf/tests/task-exit.c +14 −4 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ int test__task_exit(void) }; const char *argv[] = { "true", NULL }; char sbuf[STRERR_BUFSIZE]; struct cpu_map *cpus; struct thread_map *threads; signal(SIGCHLD, sig_handler); Loading @@ -58,14 +60,19 @@ int test__task_exit(void) * perf_evlist__prepare_workload we'll fill in the only thread * we're monitoring, the one forked there. */ evlist->cpus = cpu_map__dummy_new(); evlist->threads = thread_map__new_by_tid(-1); if (!evlist->cpus || !evlist->threads) { cpus = cpu_map__dummy_new(); threads = thread_map__new_by_tid(-1); if (!cpus || !threads) { err = -ENOMEM; pr_debug("Not enough memory to create thread/cpu maps\n"); goto out_delete_evlist; goto out_free_maps; } perf_evlist__set_maps(evlist, cpus, threads); cpus = NULL; threads = NULL; err = perf_evlist__prepare_workload(evlist, &target, argv, false, workload_exec_failed_signal); if (err < 0) { Loading Loading @@ -114,6 +121,9 @@ int test__task_exit(void) err = -1; } out_free_maps: cpu_map__put(cpus); thread_map__put(threads); out_delete_evlist: perf_evlist__delete(evlist); return err; Loading
tools/perf/ui/browsers/hists.c +11 −1 Original line number Diff line number Diff line Loading @@ -2017,7 +2017,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, &options[nr_options], dso); nr_options += add_map_opt(browser, &actions[nr_options], &options[nr_options], browser->selection->map); browser->selection ? browser->selection->map : NULL); nr_options += add_socket_opt(browser, &actions[nr_options], &options[nr_options], socked_id); Loading @@ -2027,6 +2028,15 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, &actions[nr_options], &options[nr_options], thread, NULL); /* * Note that browser->selection != NULL * when browser->he_selection is not NULL, * so we don't need to check browser->selection * before fetching browser->selection->sym like what * we do before fetching browser->selection->map. * * See hist_browser__show_entry. */ nr_options += add_script_opt(browser, &actions[nr_options], &options[nr_options], Loading
tools/perf/util/evlist.c +76 −62 Original line number Diff line number Diff line Loading @@ -125,6 +125,33 @@ void perf_evlist__delete(struct perf_evlist *evlist) free(evlist); } static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, struct perf_evsel *evsel) { /* * We already have cpus for evsel (via PMU sysfs) so * keep it, if there's no target cpu list defined. */ if (!evsel->own_cpus || evlist->has_user_cpus) { cpu_map__put(evsel->cpus); evsel->cpus = cpu_map__get(evlist->cpus); } else if (evsel->cpus != evsel->own_cpus) { cpu_map__put(evsel->cpus); evsel->cpus = cpu_map__get(evsel->own_cpus); } thread_map__put(evsel->threads); evsel->threads = thread_map__get(evlist->threads); } static void perf_evlist__propagate_maps(struct perf_evlist *evlist) { struct perf_evsel *evsel; evlist__for_each(evlist, evsel) __perf_evlist__propagate_maps(evlist, evsel); } void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) { entry->evlist = evlist; Loading @@ -134,18 +161,19 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) if (!evlist->nr_entries++) perf_evlist__set_id_pos(evlist); __perf_evlist__propagate_maps(evlist, entry); } void perf_evlist__splice_list_tail(struct perf_evlist *evlist, struct list_head *list, int nr_entries) struct list_head *list) { bool set_id_pos = !evlist->nr_entries; struct perf_evsel *evsel, *temp; list_splice_tail(list, &evlist->entries); evlist->nr_entries += nr_entries; if (set_id_pos) perf_evlist__set_id_pos(evlist); __evlist__for_each_safe(list, temp, evsel) { list_del_init(&evsel->node); perf_evlist__add(evlist, evsel); } } void __perf_evlist__set_leader(struct list_head *list) Loading Loading @@ -211,7 +239,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist, list_add_tail(&evsel->node, &head); } perf_evlist__splice_list_tail(evlist, &head, nr_attrs); perf_evlist__splice_list_tail(evlist, &head); return 0; Loading Loading @@ -1104,71 +1132,56 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false); } static int perf_evlist__propagate_maps(struct perf_evlist *evlist, bool has_user_cpus) { struct perf_evsel *evsel; evlist__for_each(evlist, evsel) { /* * We already have cpus for evsel (via PMU sysfs) so * keep it, if there's no target cpu list defined. */ if (evsel->cpus && has_user_cpus) cpu_map__put(evsel->cpus); if (!evsel->cpus || has_user_cpus) evsel->cpus = cpu_map__get(evlist->cpus); evsel->threads = thread_map__get(evlist->threads); if ((evlist->cpus && !evsel->cpus) || (evlist->threads && !evsel->threads)) return -ENOMEM; } return 0; } int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) { evlist->threads = thread_map__new_str(target->pid, target->tid, target->uid); struct cpu_map *cpus; struct thread_map *threads; threads = thread_map__new_str(target->pid, target->tid, target->uid); if (evlist->threads == NULL) if (!threads) return -1; if (target__uses_dummy_map(target)) evlist->cpus = cpu_map__dummy_new(); cpus = cpu_map__dummy_new(); else evlist->cpus = cpu_map__new(target->cpu_list); cpus = cpu_map__new(target->cpu_list); if (evlist->cpus == NULL) if (!cpus) goto out_delete_threads; return perf_evlist__propagate_maps(evlist, !!target->cpu_list); evlist->has_user_cpus = !!target->cpu_list; perf_evlist__set_maps(evlist, cpus, threads); return 0; out_delete_threads: thread_map__put(evlist->threads); evlist->threads = NULL; thread_map__put(threads); return -1; } int perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, struct thread_map *threads) { if (evlist->cpus) /* * Allow for the possibility that one or another of the maps isn't being * changed i.e. don't put it. Note we are assuming the maps that are * being applied are brand new and evlist is taking ownership of the * original reference count of 1. If that is not the case it is up to * the caller to increase the reference count. */ if (cpus != evlist->cpus) { cpu_map__put(evlist->cpus); evlist->cpus = cpus; } if (evlist->threads) if (threads != evlist->threads) { thread_map__put(evlist->threads); evlist->threads = threads; } return perf_evlist__propagate_maps(evlist, false); perf_evlist__propagate_maps(evlist); } int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel) Loading Loading @@ -1388,6 +1401,8 @@ void perf_evlist__close(struct perf_evlist *evlist) static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) { struct cpu_map *cpus; struct thread_map *threads; int err = -ENOMEM; /* Loading @@ -1399,20 +1414,19 @@ static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) * error, and we may not want to do that fallback to a * default cpu identity map :-\ */ evlist->cpus = cpu_map__new(NULL); if (evlist->cpus == NULL) cpus = cpu_map__new(NULL); if (!cpus) goto out; evlist->threads = thread_map__new_dummy(); if (evlist->threads == NULL) goto out_free_cpus; threads = thread_map__new_dummy(); if (!threads) goto out_put; err = 0; perf_evlist__set_maps(evlist, cpus, threads); out: return err; out_free_cpus: cpu_map__put(evlist->cpus); evlist->cpus = NULL; out_put: cpu_map__put(cpus); goto out; } Loading
tools/perf/util/evlist.h +4 −5 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ struct perf_evlist { int nr_mmaps; bool overwrite; bool enabled; bool has_user_cpus; size_t mmap_len; int id_pos; int is_pos; Loading Loading @@ -155,8 +156,7 @@ int perf_evlist__enable_event_idx(struct perf_evlist *evlist, void perf_evlist__set_selected(struct perf_evlist *evlist, struct perf_evsel *evsel); int perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, struct thread_map *threads); int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel); Loading @@ -179,8 +179,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist); bool perf_evlist__valid_read_format(struct perf_evlist *evlist); void perf_evlist__splice_list_tail(struct perf_evlist *evlist, struct list_head *list, int nr_entries); struct list_head *list); static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) { Loading