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

perf dsos: Introduce dsos__for_each_dso()

To better abstract the dsos internals, introduce dsos__for_each_dso that
does a callback on each dso.

This also means the read lock can be correctly held.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Anne Macedo <retpolanne@posteo.net>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ben Gainey <ben.gainey@arm.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Chengen Du <chengen.du@canonical.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Li Dong <lidong@vivo.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Markus Elfring <Markus.Elfring@web.de>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paran Lee <p4ranlee@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Song Liu <song@kernel.org>
Cc: Sun Haiyong <sunhaiyong@loongson.cn>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Cc: Yanteng Si <siyanteng@loongson.cn>
Cc: Yicong Yang <yangyicong@hisilicon.com>
Cc: zhaimingbing <zhaimingbing@cmss.chinamobile.com>
Link: https://lore.kernel.org/r/20240410064214.2755936-4-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
73f3fea2 f649ed80

+103 -68
+15 -10
tools/perf/builtin-inject.c
··· 1187 1187 process_build_id, machine); 1188 1188 } 1189 1189 1190 + static int guest_session__add_build_ids_cb(struct dso *dso, void *data) 1191 + { 1192 + struct guest_session *gs = data; 1193 + struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session); 1194 + 1195 + if (!dso->has_build_id) 1196 + return 0; 1197 + 1198 + return synthesize_build_id(inject, dso, gs->machine_pid); 1199 + 1200 + } 1201 + 1190 1202 static int guest_session__add_build_ids(struct guest_session *gs) 1191 1203 { 1192 1204 struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session); 1193 - struct machine *machine = &gs->session->machines.host; 1194 - struct dso *dso; 1195 - int ret; 1196 1205 1197 1206 /* Build IDs will be put in the Build ID feature section */ 1198 1207 perf_header__set_feat(&inject->session->header, HEADER_BUILD_ID); 1199 1208 1200 - dsos__for_each_with_build_id(dso, &machine->dsos.head) { 1201 - ret = synthesize_build_id(inject, dso, gs->machine_pid); 1202 - if (ret) 1203 - return ret; 1204 - } 1205 - 1206 - return 0; 1209 + return dsos__for_each_dso(&gs->session->machines.host.dsos, 1210 + guest_session__add_build_ids_cb, 1211 + gs); 1207 1212 } 1208 1213 1209 1214 static int guest_session__ksymbol_event(struct perf_tool *tool,
+45 -37
tools/perf/util/build-id.c
··· 327 327 return write_padded(fd, name, name_len + 1, len); 328 328 } 329 329 330 - static int machine__write_buildid_table(struct machine *machine, 331 - struct feat_fd *fd) 330 + struct machine__write_buildid_table_cb_args { 331 + struct machine *machine; 332 + struct feat_fd *fd; 333 + u16 kmisc, umisc; 334 + }; 335 + 336 + static int machine__write_buildid_table_cb(struct dso *dso, void *data) 332 337 { 333 - int err = 0; 334 - struct dso *pos; 335 - u16 kmisc = PERF_RECORD_MISC_KERNEL, 336 - umisc = PERF_RECORD_MISC_USER; 338 + struct machine__write_buildid_table_cb_args *args = data; 339 + const char *name; 340 + size_t name_len; 341 + bool in_kernel = false; 342 + 343 + if (!dso->has_build_id) 344 + return 0; 345 + 346 + if (!dso->hit && !dso__is_vdso(dso)) 347 + return 0; 348 + 349 + if (dso__is_vdso(dso)) { 350 + name = dso->short_name; 351 + name_len = dso->short_name_len; 352 + } else if (dso__is_kcore(dso)) { 353 + name = args->machine->mmap_name; 354 + name_len = strlen(name); 355 + } else { 356 + name = dso->long_name; 357 + name_len = dso->long_name_len; 358 + } 359 + 360 + in_kernel = dso->kernel || is_kernel_module(name, PERF_RECORD_MISC_CPUMODE_UNKNOWN); 361 + return write_buildid(name, name_len, &dso->bid, args->machine->pid, 362 + in_kernel ? args->kmisc : args->umisc, args->fd); 363 + } 364 + 365 + static int machine__write_buildid_table(struct machine *machine, struct feat_fd *fd) 366 + { 367 + struct machine__write_buildid_table_cb_args args = { 368 + .machine = machine, 369 + .fd = fd, 370 + .kmisc = PERF_RECORD_MISC_KERNEL, 371 + .umisc = PERF_RECORD_MISC_USER, 372 + }; 337 373 338 374 if (!machine__is_host(machine)) { 339 - kmisc = PERF_RECORD_MISC_GUEST_KERNEL; 340 - umisc = PERF_RECORD_MISC_GUEST_USER; 375 + args.kmisc = PERF_RECORD_MISC_GUEST_KERNEL; 376 + args.umisc = PERF_RECORD_MISC_GUEST_USER; 341 377 } 342 378 343 - dsos__for_each_with_build_id(pos, &machine->dsos.head) { 344 - const char *name; 345 - size_t name_len; 346 - bool in_kernel = false; 347 - 348 - if (!pos->hit && !dso__is_vdso(pos)) 349 - continue; 350 - 351 - if (dso__is_vdso(pos)) { 352 - name = pos->short_name; 353 - name_len = pos->short_name_len; 354 - } else if (dso__is_kcore(pos)) { 355 - name = machine->mmap_name; 356 - name_len = strlen(name); 357 - } else { 358 - name = pos->long_name; 359 - name_len = pos->long_name_len; 360 - } 361 - 362 - in_kernel = pos->kernel || 363 - is_kernel_module(name, 364 - PERF_RECORD_MISC_CPUMODE_UNKNOWN); 365 - err = write_buildid(name, name_len, &pos->bid, machine->pid, 366 - in_kernel ? kmisc : umisc, fd); 367 - if (err) 368 - break; 369 - } 370 - 371 - return err; 379 + return dsos__for_each_dso(&machine->dsos, machine__write_buildid_table_cb, &args); 372 380 } 373 381 374 382 int perf_session__write_buildid_table(struct perf_session *session,
+16
tools/perf/util/dsos.c
··· 433 433 up_read(&dsos->lock); 434 434 return res; 435 435 } 436 + 437 + int dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data) 438 + { 439 + struct dso *dso; 440 + 441 + down_read(&dsos->lock); 442 + list_for_each_entry(dso, &dsos->head, node) { 443 + int err; 444 + 445 + err = cb(dso, data); 446 + if (err) 447 + return err; 448 + } 449 + up_read(&dsos->lock); 450 + return 0; 451 + }
+2 -6
tools/perf/util/dsos.h
··· 23 23 struct rw_semaphore lock; 24 24 }; 25 25 26 - #define dsos__for_each_with_build_id(pos, head) \ 27 - list_for_each_entry(pos, head, node) \ 28 - if (!pos->has_build_id) \ 29 - continue; \ 30 - else 31 - 32 26 void dsos__init(struct dsos *dsos); 33 27 void dsos__exit(struct dsos *dsos); 34 28 ··· 48 54 struct kmod_path *m, const char *filename); 49 55 50 56 struct dso *dsos__find_kernel_dso(struct dsos *dsos); 57 + 58 + int dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data); 51 59 52 60 #endif /* __PERF_DSOS */
+25 -15
tools/perf/util/machine.c
··· 1562 1562 return ret; 1563 1563 } 1564 1564 1565 + static int machine__uses_kcore_cb(struct dso *dso, void *data __maybe_unused) 1566 + { 1567 + return dso__is_kcore(dso) ? 1 : 0; 1568 + } 1569 + 1565 1570 static bool machine__uses_kcore(struct machine *machine) 1566 1571 { 1567 - struct dso *dso; 1568 - 1569 - list_for_each_entry(dso, &machine->dsos.head, node) { 1570 - if (dso__is_kcore(dso)) 1571 - return true; 1572 - } 1573 - 1574 - return false; 1572 + return dsos__for_each_dso(&machine->dsos, machine__uses_kcore_cb, NULL) != 0 ? true : false; 1575 1573 } 1576 1574 1577 1575 static bool perf_event__is_extra_kernel_mmap(struct machine *machine, ··· 3135 3137 return sym->name; 3136 3138 } 3137 3139 3140 + struct machine__for_each_dso_cb_args { 3141 + struct machine *machine; 3142 + machine__dso_t fn; 3143 + void *priv; 3144 + }; 3145 + 3146 + static int machine__for_each_dso_cb(struct dso *dso, void *data) 3147 + { 3148 + struct machine__for_each_dso_cb_args *args = data; 3149 + 3150 + return args->fn(dso, args->machine, args->priv); 3151 + } 3152 + 3138 3153 int machine__for_each_dso(struct machine *machine, machine__dso_t fn, void *priv) 3139 3154 { 3140 - struct dso *pos; 3141 - int err = 0; 3155 + struct machine__for_each_dso_cb_args args = { 3156 + .machine = machine, 3157 + .fn = fn, 3158 + .priv = priv, 3159 + }; 3142 3160 3143 - list_for_each_entry(pos, &machine->dsos.head, node) { 3144 - if (fn(pos, machine, priv)) 3145 - err = -1; 3146 - } 3147 - return err; 3161 + return dsos__for_each_dso(&machine->dsos, machine__for_each_dso_cb, &args); 3148 3162 } 3149 3163 3150 3164 int machine__for_each_kernel_map(struct machine *machine, machine__map_t fn, void *priv)