Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'perf/urgent' into perf/core, to resolve a conflict

Conflicts:
tools/perf/ui/browsers/hists.c

Signed-off-by: Ingo Molnar <mingo@kernel.org>

+126 -82
+14 -4
tools/perf/tests/sw-clock.c
··· 34 34 .disabled = 1, 35 35 .freq = 1, 36 36 }; 37 + struct cpu_map *cpus; 38 + struct thread_map *threads; 37 39 38 40 attr.sample_freq = 500; 39 41 ··· 52 50 } 53 51 perf_evlist__add(evlist, evsel); 54 52 55 - evlist->cpus = cpu_map__dummy_new(); 56 - evlist->threads = thread_map__new_by_tid(getpid()); 57 - if (!evlist->cpus || !evlist->threads) { 53 + cpus = cpu_map__dummy_new(); 54 + threads = thread_map__new_by_tid(getpid()); 55 + if (!cpus || !threads) { 58 56 err = -ENOMEM; 59 57 pr_debug("Not enough memory to create thread/cpu maps\n"); 60 - goto out_delete_evlist; 58 + goto out_free_maps; 61 59 } 60 + 61 + perf_evlist__set_maps(evlist, cpus, threads); 62 + 63 + cpus = NULL; 64 + threads = NULL; 62 65 63 66 if (perf_evlist__open(evlist)) { 64 67 const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate"; ··· 114 107 err = -1; 115 108 } 116 109 110 + out_free_maps: 111 + cpu_map__put(cpus); 112 + thread_map__put(threads); 117 113 out_delete_evlist: 118 114 perf_evlist__delete(evlist); 119 115 return err;
+14 -4
tools/perf/tests/task-exit.c
··· 43 43 }; 44 44 const char *argv[] = { "true", NULL }; 45 45 char sbuf[STRERR_BUFSIZE]; 46 + struct cpu_map *cpus; 47 + struct thread_map *threads; 46 48 47 49 signal(SIGCHLD, sig_handler); 48 50 ··· 60 58 * perf_evlist__prepare_workload we'll fill in the only thread 61 59 * we're monitoring, the one forked there. 62 60 */ 63 - evlist->cpus = cpu_map__dummy_new(); 64 - evlist->threads = thread_map__new_by_tid(-1); 65 - if (!evlist->cpus || !evlist->threads) { 61 + cpus = cpu_map__dummy_new(); 62 + threads = thread_map__new_by_tid(-1); 63 + if (!cpus || !threads) { 66 64 err = -ENOMEM; 67 65 pr_debug("Not enough memory to create thread/cpu maps\n"); 68 - goto out_delete_evlist; 66 + goto out_free_maps; 69 67 } 68 + 69 + perf_evlist__set_maps(evlist, cpus, threads); 70 + 71 + cpus = NULL; 72 + threads = NULL; 70 73 71 74 err = perf_evlist__prepare_workload(evlist, &target, argv, false, 72 75 workload_exec_failed_signal); ··· 121 114 err = -1; 122 115 } 123 116 117 + out_free_maps: 118 + cpu_map__put(cpus); 119 + thread_map__put(threads); 124 120 out_delete_evlist: 125 121 perf_evlist__delete(evlist); 126 122 return err;
+11 -1
tools/perf/ui/browsers/hists.c
··· 2017 2017 &options[nr_options], dso); 2018 2018 nr_options += add_map_opt(browser, &actions[nr_options], 2019 2019 &options[nr_options], 2020 - browser->selection->map); 2020 + browser->selection ? 2021 + browser->selection->map : NULL); 2021 2022 nr_options += add_socket_opt(browser, &actions[nr_options], 2022 2023 &options[nr_options], 2023 2024 socked_id); ··· 2028 2027 &actions[nr_options], 2029 2028 &options[nr_options], 2030 2029 thread, NULL); 2030 + /* 2031 + * Note that browser->selection != NULL 2032 + * when browser->he_selection is not NULL, 2033 + * so we don't need to check browser->selection 2034 + * before fetching browser->selection->sym like what 2035 + * we do before fetching browser->selection->map. 2036 + * 2037 + * See hist_browser__show_entry. 2038 + */ 2031 2039 nr_options += add_script_opt(browser, 2032 2040 &actions[nr_options], 2033 2041 &options[nr_options],
+76 -62
tools/perf/util/evlist.c
··· 125 125 free(evlist); 126 126 } 127 127 128 + static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, 129 + struct perf_evsel *evsel) 130 + { 131 + /* 132 + * We already have cpus for evsel (via PMU sysfs) so 133 + * keep it, if there's no target cpu list defined. 134 + */ 135 + if (!evsel->own_cpus || evlist->has_user_cpus) { 136 + cpu_map__put(evsel->cpus); 137 + evsel->cpus = cpu_map__get(evlist->cpus); 138 + } else if (evsel->cpus != evsel->own_cpus) { 139 + cpu_map__put(evsel->cpus); 140 + evsel->cpus = cpu_map__get(evsel->own_cpus); 141 + } 142 + 143 + thread_map__put(evsel->threads); 144 + evsel->threads = thread_map__get(evlist->threads); 145 + } 146 + 147 + static void perf_evlist__propagate_maps(struct perf_evlist *evlist) 148 + { 149 + struct perf_evsel *evsel; 150 + 151 + evlist__for_each(evlist, evsel) 152 + __perf_evlist__propagate_maps(evlist, evsel); 153 + } 154 + 128 155 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) 129 156 { 130 157 entry->evlist = evlist; ··· 161 134 162 135 if (!evlist->nr_entries++) 163 136 perf_evlist__set_id_pos(evlist); 137 + 138 + __perf_evlist__propagate_maps(evlist, entry); 164 139 } 165 140 166 141 void perf_evlist__splice_list_tail(struct perf_evlist *evlist, 167 - struct list_head *list, 168 - int nr_entries) 142 + struct list_head *list) 169 143 { 170 - bool set_id_pos = !evlist->nr_entries; 144 + struct perf_evsel *evsel, *temp; 171 145 172 - list_splice_tail(list, &evlist->entries); 173 - evlist->nr_entries += nr_entries; 174 - if (set_id_pos) 175 - perf_evlist__set_id_pos(evlist); 146 + __evlist__for_each_safe(list, temp, evsel) { 147 + list_del_init(&evsel->node); 148 + perf_evlist__add(evlist, evsel); 149 + } 176 150 } 177 151 178 152 void __perf_evlist__set_leader(struct list_head *list) ··· 239 211 list_add_tail(&evsel->node, &head); 240 212 } 241 213 242 - perf_evlist__splice_list_tail(evlist, &head, nr_attrs); 214 + perf_evlist__splice_list_tail(evlist, &head); 243 215 244 216 return 0; 245 217 ··· 1132 1104 return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false); 1133 1105 } 1134 1106 1135 - static int perf_evlist__propagate_maps(struct perf_evlist *evlist, 1136 - bool has_user_cpus) 1137 - { 1138 - struct perf_evsel *evsel; 1139 - 1140 - evlist__for_each(evlist, evsel) { 1141 - /* 1142 - * We already have cpus for evsel (via PMU sysfs) so 1143 - * keep it, if there's no target cpu list defined. 1144 - */ 1145 - if (evsel->cpus && has_user_cpus) 1146 - cpu_map__put(evsel->cpus); 1147 - 1148 - if (!evsel->cpus || has_user_cpus) 1149 - evsel->cpus = cpu_map__get(evlist->cpus); 1150 - 1151 - evsel->threads = thread_map__get(evlist->threads); 1152 - 1153 - if ((evlist->cpus && !evsel->cpus) || 1154 - (evlist->threads && !evsel->threads)) 1155 - return -ENOMEM; 1156 - } 1157 - 1158 - return 0; 1159 - } 1160 - 1161 1107 int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) 1162 1108 { 1163 - evlist->threads = thread_map__new_str(target->pid, target->tid, 1164 - target->uid); 1109 + struct cpu_map *cpus; 1110 + struct thread_map *threads; 1165 1111 1166 - if (evlist->threads == NULL) 1112 + threads = thread_map__new_str(target->pid, target->tid, target->uid); 1113 + 1114 + if (!threads) 1167 1115 return -1; 1168 1116 1169 1117 if (target__uses_dummy_map(target)) 1170 - evlist->cpus = cpu_map__dummy_new(); 1118 + cpus = cpu_map__dummy_new(); 1171 1119 else 1172 - evlist->cpus = cpu_map__new(target->cpu_list); 1120 + cpus = cpu_map__new(target->cpu_list); 1173 1121 1174 - if (evlist->cpus == NULL) 1122 + if (!cpus) 1175 1123 goto out_delete_threads; 1176 1124 1177 - return perf_evlist__propagate_maps(evlist, !!target->cpu_list); 1125 + evlist->has_user_cpus = !!target->cpu_list; 1126 + 1127 + perf_evlist__set_maps(evlist, cpus, threads); 1128 + 1129 + return 0; 1178 1130 1179 1131 out_delete_threads: 1180 - thread_map__put(evlist->threads); 1181 - evlist->threads = NULL; 1132 + thread_map__put(threads); 1182 1133 return -1; 1183 1134 } 1184 1135 1185 - int perf_evlist__set_maps(struct perf_evlist *evlist, 1186 - struct cpu_map *cpus, 1187 - struct thread_map *threads) 1136 + void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, 1137 + struct thread_map *threads) 1188 1138 { 1189 - if (evlist->cpus) 1139 + /* 1140 + * Allow for the possibility that one or another of the maps isn't being 1141 + * changed i.e. don't put it. Note we are assuming the maps that are 1142 + * being applied are brand new and evlist is taking ownership of the 1143 + * original reference count of 1. If that is not the case it is up to 1144 + * the caller to increase the reference count. 1145 + */ 1146 + if (cpus != evlist->cpus) { 1190 1147 cpu_map__put(evlist->cpus); 1148 + evlist->cpus = cpus; 1149 + } 1191 1150 1192 - evlist->cpus = cpus; 1193 - 1194 - if (evlist->threads) 1151 + if (threads != evlist->threads) { 1195 1152 thread_map__put(evlist->threads); 1153 + evlist->threads = threads; 1154 + } 1196 1155 1197 - evlist->threads = threads; 1198 - 1199 - return perf_evlist__propagate_maps(evlist, false); 1156 + perf_evlist__propagate_maps(evlist); 1200 1157 } 1201 1158 1202 1159 int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel) ··· 1401 1388 1402 1389 static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) 1403 1390 { 1391 + struct cpu_map *cpus; 1392 + struct thread_map *threads; 1404 1393 int err = -ENOMEM; 1405 1394 1406 1395 /* ··· 1414 1399 * error, and we may not want to do that fallback to a 1415 1400 * default cpu identity map :-\ 1416 1401 */ 1417 - evlist->cpus = cpu_map__new(NULL); 1418 - if (evlist->cpus == NULL) 1402 + cpus = cpu_map__new(NULL); 1403 + if (!cpus) 1419 1404 goto out; 1420 1405 1421 - evlist->threads = thread_map__new_dummy(); 1422 - if (evlist->threads == NULL) 1423 - goto out_free_cpus; 1406 + threads = thread_map__new_dummy(); 1407 + if (!threads) 1408 + goto out_put; 1424 1409 1425 - err = 0; 1410 + perf_evlist__set_maps(evlist, cpus, threads); 1426 1411 out: 1427 1412 return err; 1428 - out_free_cpus: 1429 - cpu_map__put(evlist->cpus); 1430 - evlist->cpus = NULL; 1413 + out_put: 1414 + cpu_map__put(cpus); 1431 1415 goto out; 1432 1416 } 1433 1417
+4 -5
tools/perf/util/evlist.h
··· 42 42 int nr_mmaps; 43 43 bool overwrite; 44 44 bool enabled; 45 + bool has_user_cpus; 45 46 size_t mmap_len; 46 47 int id_pos; 47 48 int is_pos; ··· 156 155 void perf_evlist__set_selected(struct perf_evlist *evlist, 157 156 struct perf_evsel *evsel); 158 157 159 - int perf_evlist__set_maps(struct perf_evlist *evlist, 160 - struct cpu_map *cpus, 161 - struct thread_map *threads); 158 + void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, 159 + struct thread_map *threads); 162 160 int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); 163 161 int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel); 164 162 ··· 179 179 bool perf_evlist__valid_read_format(struct perf_evlist *evlist); 180 180 181 181 void perf_evlist__splice_list_tail(struct perf_evlist *evlist, 182 - struct list_head *list, 183 - int nr_entries); 182 + struct list_head *list); 184 183 185 184 static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) 186 185 {
+1
tools/perf/util/evsel.c
··· 1043 1043 perf_evsel__free_config_terms(evsel); 1044 1044 close_cgroup(evsel->cgrp); 1045 1045 cpu_map__put(evsel->cpus); 1046 + cpu_map__put(evsel->own_cpus); 1046 1047 thread_map__put(evsel->threads); 1047 1048 zfree(&evsel->group_name); 1048 1049 zfree(&evsel->name);
+1
tools/perf/util/evsel.h
··· 98 98 struct cgroup_sel *cgrp; 99 99 void *handler; 100 100 struct cpu_map *cpus; 101 + struct cpu_map *own_cpus; 101 102 struct thread_map *threads; 102 103 unsigned int sample_size; 103 104 int id_pos;
+2 -2
tools/perf/util/header.c
··· 1431 1431 if (ph->needs_swap) 1432 1432 nr = bswap_32(nr); 1433 1433 1434 - ph->env.nr_cpus_online = nr; 1434 + ph->env.nr_cpus_avail = nr; 1435 1435 1436 1436 ret = readn(fd, &nr, sizeof(nr)); 1437 1437 if (ret != sizeof(nr)) ··· 1440 1440 if (ph->needs_swap) 1441 1441 nr = bswap_32(nr); 1442 1442 1443 - ph->env.nr_cpus_avail = nr; 1443 + ph->env.nr_cpus_online = nr; 1444 1444 return 0; 1445 1445 } 1446 1446
+3 -4
tools/perf/util/parse-events.c
··· 288 288 if (!evsel) 289 289 return NULL; 290 290 291 - if (cpus) 292 - evsel->cpus = cpu_map__get(cpus); 291 + evsel->cpus = cpu_map__get(cpus); 292 + evsel->own_cpus = cpu_map__get(cpus); 293 293 294 294 if (name) 295 295 evsel->name = strdup(name); ··· 1174 1174 ret = parse_events__scanner(str, &data, PE_START_EVENTS); 1175 1175 perf_pmu__parse_cleanup(); 1176 1176 if (!ret) { 1177 - int entries = data.idx - evlist->nr_entries; 1178 1177 struct perf_evsel *last; 1179 1178 1180 - perf_evlist__splice_list_tail(evlist, &data.list, entries); 1179 + perf_evlist__splice_list_tail(evlist, &data.list); 1181 1180 evlist->nr_groups += data.nr_groups; 1182 1181 last = perf_evlist__last(evlist); 1183 1182 last->cmdline_group_boundary = true;