From nobody Sat Nov 30 10:50:54 2024 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3D24018B477 for ; Mon, 9 Sep 2024 20:37:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725914272; cv=none; b=OEbx2kgUFvVwlMfQlBR2dYxUemEhdqPvYJrGG4IPHo9O+u3wTsSyiolmVwyVSzZ46PGbDt3OUrnBHGgs6TIvVsTlcSaCogrtfDL5+H4+4QBa8aMn5+qKQJ4mX3EEylf25y9unhnZ9vGjRbnUlB8wluQMwDxDl1O/hkokVweoyks= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725914272; c=relaxed/simple; bh=eHJGHN9ZgfSRD5mYwKtP3gfcwoonvdu8rY9fnz8dm6I=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=G+IFCDP/LMFYEsBuzGprMNWzU/ZBjQ2LbRKWTPjclK6fZ1ps5i3gcbiEmeJ9U7QGbLaMIVJ4T7F9o2CZqASH9FtDRbH0SqDGp0X+W6EVLFZFAXM7dKQha8oWOtxuG5om/N2XQ9ivAl/wJqX40sEA/2h4L4vMMk9UBKw4towtdlQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=o5CjpmER; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="o5CjpmER" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e1d46cee0b0so4536733276.2 for ; Mon, 09 Sep 2024 13:37:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1725914269; x=1726519069; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=riE2Y5T5o1PrdK09V4CHcR+iYujERLclBkWQoR+wdM8=; b=o5CjpmERJauWo5qdhqf+OMHDqK82YMgMwVCtwbs1JOWSuEvHsahREbnenc0z/o+lej tgZDSjDgDQG7zj9P284t/WK24xew1SGYACC2WDkWk2rIU1S6BNatbWs7WjUj3BgWRg6U /+6/i+MkI5WTSMfm1mFKSzUIoMvzp1IfGGh274DCSrK3SKoTdY4Fzchb6H9SOnOVRHyj WhyBrmhRc7GDim6vSdqZMyztO8d7FAA12h/9w/IQbEBp27gn8CRalKdnLJiBTzoEwZrR 7xYEV4EeYz4pPhZqiYbrT3sdkANktYAipqOlRH3ncbF8FZIDFE8iP7imYMXTLxuPMBML niVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725914269; x=1726519069; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=riE2Y5T5o1PrdK09V4CHcR+iYujERLclBkWQoR+wdM8=; b=FpM0D78K6IVomapObm5AckVuQwn01salR3H8Hjjx6psy2DR4UHkahQJm+ScWGf9XhG WdjlINnvME0hJoSspx0O58CJem8fPvPfhCC5il3x2QzWpXeTSA9e/L1c0boZlIxH7MGz UcwaJE17Uf3DfjQsiVTzZBV1OH4JnRbkGMFpkoag3fR366CR5mpQ8FefDyrRiQu/JBuj unhDglazoXw5XXIlTMqw11CORC942ST282zBjZPwKzRBRE/mfAi+4Q4jUxId6EXqqbuF BGQ82Dhkk2ngLGcktyzgrF7eZ2oqJ1v6IxCR965KbY53Wlarj9zWW5wgWFEwhKAKo2lz TJgw== X-Forwarded-Encrypted: i=1; AJvYcCWNc5P4pNkLjnA1IYudnTLOdQal4a5h4aSAycTsUeOMwoHaxrLkjTDFylRcCTkDwTymYozQggXXFCJQ5jg=@vger.kernel.org X-Gm-Message-State: AOJu0YzR3JfiYs5d/xeUtobv4vW+8GZYoycoyBqiNExcN9+Pz85I3y6D YxBwnbOSFbgUiaLmVS/cjtVx9/fV66fFSDpR5W1e1NXeK/bbop8Zw3RJiRF/n/yj2NWbfduiE3k 8ynaDYA== X-Google-Smtp-Source: AGHT+IFw0v/ERsDoQPrmRfi2lZR9SLEXkvKbz5hWc62/lKRxJULkEExCOOiC1kLbivngwG7zCyAiIKtjDHLk X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:b7b9:f9a0:1197:ff33]) (user=irogers job=sendgmr) by 2002:a05:6902:2d43:b0:dfa:8ed1:8f1b with SMTP id 3f1490d57ef6-e1d34864d44mr21429276.1.1725914269332; Mon, 09 Sep 2024 13:37:49 -0700 (PDT) Date: Mon, 9 Sep 2024 13:37:37 -0700 In-Reply-To: <20240909203740.143492-1-irogers@google.com> Message-Id: <20240909203740.143492-2-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240909203740.143492-1-irogers@google.com> X-Mailer: git-send-email 2.46.0.598.g6f2099f65c-goog Subject: [PATCH v2 1/4] perf inject: Fix build ID injection From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Colin Ian King , Casey Chen , Anne Macedo , Sun Haiyong , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Build ID injection wasn't inserting a sample ID and aligning events to 64 bytes rather than 8. No sample ID means events are unordered and two different build_id events for the same path, as happens when a file is replaced, can't be differentiated. Add in sample ID insertion for the build_id events alongside some refactoring. The refactoring better aligns the function arguments for different use cases, such as synthesizing build_id events without needing to have a dso. The misc bits are explicitly passed as with callchains the maps/dsos may span user and kernel land, so using sample->cpumode isn't good enough. Acked-by: Namhyung Kim Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 170 ++++++++++++++++++++++------- tools/perf/util/build-id.c | 6 +- tools/perf/util/synthetic-events.c | 44 ++++++-- tools/perf/util/synthetic-events.h | 10 +- 4 files changed, 175 insertions(+), 55 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 0ccf80fe8399..24470c57527d 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -130,6 +130,7 @@ struct perf_inject { struct perf_file_section secs[HEADER_FEAT_BITS]; struct guest_session guest_session; struct strlist *known_build_ids; + const struct evsel *mmap_evsel; }; =20 struct event_entry { @@ -138,8 +139,13 @@ struct event_entry { union perf_event event[]; }; =20 -static int dso__inject_build_id(struct dso *dso, const struct perf_tool *t= ool, - struct machine *machine, u8 cpumode, u32 flags); +static int tool__inject_build_id(const struct perf_tool *tool, + struct perf_sample *sample, + struct machine *machine, + const struct evsel *evsel, + __u16 misc, + const char *filename, + struct dso *dso, u32 flags); =20 static int output_bytes(struct perf_inject *inject, void *buf, size_t sz) { @@ -422,6 +428,28 @@ static struct dso *findnew_dso(int pid, int tid, const= char *filename, return dso; } =20 +/* + * The evsel used for the sample ID for mmap events. Typically stashed when + * processing mmap events. If not stashed, search the evlist for the first= mmap + * gathering event. + */ +static const struct evsel *inject__mmap_evsel(struct perf_inject *inject) +{ + struct evsel *pos; + + if (inject->mmap_evsel) + return inject->mmap_evsel; + + evlist__for_each_entry(inject->session->evlist, pos) { + if (pos->core.attr.mmap) { + inject->mmap_evsel =3D pos; + return pos; + } + } + pr_err("No mmap events found\n"); + return NULL; +} + static int perf_event__repipe_common_mmap(const struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -469,12 +497,28 @@ static int perf_event__repipe_common_mmap(const struc= t perf_tool *tool, } =20 if (dso && !dso__hit(dso)) { - dso__set_hit(dso); - dso__inject_build_id(dso, tool, machine, sample->cpumode, flags); + struct evsel *evsel =3D evlist__event2evsel(inject->session->evlist, ev= ent); + + if (evsel) { + dso__set_hit(dso); + tool__inject_build_id(tool, sample, machine, evsel, + /*misc=3D*/sample->cpumode, + filename, dso, flags); + } } } else { + int err; + + /* + * Remember the evsel for lazy build id generation. It is used + * for the sample id header type. + */ + if (inject->build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY && + !inject->mmap_evsel) + inject->mmap_evsel =3D evlist__event2evsel(inject->session->evlist, eve= nt); + /* Create the thread, map, etc. Not done for the unordered inject all ca= se. */ - int err =3D perf_event_process(tool, event, sample, machine); + err =3D perf_event_process(tool, event, sample, machine); =20 if (err) { dso__put(dso); @@ -667,16 +711,20 @@ static bool perf_inject__lookup_known_build_id(struct= perf_inject *inject, return false; } =20 -static int dso__inject_build_id(struct dso *dso, const struct perf_tool *t= ool, - struct machine *machine, u8 cpumode, u32 flags) +static int tool__inject_build_id(const struct perf_tool *tool, + struct perf_sample *sample, + struct machine *machine, + const struct evsel *evsel, + __u16 misc, + const char *filename, + struct dso *dso, u32 flags) { - struct perf_inject *inject =3D container_of(tool, struct perf_inject, - tool); + struct perf_inject *inject =3D container_of(tool, struct perf_inject, too= l); int err; =20 - if (is_anon_memory(dso__long_name(dso)) || flags & MAP_HUGETLB) + if (is_anon_memory(filename) || flags & MAP_HUGETLB) return 0; - if (is_no_dso_memory(dso__long_name(dso))) + if (is_no_dso_memory(filename)) return 0; =20 if (inject->known_build_ids !=3D NULL && @@ -684,24 +732,65 @@ static int dso__inject_build_id(struct dso *dso, cons= t struct perf_tool *tool, return 1; =20 if (dso__read_build_id(dso) < 0) { - pr_debug("no build_id found for %s\n", dso__long_name(dso)); + pr_debug("no build_id found for %s\n", filename); return -1; } =20 - err =3D perf_event__synthesize_build_id(tool, dso, cpumode, - perf_event__repipe, machine); + err =3D perf_event__synthesize_build_id(tool, sample, machine, + perf_event__repipe, + evsel, misc, dso__bid(dso), + filename); if (err) { - pr_err("Can't synthesize build_id event for %s\n", dso__long_name(dso)); + pr_err("Can't synthesize build_id event for %s\n", filename); return -1; } =20 return 0; } =20 +static int mark_dso_hit(const struct perf_tool *tool, + struct perf_sample *sample, + struct machine *machine, + const struct evsel *mmap_evsel, + struct map *map, bool sample_in_dso) +{ + struct dso *dso; + u16 misc =3D sample->cpumode; + + if (!map) + return 0; + + if (!sample_in_dso) { + u16 guest_mask =3D PERF_RECORD_MISC_GUEST_KERNEL | + PERF_RECORD_MISC_GUEST_USER; + + if ((misc & guest_mask) !=3D 0) { + misc &=3D PERF_RECORD_MISC_HYPERVISOR; + misc |=3D __map__is_kernel(map) + ? PERF_RECORD_MISC_GUEST_KERNEL + : PERF_RECORD_MISC_GUEST_USER; + } else { + misc &=3D PERF_RECORD_MISC_HYPERVISOR; + misc |=3D __map__is_kernel(map) + ? PERF_RECORD_MISC_KERNEL + : PERF_RECORD_MISC_USER; + } + } + dso =3D map__dso(map); + if (dso && !dso__hit(dso)) { + dso__set_hit(dso); + tool__inject_build_id(tool, sample, machine, + mmap_evsel, misc, dso__long_name(dso), dso, + map__flags(map)); + } + return 0; +} + struct mark_dso_hit_args { const struct perf_tool *tool; + struct perf_sample *sample; struct machine *machine; - u8 cpumode; + const struct evsel *mmap_evsel; }; =20 static int mark_dso_hit_callback(struct callchain_cursor_node *node, void = *data) @@ -709,16 +798,8 @@ static int mark_dso_hit_callback(struct callchain_curs= or_node *node, void *data) struct mark_dso_hit_args *args =3D data; struct map *map =3D node->ms.map; =20 - if (map) { - struct dso *dso =3D map__dso(map); - - if (dso && !dso__hit(dso)) { - dso__set_hit(dso); - dso__inject_build_id(dso, args->tool, args->machine, - args->cpumode, map__flags(map)); - } - } - return 0; + return mark_dso_hit(args->tool, args->sample, args->machine, + args->mmap_evsel, map, /*sample_in_dso=3D*/false); } =20 int perf_event__inject_buildid(const struct perf_tool *tool, union perf_ev= ent *event, @@ -728,10 +809,16 @@ int perf_event__inject_buildid(const struct perf_tool= *tool, union perf_event *e { struct addr_location al; struct thread *thread; + struct perf_inject *inject =3D container_of(tool, struct perf_inject, too= l); struct mark_dso_hit_args args =3D { .tool =3D tool, + /* + * Use the parsed sample data of the sample event, which will + * have a later timestamp than the mmap event. + */ + .sample =3D sample, .machine =3D machine, - .cpumode =3D sample->cpumode, + .mmap_evsel =3D inject__mmap_evsel(inject), }; =20 addr_location__init(&al); @@ -743,13 +830,8 @@ int perf_event__inject_buildid(const struct perf_tool = *tool, union perf_event *e } =20 if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) { - struct dso *dso =3D map__dso(al.map); - - if (!dso__hit(dso)) { - dso__set_hit(dso); - dso__inject_build_id(dso, tool, machine, - sample->cpumode, map__flags(al.map)); - } + mark_dso_hit(tool, sample, machine, args.mmap_evsel, al.map, + /*sample_in_dso=3D*/true); } =20 sample__for_each_callchain_node(thread, evsel, sample, PERF_MAX_STACK_DEP= TH, @@ -1159,17 +1241,27 @@ static int process_build_id(const struct perf_tool = *tool, static int synthesize_build_id(struct perf_inject *inject, struct dso *dso= , pid_t machine_pid) { struct machine *machine =3D perf_session__findnew_machine(inject->session= , machine_pid); - u8 cpumode =3D dso__is_in_kernel_space(dso) ? - PERF_RECORD_MISC_GUEST_KERNEL : - PERF_RECORD_MISC_GUEST_USER; + struct perf_sample synth_sample =3D { + .pid =3D -1, + .tid =3D -1, + .time =3D -1, + .stream_id =3D -1, + .cpu =3D -1, + .period =3D 1, + .cpumode =3D dso__is_in_kernel_space(dso) + ? PERF_RECORD_MISC_GUEST_KERNEL + : PERF_RECORD_MISC_GUEST_USER, + }; =20 if (!machine) return -ENOMEM; =20 dso__set_hit(dso); =20 - return perf_event__synthesize_build_id(&inject->tool, dso, cpumode, - process_build_id, machine); + return perf_event__synthesize_build_id(&inject->tool, &synth_sample, mach= ine, + process_build_id, inject__mmap_evsel(inject), + /*misc=3D*/synth_sample.cpumode, + dso__bid(dso), dso__long_name(dso)); } =20 static int guest_session__add_build_ids_cb(struct dso *dso, void *data) diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 451d145fa4ed..8982f68e7230 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -277,8 +277,8 @@ static int write_buildid(const char *name, size_t name_= len, struct build_id *bid struct perf_record_header_build_id b; size_t len; =20 - len =3D name_len + 1; - len =3D PERF_ALIGN(len, NAME_ALIGN); + len =3D sizeof(b) + name_len + 1; + len =3D PERF_ALIGN(len, sizeof(u64)); =20 memset(&b, 0, sizeof(b)); memcpy(&b.data, bid->data, bid->size); @@ -286,7 +286,7 @@ static int write_buildid(const char *name, size_t name_= len, struct build_id *bid misc |=3D PERF_RECORD_MISC_BUILD_ID_SIZE; b.pid =3D pid; b.header.misc =3D misc; - b.header.size =3D sizeof(b) + len; + b.header.size =3D len; =20 err =3D do_write(fd, &b, sizeof(b)); if (err < 0) diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index 0a7f93ae76fb..6bb62e4e2d5d 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -2225,28 +2225,48 @@ int perf_event__synthesize_tracing_data(const struc= t perf_tool *tool, int fd, st } #endif =20 -int perf_event__synthesize_build_id(const struct perf_tool *tool, struct d= so *pos, u16 misc, - perf_event__handler_t process, struct machine *machine) +int perf_event__synthesize_build_id(const struct perf_tool *tool, + struct perf_sample *sample, + struct machine *machine, + perf_event__handler_t process, + const struct evsel *evsel, + __u16 misc, + const struct build_id *bid, + const char *filename) { union perf_event ev; size_t len; =20 - if (!dso__hit(pos)) - return 0; + len =3D sizeof(ev.build_id) + strlen(filename) + 1; + len =3D PERF_ALIGN(len, sizeof(u64)); =20 - memset(&ev, 0, sizeof(ev)); + memset(&ev, 0, len); =20 - len =3D dso__long_name_len(pos) + 1; - len =3D PERF_ALIGN(len, NAME_ALIGN); - ev.build_id.size =3D min(dso__bid(pos)->size, sizeof(dso__bid(pos)->data)= ); - memcpy(&ev.build_id.build_id, dso__bid(pos)->data, ev.build_id.size); + ev.build_id.size =3D min(bid->size, sizeof(ev.build_id.build_id)); + memcpy(ev.build_id.build_id, bid->data, ev.build_id.size); ev.build_id.header.type =3D PERF_RECORD_HEADER_BUILD_ID; ev.build_id.header.misc =3D misc | PERF_RECORD_MISC_BUILD_ID_SIZE; ev.build_id.pid =3D machine->pid; - ev.build_id.header.size =3D sizeof(ev.build_id) + len; - memcpy(&ev.build_id.filename, dso__long_name(pos), dso__long_name_len(pos= )); + ev.build_id.header.size =3D len; + strcpy(ev.build_id.filename, filename); + + if (evsel) { + void *array =3D &ev; + int ret; =20 - return process(tool, &ev, NULL, machine); + array +=3D ev.header.size; + ret =3D perf_event__synthesize_id_sample(array, evsel->core.attr.sample_= type, sample); + if (ret < 0) + return ret; + + if (ret & 7) { + pr_err("Bad id sample size %d\n", ret); + return -EINVAL; + } + + ev.header.size +=3D ret; + } + return process(tool, &ev, sample, machine); } =20 int perf_event__synthesize_stat_events(struct perf_stat_config *config, co= nst struct perf_tool *tool, diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic= -events.h index 31df7653677f..795bf3e18396 100644 --- a/tools/perf/util/synthetic-events.h +++ b/tools/perf/util/synthetic-events.h @@ -9,6 +9,7 @@ #include =20 struct auxtrace_record; +struct build_id; struct dso; struct evlist; struct evsel; @@ -45,7 +46,14 @@ typedef int (*perf_event__handler_t)(const struct perf_t= ool *tool, union perf_ev =20 int perf_event__synthesize_attrs(const struct perf_tool *tool, struct evli= st *evlist, perf_event__handler_t process); int perf_event__synthesize_attr(const struct perf_tool *tool, struct perf_= event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process); -int perf_event__synthesize_build_id(const struct perf_tool *tool, struct d= so *pos, u16 misc, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_build_id(const struct perf_tool *tool, + struct perf_sample *sample, + struct machine *machine, + perf_event__handler_t process, + const struct evsel *evsel, + __u16 misc, + const struct build_id *bid, + const char *filename); int perf_event__synthesize_cpu_map(const struct perf_tool *tool, const str= uct perf_cpu_map *cpus, perf_event__handler_t process, struct machine *mach= ine); int perf_event__synthesize_event_update_cpus(const struct perf_tool *tool,= struct evsel *evsel, perf_event__handler_t process); int perf_event__synthesize_event_update_name(const struct perf_tool *tool,= struct evsel *evsel, perf_event__handler_t process); --=20 2.46.0.598.g6f2099f65c-goog From nobody Sat Nov 30 10:50:54 2024 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D785E18A93F for ; Mon, 9 Sep 2024 20:37:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725914274; cv=none; b=d+f1TgqG927KQk5Vw33WVW0hzezXcaccARQQJfEYHFPpQD+ZcSXMRGKp4m2HQnf9s+ENyshfdoScozKxR86pnPYapADfMCtSH/KZnd87QsJEHkegmP4emGz8oGM2/Z7CpErh3Hz6UqjgmbZ20Ncuv/jH1mpj7MS2c27YriTyW0g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725914274; c=relaxed/simple; bh=Clp56WWuXS/PFSTUhYjihAny4rJ1a82Jl6raVIJiC88=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=KDkEYMNlKvBLCrX09SzCSV4uzNltJ9ooVc3NXWd+24A4tYMKtSg9gOYePLQn+dkNVAMa0sIci/9s4kEGRhufVa4N3RAsdNH3q57pqfpVust0m1MsYSqCPIHzg8dqNKxKjmilb+Yy7lbMfxQ10Xf0NLwnfaFuwG8VQzm/6SuHV+c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=NhywGSBZ; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="NhywGSBZ" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e1a8de19944so11112813276.1 for ; Mon, 09 Sep 2024 13:37:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1725914272; x=1726519072; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=seNNgOYd+yOyVPoC1OLWCPYg4+Zlk5hIs7OYJde/eng=; b=NhywGSBZGfFlhp8sYIzXaLo0YN4GWh/E2oTU2lznCdtmADelD8s2S7IsO5/g+VHzZ7 y7MZOHJO6coLdwmT7xNtml5WLuGixAAYHnlrZ+Ex6zCQUT4zg0WfAl2x5U5u5IoU9sQd QQ3pfn4/CU/atY0m/PIteuqpwSv/GzsdD0Khn5PvqvJf4H7Jj3HAwtVD9uDmBJ4iUpSY wpOtAACtnLZck6aHO2V1xEhLGvG12mVnln+eDdmW1N1RGDDmL+STJ5QavC1mRV3QtYhy BwcIUMTJZLeHYmZO0ptv5r56TOobcKurZ99GL7MmYCFrPzgcgqCEKNPqzPydHUPxZRy7 F4Pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725914272; x=1726519072; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=seNNgOYd+yOyVPoC1OLWCPYg4+Zlk5hIs7OYJde/eng=; b=gqPup5XvhbF7XnTpJ3SbSx6X2JX7HiiVMpY8HoTbk0l4/pdSb6fivXqx6q0ur6Znc4 MO0zavc7qkEJz386pDgkFtLRxyAev2pzIN1rXhi0HmjMQgyljn8reNjYFO+3joh173+g nkWIv6pqDlA3hn/OOCmshIh7JCzS7jFsRKvNXE+hUr6J5qQz8uB8MUfrlsQVyPx7Lwfz OBYJbzWeQ5Kj1tkSVzIA4tBM9iD0Q+RaRLvzz13N/Qnb7knUviYd00bW3ftWID13vSp4 HbDciPYb8zmNs91CvvfaEvJhee4b5f9znB8wJkuwXX6ugOx+ip/AkJxn9NdV7Okx7uts 7WCw== X-Forwarded-Encrypted: i=1; AJvYcCVM0U+gN0kuckP7FCT4g1BhbEegmbzLhnAXBj2xJVdcABNCuwTO/zpRZCBE7R5PIkV8JKuK8V9XTEmuVM0=@vger.kernel.org X-Gm-Message-State: AOJu0YwReRtt1ZJkRhO1uvK6sNSjGQNXx01X+vrd/bxs//ac8wesdS7Q v7Y4Jls+kkq7NNNj1caDRx5guPtqBYSZu74C2/MyA1WBHdc1mUfYLu6XV95URuXrRkzcpm0JWWi 4MthcEA== X-Google-Smtp-Source: AGHT+IFRBqcIA/UKEfCNHcx4yJDQCt0HfpV4MJhN7slNa5TRF1tb1g+qjA9LwMlX6igzKJbD8DS0ZpMxkUpD X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:b7b9:f9a0:1197:ff33]) (user=irogers job=sendgmr) by 2002:a25:d884:0:b0:e11:5807:1072 with SMTP id 3f1490d57ef6-e1d34a32110mr21878276.8.1725914271660; Mon, 09 Sep 2024 13:37:51 -0700 (PDT) Date: Mon, 9 Sep 2024 13:37:38 -0700 In-Reply-To: <20240909203740.143492-1-irogers@google.com> Message-Id: <20240909203740.143492-3-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240909203740.143492-1-irogers@google.com> X-Mailer: git-send-email 2.46.0.598.g6f2099f65c-goog Subject: [PATCH v2 2/4] perf inject: Add new mmap2-buildid-all option From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Colin Ian King , Casey Chen , Anne Macedo , Sun Haiyong , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add an option that allows all mmap or mmap2 events to be rewritten as mmap2 events with build IDs. This is similar to the existing -b/--build-ids and --buildid-all options except instead of adding a build_id event an existing mmap/mmap2 event is used as a template and a new mmap2 event synthesized from it. As mmap2 events are typical this avoids the insertion of build_id events. Add test coverage to the pipe test. Acked-by: Namhyung Kim Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 88 ++++++++++++++++++++++++++++- tools/perf/tests/shell/pipe_test.sh | 1 + tools/perf/util/synthetic-events.c | 57 +++++++++++++++++++ tools/perf/util/synthetic-events.h | 11 ++++ 4 files changed, 154 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 24470c57527d..5a27fa46e93d 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -107,6 +107,7 @@ enum build_id_rewrite_style { BID_RWS__NONE =3D 0, BID_RWS__INJECT_HEADER_LAZY, BID_RWS__INJECT_HEADER_ALL, + BID_RWS__MMAP2_BUILDID_ALL, }; =20 struct perf_inject { @@ -146,6 +147,16 @@ static int tool__inject_build_id(const struct perf_too= l *tool, __u16 misc, const char *filename, struct dso *dso, u32 flags); +static int tool__inject_mmap2_build_id(const struct perf_tool *tool, + struct perf_sample *sample, + struct machine *machine, + const struct evsel *evsel, + __u16 misc, + __u32 pid, __u32 tid, + __u64 start, __u64 len, __u64 pgoff, + struct dso *dso, + __u32 prot, __u32 flags, + const char *filename); =20 static int output_bytes(struct perf_inject *inject, void *buf, size_t sz) { @@ -161,6 +172,7 @@ static int output_bytes(struct perf_inject *inject, voi= d *buf, size_t sz) =20 static int perf_event__repipe_synth(const struct perf_tool *tool, union perf_event *event) + { struct perf_inject *inject =3D container_of(tool, struct perf_inject, tool); @@ -454,7 +466,9 @@ static int perf_event__repipe_common_mmap(const struct = perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine, - __u32 pid, __u32 tid, __u32 flags, + __u32 pid, __u32 tid, + __u64 start, __u64 len, __u64 pgoff, + __u32 flags, __u32 prot, const char *filename, const struct dso_id *dso_id, int (*perf_event_process)(const struct perf_tool *tool, @@ -525,6 +539,26 @@ static int perf_event__repipe_common_mmap(const struct= perf_tool *tool, return err; } } + if ((inject->build_id_style =3D=3D BID_RWS__MMAP2_BUILDID_ALL) && + !(event->header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)) { + struct evsel *evsel =3D evlist__event2evsel(inject->session->evlist, eve= nt); + + if (evsel && !dso_sought) { + dso =3D findnew_dso(pid, tid, filename, dso_id, machine); + dso_sought =3D true; + } + if (evsel && dso && + !tool__inject_mmap2_build_id(tool, sample, machine, evsel, + sample->cpumode | PERF_RECORD_MISC_MMAP_BUILD_ID, + pid, tid, start, len, pgoff, + dso, + prot, flags, + filename)) { + /* Injected mmap2 so no need to repipe. */ + dso__put(dso); + return 0; + } + } dso__put(dso); return perf_event__repipe(tool, event, sample, machine); } @@ -536,7 +570,9 @@ static int perf_event__repipe_mmap(const struct perf_to= ol *tool, { return perf_event__repipe_common_mmap( tool, event, sample, machine, - event->mmap.pid, event->mmap.tid, /*flags=3D*/0, + event->mmap.pid, event->mmap.tid, + event->mmap.start, event->mmap.len, event->mmap.pgoff, + /*flags=3D*/0, PROT_EXEC, event->mmap.filename, /*dso_id=3D*/NULL, perf_event__process_mmap); } @@ -559,7 +595,9 @@ static int perf_event__repipe_mmap2(const struct perf_t= ool *tool, =20 return perf_event__repipe_common_mmap( tool, event, sample, machine, - event->mmap2.pid, event->mmap2.tid, event->mmap2.flags, + event->mmap2.pid, event->mmap2.tid, + event->mmap2.start, event->mmap2.len, event->mmap2.pgoff, + event->mmap2.flags, event->mmap2.prot, event->mmap2.filename, dso_id, perf_event__process_mmap2); } @@ -748,6 +786,45 @@ static int tool__inject_build_id(const struct perf_too= l *tool, return 0; } =20 +static int tool__inject_mmap2_build_id(const struct perf_tool *tool, + struct perf_sample *sample, + struct machine *machine, + const struct evsel *evsel, + __u16 misc, + __u32 pid, __u32 tid, + __u64 start, __u64 len, __u64 pgoff, + struct dso *dso, + __u32 prot, __u32 flags, + const char *filename) +{ + int err; + + /* Return to repipe anonymous maps. */ + if (is_anon_memory(filename) || flags & MAP_HUGETLB) + return 1; + if (is_no_dso_memory(filename)) + return 1; + + if (dso__read_build_id(dso)) { + pr_debug("no build_id found for %s\n", filename); + return -1; + } + + err =3D perf_event__synthesize_mmap2_build_id(tool, sample, machine, + perf_event__repipe, + evsel, + misc, pid, tid, + start, len, pgoff, + dso__bid(dso), + prot, flags, + filename); + if (err) { + pr_err("Can't synthesize build_id event for %s\n", filename); + return -1; + } + return 0; +} + static int mark_dso_hit(const struct perf_tool *tool, struct perf_sample *sample, struct machine *machine, @@ -2261,12 +2338,15 @@ int cmd_inject(int argc, const char **argv) const char *known_build_ids =3D NULL; bool build_ids; bool build_id_all; + bool mmap2_build_id_all; =20 struct option options[] =3D { OPT_BOOLEAN('b', "build-ids", &build_ids, "Inject build-ids into the output stream"), OPT_BOOLEAN(0, "buildid-all", &build_id_all, "Inject build-ids of all DSOs into the output stream"), + OPT_BOOLEAN(0, "mmap2-buildid-all", &mmap2_build_id_all, + "Rewrite all mmap events as mmap2 events with build IDs"), OPT_STRING(0, "known-build-ids", &known_build_ids, "buildid path [,buildid path...]", "build-ids to use for given paths"), @@ -2363,6 +2443,8 @@ int cmd_inject(int argc, const char **argv) return -1; } } + if (mmap2_build_id_all) + inject.build_id_style =3D BID_RWS__MMAP2_BUILDID_ALL; if (build_ids) inject.build_id_style =3D BID_RWS__INJECT_HEADER_LAZY; if (build_id_all) diff --git a/tools/perf/tests/shell/pipe_test.sh b/tools/perf/tests/shell/p= ipe_test.sh index a3c94b4182c2..250574cd68b6 100755 --- a/tools/perf/tests/shell/pipe_test.sh +++ b/tools/perf/tests/shell/pipe_test.sh @@ -118,6 +118,7 @@ test_inject_bids() { test_record_report test_inject_bids -b test_inject_bids --buildid-all +test_inject_bids --mmap2-buildid-all =20 cleanup exit $err diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index 6bb62e4e2d5d..a58444c4aed1 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -2266,6 +2266,63 @@ int perf_event__synthesize_build_id(const struct per= f_tool *tool, =20 ev.header.size +=3D ret; } + + return process(tool, &ev, sample, machine); +} + +int perf_event__synthesize_mmap2_build_id(const struct perf_tool *tool, + struct perf_sample *sample, + struct machine *machine, + perf_event__handler_t process, + const struct evsel *evsel, + __u16 misc, + __u32 pid, __u32 tid, + __u64 start, __u64 len, __u64 pgoff, + const struct build_id *bid, + __u32 prot, __u32 flags, + const char *filename) +{ + union perf_event ev; + size_t ev_len; + void *array; + int ret; + + ev_len =3D sizeof(ev.mmap2) - sizeof(ev.mmap2.filename) + strlen(filename= ) + 1; + ev_len =3D PERF_ALIGN(ev_len, sizeof(u64)); + + memset(&ev, 0, ev_len); + + ev.mmap2.header.type =3D PERF_RECORD_MMAP2; + ev.mmap2.header.misc =3D misc | PERF_RECORD_MISC_MMAP_BUILD_ID; + ev.mmap2.header.size =3D ev_len; + + ev.mmap2.pid =3D pid; + ev.mmap2.tid =3D tid; + ev.mmap2.start =3D start; + ev.mmap2.len =3D len; + ev.mmap2.pgoff =3D pgoff; + + ev.mmap2.build_id_size =3D min(bid->size, sizeof(ev.mmap2.build_id)); + memcpy(ev.mmap2.build_id, bid->data, ev.mmap2.build_id_size); + + ev.mmap2.prot =3D prot; + ev.mmap2.flags =3D flags; + + memcpy(ev.mmap2.filename, filename, min(strlen(filename), sizeof(ev.mmap.= filename))); + + array =3D &ev; + array +=3D ev.header.size; + ret =3D perf_event__synthesize_id_sample(array, evsel->core.attr.sample_t= ype, sample); + if (ret < 0) + return ret; + + if (ret & 7) { + pr_err("Bad id sample size %d\n", ret); + return -EINVAL; + } + + ev.header.size +=3D ret; + return process(tool, &ev, sample, machine); } =20 diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic= -events.h index 795bf3e18396..b9c936b5cfeb 100644 --- a/tools/perf/util/synthetic-events.h +++ b/tools/perf/util/synthetic-events.h @@ -54,6 +54,17 @@ int perf_event__synthesize_build_id(const struct perf_to= ol *tool, __u16 misc, const struct build_id *bid, const char *filename); +int perf_event__synthesize_mmap2_build_id(const struct perf_tool *tool, + struct perf_sample *sample, + struct machine *machine, + perf_event__handler_t process, + const struct evsel *evsel, + __u16 misc, + __u32 pid, __u32 tid, + __u64 start, __u64 len, __u64 pgoff, + const struct build_id *bid, + __u32 prot, __u32 flags, + const char *filename); int perf_event__synthesize_cpu_map(const struct perf_tool *tool, const str= uct perf_cpu_map *cpus, perf_event__handler_t process, struct machine *mach= ine); int perf_event__synthesize_event_update_cpus(const struct perf_tool *tool,= struct evsel *evsel, perf_event__handler_t process); int perf_event__synthesize_event_update_name(const struct perf_tool *tool,= struct evsel *evsel, perf_event__handler_t process); --=20 2.46.0.598.g6f2099f65c-goog From nobody Sat Nov 30 10:50:54 2024 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2595B18A959 for ; Mon, 9 Sep 2024 20:37:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725914276; cv=none; b=PcWC8Vr9WCn0QYXtaBhnVDrIFv2yfBfQ/CAbxaOF6tc8x9egXOJy7zLpPb+O/rMFxOWOPOAAaaCDfG8jySZm4iw5Ko3dR1bvNb0LBG6meAUlwxAKOPbJs1PoJGPrY180fSBkdxrAO0YDlmco+2q0XIf8dNmcARfY8lk8e51a/J0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725914276; c=relaxed/simple; bh=D+SSmFc5FfPdhU1r5UpCS2rCSL+zyGVRvs36nBFGJa4=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=oskDIdN9sNiNYJfMTV8gA6So8Ueil+ss89wK/WpMqvgeReUx0M6vhpaJQ36oaEOqzBe5p2WyzzuEnkczdrrW9BRJbcCB6OtuD/hxy0rXDfpUfDyev9A4gPRl/bWuaYHuJdNdzMRQ5N2sIdjyUG56UpiTFj6/uUiBPYMNFCFPWpo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=L5lw3rU9; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="L5lw3rU9" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e1a7ef9eb78so9746463276.3 for ; Mon, 09 Sep 2024 13:37:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1725914274; x=1726519074; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=vkNhK/smhh6RQk8jhHd3svFqj+E5OE7Int+5C0aR36c=; b=L5lw3rU996PibW3QpFtfvbwF6rZe/LLjPMakBJ7VZ/H8xGQJL/eF+/2rLZBLh4buXh Lh0rAGt8Ov8fqueNArZob+gi5uEX7cwdt61xwO7A/3I3pXWsbWR2O52rC5Q0cQUSHUEI xVmYKTyB0xkWkhVSP7nebW1zlAVliOljQC7Sh/BIYHbRV+zr5OTGTTx6Js8ykMiKJ1VG TIjyccvfpdE114nbDg+h+tPirHk6sK73uLBlqSzoBdLPkFM1QcLgLUS3+Z9Pdki6qx5f VDJ8vBw6k3B5Iel20GMUzvUf7T9kIIWKdN7QBiz0Itr8vhlxiry2R6pMltCWsco3E0h3 RfaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725914274; x=1726519074; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=vkNhK/smhh6RQk8jhHd3svFqj+E5OE7Int+5C0aR36c=; b=WH0OCOOceL9KnYOn0SXFLtX9LinsevAtkWbH4omAwa9CtGxw/DBhtaruB7lTKEXVxV /ZGI0mzIx45/hD2nXJUNS5EiuxJTN5UV6EukZ4b4iunWqysXsptfgWb8rGaCUykw4KZI JtBBqV5H5gb2XYlSax+1B5KrHrExIN3WKHIOXtZ5128YpTiUNJzei1PJyJF5M1Vx/uzx 9xrp58+oR8EMvfuskWcNd/3O43ocmcw4sZiMcewfoH9lt8sjqbQS6dNMsksgJdRkyOeo IRbdpzC+RhXA4orYVnGXG5Fc9zwAqtAbRgjsR5rzFm3EZbcFTjn1Vs3hr5y59ZdVims/ +Dyg== X-Forwarded-Encrypted: i=1; AJvYcCWu1UvRS94HsvLvVEtm+ZcK0yWuqFZqcHbtvDL5f7HhRXHfL6JUHNYk4qu3ZSpg7uB78rQDiLPhgrXjIsw=@vger.kernel.org X-Gm-Message-State: AOJu0Yzo5VgH/vI4Vp6NSNpkLqAGHw+dwSE1v+rCGIaBWSCZ2V7Q2zWB FvrCGd/NIGhZO5K0Ds8YoyCgFD6oRNUwo68eAK1wJRHCiZ2p/rhy1qBagNqdW9Q7HhEo6iYiVms txZODrw== X-Google-Smtp-Source: AGHT+IE4dvakATehXxGZD6jo95hQzfhx9BPhrQMVrXB21IOBzBpx6KVswv3eo/qQKzfxY5V7aZAXv0V+NPbz X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:b7b9:f9a0:1197:ff33]) (user=irogers job=sendgmr) by 2002:a25:d347:0:b0:e16:51f9:59da with SMTP id 3f1490d57ef6-e1d349e2dd5mr32365276.6.1725914274226; Mon, 09 Sep 2024 13:37:54 -0700 (PDT) Date: Mon, 9 Sep 2024 13:37:39 -0700 In-Reply-To: <20240909203740.143492-1-irogers@google.com> Message-Id: <20240909203740.143492-4-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240909203740.143492-1-irogers@google.com> X-Mailer: git-send-email 2.46.0.598.g6f2099f65c-goog Subject: [PATCH v2 3/4] perf inject: Lazy build-id mmap2 event insertion From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Colin Ian King , Casey Chen , Anne Macedo , Sun Haiyong , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add -B option that lazily inserts mmap2 events thereby dropping all mmap events without samples. This is similar to the behavior of -b where only build_id events are inserted when a dso is accessed in a sample. File size savings can be significant in system-wide mode, consider: ``` $ perf record -g -a -o perf.data sleep 1 $ perf inject -B -i perf.data -o perf.new.data $ ls -al perf.data perf.new.data 5147049 perf.data 2248493 perf.new.data ``` Give test coverage of the new option in pipe test. Acked-by: Namhyung Kim Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 62 +++++++++++++++++++++++------ tools/perf/tests/shell/pipe_test.sh | 1 + tools/perf/util/map.c | 1 + tools/perf/util/map.h | 11 +++++ 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 5a27fa46e93d..9eb72ff48d88 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -108,6 +108,7 @@ enum build_id_rewrite_style { BID_RWS__INJECT_HEADER_LAZY, BID_RWS__INJECT_HEADER_ALL, BID_RWS__MMAP2_BUILDID_ALL, + BID_RWS__MMAP2_BUILDID_LAZY, }; =20 struct perf_inject { @@ -527,7 +528,8 @@ static int perf_event__repipe_common_mmap(const struct = perf_tool *tool, * Remember the evsel for lazy build id generation. It is used * for the sample id header type. */ - if (inject->build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY && + if ((inject->build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY || + inject->build_id_style =3D=3D BID_RWS__MMAP2_BUILDID_LAZY) && !inject->mmap_evsel) inject->mmap_evsel =3D evlist__event2evsel(inject->session->evlist, eve= nt); =20 @@ -560,6 +562,9 @@ static int perf_event__repipe_common_mmap(const struct = perf_tool *tool, } } dso__put(dso); + if (inject->build_id_style =3D=3D BID_RWS__MMAP2_BUILDID_LAZY) + return 0; + return perf_event__repipe(tool, event, sample, machine); } =20 @@ -825,7 +830,8 @@ static int tool__inject_mmap2_build_id(const struct per= f_tool *tool, return 0; } =20 -static int mark_dso_hit(const struct perf_tool *tool, +static int mark_dso_hit(const struct perf_inject *inject, + const struct perf_tool *tool, struct perf_sample *sample, struct machine *machine, const struct evsel *mmap_evsel, @@ -854,16 +860,39 @@ static int mark_dso_hit(const struct perf_tool *tool, } } dso =3D map__dso(map); - if (dso && !dso__hit(dso)) { - dso__set_hit(dso); - tool__inject_build_id(tool, sample, machine, - mmap_evsel, misc, dso__long_name(dso), dso, - map__flags(map)); + if (inject->build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY) { + if (dso && !dso__hit(dso)) { + dso__set_hit(dso); + tool__inject_build_id(tool, sample, machine, + mmap_evsel, misc, dso__long_name(dso), dso, + map__flags(map)); + } + } else if (inject->build_id_style =3D=3D BID_RWS__MMAP2_BUILDID_LAZY) { + if (!map__hit(map)) { + const struct build_id null_bid =3D { .size =3D 0 }; + const struct build_id *bid =3D dso ? dso__bid(dso) : &null_bid; + const char *filename =3D dso ? dso__long_name(dso) : ""; + + map__set_hit(map); + perf_event__synthesize_mmap2_build_id(tool, sample, machine, + perf_event__repipe, + mmap_evsel, + misc, + sample->pid, sample->tid, + map__start(map), + map__end(map) - map__start(map), + map__pgoff(map), + bid, + map__prot(map), + map__flags(map), + filename); + } } return 0; } =20 struct mark_dso_hit_args { + const struct perf_inject *inject; const struct perf_tool *tool; struct perf_sample *sample; struct machine *machine; @@ -875,7 +904,7 @@ static int mark_dso_hit_callback(struct callchain_curso= r_node *node, void *data) struct mark_dso_hit_args *args =3D data; struct map *map =3D node->ms.map; =20 - return mark_dso_hit(args->tool, args->sample, args->machine, + return mark_dso_hit(args->inject, args->tool, args->sample, args->machine, args->mmap_evsel, map, /*sample_in_dso=3D*/false); } =20 @@ -888,6 +917,7 @@ int perf_event__inject_buildid(const struct perf_tool *= tool, union perf_event *e struct thread *thread; struct perf_inject *inject =3D container_of(tool, struct perf_inject, too= l); struct mark_dso_hit_args args =3D { + .inject =3D inject, .tool =3D tool, /* * Use the parsed sample data of the sample event, which will @@ -907,7 +937,7 @@ int perf_event__inject_buildid(const struct perf_tool *= tool, union perf_event *e } =20 if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) { - mark_dso_hit(tool, sample, machine, args.mmap_evsel, al.map, + mark_dso_hit(inject, tool, sample, machine, args.mmap_evsel, al.map, /*sample_in_dso=3D*/true); } =20 @@ -2155,7 +2185,8 @@ static int __cmd_inject(struct perf_inject *inject) #endif } =20 - if (inject->build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY) { + if (inject->build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY || + inject->build_id_style =3D=3D BID_RWS__MMAP2_BUILDID_LAZY) { inject->tool.sample =3D perf_event__inject_buildid; } else if (inject->sched_stat) { struct evsel *evsel; @@ -2338,6 +2369,7 @@ int cmd_inject(int argc, const char **argv) const char *known_build_ids =3D NULL; bool build_ids; bool build_id_all; + bool mmap2_build_ids; bool mmap2_build_id_all; =20 struct option options[] =3D { @@ -2345,6 +2377,8 @@ int cmd_inject(int argc, const char **argv) "Inject build-ids into the output stream"), OPT_BOOLEAN(0, "buildid-all", &build_id_all, "Inject build-ids of all DSOs into the output stream"), + OPT_BOOLEAN('B', "mmap2-buildids", &mmap2_build_ids, + "Drop unused mmap events, make others mmap2 with build IDs"), OPT_BOOLEAN(0, "mmap2-buildid-all", &mmap2_build_id_all, "Rewrite all mmap events as mmap2 events with build IDs"), OPT_STRING(0, "known-build-ids", &known_build_ids, @@ -2443,6 +2477,8 @@ int cmd_inject(int argc, const char **argv) return -1; } } + if (mmap2_build_ids) + inject.build_id_style =3D BID_RWS__MMAP2_BUILDID_LAZY; if (mmap2_build_id_all) inject.build_id_style =3D BID_RWS__MMAP2_BUILDID_ALL; if (build_ids) @@ -2453,7 +2489,8 @@ int cmd_inject(int argc, const char **argv) data.path =3D inject.input_name; =20 ordered_events =3D inject.jit_mode || inject.sched_stat || - (inject.build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY); + inject.build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY || + inject.build_id_style =3D=3D BID_RWS__MMAP2_BUILDID_LAZY; perf_tool__init(&inject.tool, ordered_events); inject.tool.sample =3D perf_event__repipe_sample; inject.tool.read =3D perf_event__repipe_sample; @@ -2532,7 +2569,8 @@ int cmd_inject(int argc, const char **argv) } } =20 - if (inject.build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY) { + if (inject.build_id_style =3D=3D BID_RWS__INJECT_HEADER_LAZY || + inject.build_id_style =3D=3D BID_RWS__MMAP2_BUILDID_LAZY) { /* * to make sure the mmap records are ordered correctly * and so that the correct especially due to jitted code diff --git a/tools/perf/tests/shell/pipe_test.sh b/tools/perf/tests/shell/p= ipe_test.sh index 250574cd68b6..d4c8005ce9b9 100755 --- a/tools/perf/tests/shell/pipe_test.sh +++ b/tools/perf/tests/shell/pipe_test.sh @@ -116,6 +116,7 @@ test_inject_bids() { } =20 test_record_report +test_inject_bids -B test_inject_bids -b test_inject_bids --buildid-all test_inject_bids --mmap2-buildid-all diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index e781c8d56a9a..d729438b7d65 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -116,6 +116,7 @@ static void map__init(struct map *map, u64 start, u64 e= nd, u64 pgoff, map__set_mapping_type(map, MAPPING_TYPE__DSO); assert(map__erange_warned(map) =3D=3D false); assert(map__priv(map) =3D=3D false); + assert(map__hit(map) =3D=3D false); } =20 struct map *map__new(struct machine *machine, u64 start, u64 len, diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 6c43f31a9fe0..4262f5a143be 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -35,6 +35,7 @@ DECLARE_RC_STRUCT(map) { enum mapping_type mapping_type:8; bool erange_warned; bool priv; + bool hit; }; =20 struct kmap; @@ -83,6 +84,11 @@ static inline bool map__priv(const struct map *map) return RC_CHK_ACCESS(map)->priv; } =20 +static inline bool map__hit(const struct map *map) +{ + return RC_CHK_ACCESS(map)->hit; +} + static inline refcount_t *map__refcnt(struct map *map) { return &RC_CHK_ACCESS(map)->refcnt; @@ -287,6 +293,11 @@ static inline void map__set_priv(struct map *map) RC_CHK_ACCESS(map)->priv =3D true; } =20 +static inline void map__set_hit(struct map *map) +{ + RC_CHK_ACCESS(map)->hit =3D true; +} + static inline void map__set_erange_warned(struct map *map) { RC_CHK_ACCESS(map)->erange_warned =3D true; --=20 2.46.0.598.g6f2099f65c-goog From nobody Sat Nov 30 10:50:54 2024 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A87A18C006 for ; Mon, 9 Sep 2024 20:37:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725914279; cv=none; b=reyqCQI9ecx+/Mty1HVax7RJbHMoLMyKON6lzxuA171hj6j5tcXaCxmOpb+L6H29wJHbAh4sjKSfYsEJ/HsLiAQCKCddbg11Gh0jroaIPGXnfDtIEXQFDAkS4PYbQu+qmPrBVWGlm/aPqrav26+gaVqjmoVMoDfgNfzT4vrfMCY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725914279; c=relaxed/simple; bh=HptkHQHuvQDj1d3rSs7Sbbf5fWJ/fColrJrJTFzngig=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=QZ2rCdhW760jyMU3EA/fXmjz4HZjFN/dn7PxLPW2jx6i62G5gWNg52fvOqrLtZi8oED0kps5XdCIsy0rTQlYE0iJfsTR+MSYE6MYtXV4uNXmojqCYZUIk09zCqGeChYE7ZRXpBGk4CEvO51oZgytmS4+JYFLvgRblRyTFQx6Jfg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=0A+5zuQj; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="0A+5zuQj" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-6d34c57a88eso152625877b3.0 for ; Mon, 09 Sep 2024 13:37:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1725914277; x=1726519077; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=ReastPPbfrF1K+IO0MgSOanwMg0WzDPxfwAbYOVYAmc=; b=0A+5zuQjvWBAXaUm+hUXKt97y3j6Xqjd1Gg/XuNc6MTzeFb6Ud3k6+iBctfrPzaBfc 2uE+iLkEL6jxkeg6vORuT/eQ5WGd/3cOYmnGuFmY/UaRGEER/BRJVwKatQ5fg+dd+xKH xe4T7PjqCWuVmkO0lu8+ChhcrGOOxfHK17wGJ+IMR+rL9gTKhQaD/s+dBMIdzTV8WR3u buPQ4bPV9mqbzGwg7lRM1HeGbASWdYlbbyylS+qkZHKQLHD/+0sG76WUTcLR9sBTAmw5 qgEE2k9KrNAxB+a5MVYoe9os2x04XXBqLh8rVOn3S6T8FM4d+QJ9l5wPg1sRlouUFBCZ /L4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725914277; x=1726519077; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ReastPPbfrF1K+IO0MgSOanwMg0WzDPxfwAbYOVYAmc=; b=ftipVFVw2UOdfeT+BpAtAYRfHS8ob8/293Z4nY0Kk7opuv4WnekEPonrAK3mOGHPxG b/N/mFDjIo31RUhNY66Ct/OGTkzmp9vSbxn+Boot5q/Nw++V4GwOt2uOvCfXksjBfqMp WR/bSxl88k3jkhizedjXd2z5xURMdO+0gRS23dTDZIVfRlzcH4lYyAxB+ZaF5ka+2gvE MaAmdas5zu1zBOb8W41FTCrZ/xwNWV3miOMrtlkCtUlA2MAJpxMxSxUeNn0pUJSPOzhT LPvDfzeKuyPoZIh0MtYjPGVe7nlWQ2HLP/cm+nDcO451hOG93MnnctN9S08qOd06M8wm +1XQ== X-Forwarded-Encrypted: i=1; AJvYcCVqM55SlXKtPwyPXx2lqHX3FBGGlnhjlb05tuczYiYq6SWO+3ibZpCiw4BrGsPsxFg9KBedzS/FPZ38FJQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwFvEtOsjawMgvipV9PwE4WAlmPqDucpdwA1wl9HbxgwjKAbwiw NcaX/EsoOSj4Yrv8bGpC66LWCZhyCTNUYaqoLbz+/FyuO2saFsHu6PqsvKgcdMyHrDidpo/tgE4 8HOmzPA== X-Google-Smtp-Source: AGHT+IEEO133mN0FLFV4W3AzE2rRP0msPowiLmvYMo3WDwZfY4rTrb7anK0cThA4Tw2iJw2eCeKbdObKrndc X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:b7b9:f9a0:1197:ff33]) (user=irogers job=sendgmr) by 2002:a05:6902:4d1:b0:e0e:a784:2957 with SMTP id 3f1490d57ef6-e1d34865f70mr32011276.1.1725914276607; Mon, 09 Sep 2024 13:37:56 -0700 (PDT) Date: Mon, 9 Sep 2024 13:37:40 -0700 In-Reply-To: <20240909203740.143492-1-irogers@google.com> Message-Id: <20240909203740.143492-5-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240909203740.143492-1-irogers@google.com> X-Mailer: git-send-email 2.46.0.598.g6f2099f65c-goog Subject: [PATCH v2 4/4] perf callchain: Allow symbols to be optional when resolving a callchain From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Colin Ian King , Casey Chen , Anne Macedo , Sun Haiyong , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In uses like perf inject it is not necessary to gather the symbol for each call chain location, the map for the sample IP is wanted so that build IDs and the like can be injected. Make gathering the symbol in the callchain_cursor optional. For a perf inject -B command this lowers the peak RSS from 54.1MB to 29.6MB by avoiding loading symbols. Acked-by: Namhyung Kim Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 2 +- tools/perf/util/callchain.c | 8 ++-- tools/perf/util/callchain.h | 2 +- tools/perf/util/machine.c | 92 +++++++++++++++++++++---------------- tools/perf/util/machine.h | 33 ++++++++++--- 5 files changed, 85 insertions(+), 52 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 9eb72ff48d88..d6989195a061 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -942,7 +942,7 @@ int perf_event__inject_buildid(const struct perf_tool *= tool, union perf_event *e } =20 sample__for_each_callchain_node(thread, evsel, sample, PERF_MAX_STACK_DEP= TH, - mark_dso_hit_callback, &args); + /*symbols=3D*/false, mark_dso_hit_callback, &args); =20 thread__put(thread); repipe: diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 0d608e875fe9..0c7564747a14 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1800,7 +1800,7 @@ s64 callchain_avg_cycles(struct callchain_node *cnode) =20 int sample__for_each_callchain_node(struct thread *thread, struct evsel *e= vsel, struct perf_sample *sample, int max_stack, - callchain_iter_fn cb, void *data) + bool symbols, callchain_iter_fn cb, void *data) { struct callchain_cursor *cursor =3D get_tls_callchain_cursor(); int ret; @@ -1809,9 +1809,9 @@ int sample__for_each_callchain_node(struct thread *th= read, struct evsel *evsel, return -ENOMEM; =20 /* Fill in the callchain. */ - ret =3D thread__resolve_callchain(thread, cursor, evsel, sample, - /*parent=3D*/NULL, /*root_al=3D*/NULL, - max_stack); + ret =3D __thread__resolve_callchain(thread, cursor, evsel, sample, + /*parent=3D*/NULL, /*root_al=3D*/NULL, + max_stack, symbols); if (ret) return ret; =20 diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 76891f8e2373..86ed9e4d04f9 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -315,6 +315,6 @@ typedef int (*callchain_iter_fn)(struct callchain_curso= r_node *node, void *data) =20 int sample__for_each_callchain_node(struct thread *thread, struct evsel *e= vsel, struct perf_sample *sample, int max_stack, - callchain_iter_fn cb, void *data); + bool symbols, callchain_iter_fn cb, void *data); =20 #endif /* __PERF_CALLCHAIN_H */ diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 5783b96fb988..fad227b625d1 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2060,7 +2060,8 @@ static int add_callchain_ip(struct thread *thread, bool branch, struct branch_flags *flags, struct iterations *iter, - u64 branch_from) + u64 branch_from, + bool symbols) { struct map_symbol ms =3D {}; struct addr_location al; @@ -2099,7 +2100,8 @@ static int add_callchain_ip(struct thread *thread, } goto out; } - thread__find_symbol(thread, *cpumode, ip, &al); + if (symbols) + thread__find_symbol(thread, *cpumode, ip, &al); } =20 if (al.sym !=3D NULL) { @@ -2228,7 +2230,8 @@ static int lbr_callchain_add_kernel_ip(struct thread = *thread, struct symbol **parent, struct addr_location *root_al, u64 branch_from, - bool callee, int end) + bool callee, int end, + bool symbols) { struct ip_callchain *chain =3D sample->callchain; u8 cpumode =3D PERF_RECORD_MISC_USER; @@ -2238,7 +2241,8 @@ static int lbr_callchain_add_kernel_ip(struct thread = *thread, for (i =3D 0; i < end + 1; i++) { err =3D add_callchain_ip(thread, cursor, parent, root_al, &cpumode, chain->ips[i], - false, NULL, NULL, branch_from); + false, NULL, NULL, branch_from, + symbols); if (err) return err; } @@ -2248,7 +2252,8 @@ static int lbr_callchain_add_kernel_ip(struct thread = *thread, for (i =3D end; i >=3D 0; i--) { err =3D add_callchain_ip(thread, cursor, parent, root_al, &cpumode, chain->ips[i], - false, NULL, NULL, branch_from); + false, NULL, NULL, branch_from, + symbols); if (err) return err; } @@ -2291,7 +2296,8 @@ static int lbr_callchain_add_lbr_ip(struct thread *th= read, struct symbol **parent, struct addr_location *root_al, u64 *branch_from, - bool callee) + bool callee, + bool symbols) { struct branch_stack *lbr_stack =3D sample->branch_stack; struct branch_entry *entries =3D perf_sample__branch_entries(sample); @@ -2324,7 +2330,7 @@ static int lbr_callchain_add_lbr_ip(struct thread *th= read, err =3D add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip, true, flags, NULL, - *branch_from); + *branch_from, symbols); if (err) return err; =20 @@ -2349,7 +2355,7 @@ static int lbr_callchain_add_lbr_ip(struct thread *th= read, err =3D add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip, true, flags, NULL, - *branch_from); + *branch_from, symbols); if (err) return err; save_lbr_cursor_node(thread, cursor, i); @@ -2364,7 +2370,7 @@ static int lbr_callchain_add_lbr_ip(struct thread *th= read, err =3D add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip, true, flags, NULL, - *branch_from); + *branch_from, symbols); if (err) return err; save_lbr_cursor_node(thread, cursor, i); @@ -2378,7 +2384,7 @@ static int lbr_callchain_add_lbr_ip(struct thread *th= read, err =3D add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip, true, flags, NULL, - *branch_from); + *branch_from, symbols); if (err) return err; } @@ -2545,7 +2551,8 @@ static int resolve_lbr_callchain_sample(struct thread= *thread, struct symbol **parent, struct addr_location *root_al, int max_stack, - unsigned int max_lbr) + unsigned int max_lbr, + bool symbols) { bool callee =3D (callchain_param.order =3D=3D ORDER_CALLEE); struct ip_callchain *chain =3D sample->callchain; @@ -2587,12 +2594,12 @@ static int resolve_lbr_callchain_sample(struct thre= ad *thread, /* Add kernel ip */ err =3D lbr_callchain_add_kernel_ip(thread, cursor, sample, parent, root_al, branch_from, - true, i); + true, i, symbols); if (err) goto error; =20 err =3D lbr_callchain_add_lbr_ip(thread, cursor, sample, parent, - root_al, &branch_from, true); + root_al, &branch_from, true, symbols); if (err) goto error; =20 @@ -2609,14 +2616,14 @@ static int resolve_lbr_callchain_sample(struct thre= ad *thread, goto error; } err =3D lbr_callchain_add_lbr_ip(thread, cursor, sample, parent, - root_al, &branch_from, false); + root_al, &branch_from, false, symbols); if (err) goto error; =20 /* Add kernel ip */ err =3D lbr_callchain_add_kernel_ip(thread, cursor, sample, parent, root_al, branch_from, - false, i); + false, i, symbols); if (err) goto error; } @@ -2630,7 +2637,7 @@ static int find_prev_cpumode(struct ip_callchain *cha= in, struct thread *thread, struct callchain_cursor *cursor, struct symbol **parent, struct addr_location *root_al, - u8 *cpumode, int ent) + u8 *cpumode, int ent, bool symbols) { int err =3D 0; =20 @@ -2640,7 +2647,7 @@ static int find_prev_cpumode(struct ip_callchain *cha= in, struct thread *thread, if (ip >=3D PERF_CONTEXT_MAX) { err =3D add_callchain_ip(thread, cursor, parent, root_al, cpumode, ip, - false, NULL, NULL, 0); + false, NULL, NULL, 0, symbols); break; } } @@ -2662,7 +2669,8 @@ static int thread__resolve_callchain_sample(struct th= read *thread, struct perf_sample *sample, struct symbol **parent, struct addr_location *root_al, - int max_stack) + int max_stack, + bool symbols) { struct branch_stack *branch =3D sample->branch_stack; struct branch_entry *entries =3D perf_sample__branch_entries(sample); @@ -2682,7 +2690,8 @@ static int thread__resolve_callchain_sample(struct th= read *thread, =20 err =3D resolve_lbr_callchain_sample(thread, cursor, sample, parent, root_al, max_stack, - !env ? 0 : env->max_branches); + !env ? 0 : env->max_branches, + symbols); if (err) return (err < 0) ? err : 0; } @@ -2747,13 +2756,14 @@ static int thread__resolve_callchain_sample(struct = thread *thread, root_al, NULL, be[i].to, true, &be[i].flags, - NULL, be[i].from); + NULL, be[i].from, symbols); =20 - if (!err) + if (!err) { err =3D add_callchain_ip(thread, cursor, parent, root_al, NULL, be[i].from, true, &be[i].flags, - &iter[i], 0); + &iter[i], 0, symbols); + } if (err =3D=3D -EINVAL) break; if (err) @@ -2769,7 +2779,7 @@ static int thread__resolve_callchain_sample(struct th= read *thread, check_calls: if (chain && callchain_param.order !=3D ORDER_CALLEE) { err =3D find_prev_cpumode(chain, thread, cursor, parent, root_al, - &cpumode, chain->nr - first_call); + &cpumode, chain->nr - first_call, symbols); if (err) return (err < 0) ? err : 0; } @@ -2791,7 +2801,7 @@ static int thread__resolve_callchain_sample(struct th= read *thread, ++nr_entries; else if (callchain_param.order !=3D ORDER_CALLEE) { err =3D find_prev_cpumode(chain, thread, cursor, parent, - root_al, &cpumode, j); + root_al, &cpumode, j, symbols); if (err) return (err < 0) ? err : 0; continue; @@ -2818,8 +2828,8 @@ static int thread__resolve_callchain_sample(struct th= read *thread, if (leaf_frame_caller && leaf_frame_caller !=3D ip) { =20 err =3D add_callchain_ip(thread, cursor, parent, - root_al, &cpumode, leaf_frame_caller, - false, NULL, NULL, 0); + root_al, &cpumode, leaf_frame_caller, + false, NULL, NULL, 0, symbols); if (err) return (err < 0) ? err : 0; } @@ -2827,7 +2837,7 @@ static int thread__resolve_callchain_sample(struct th= read *thread, =20 err =3D add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip, - false, NULL, NULL, 0); + false, NULL, NULL, 0, symbols); =20 if (err) return (err < 0) ? err : 0; @@ -2907,7 +2917,7 @@ static int thread__resolve_callchain_unwind(struct th= read *thread, struct callchain_cursor *cursor, struct evsel *evsel, struct perf_sample *sample, - int max_stack) + int max_stack, bool symbols) { /* Can we do dwarf post unwind? */ if (!((evsel->core.attr.sample_type & PERF_SAMPLE_REGS_USER) && @@ -2919,17 +2929,21 @@ static int thread__resolve_callchain_unwind(struct = thread *thread, (!sample->user_stack.size)) return 0; =20 + if (!symbols) + pr_debug("Not resolving symbols with an unwinder isn't currently support= ed\n"); + return unwind__get_entries(unwind_entry, cursor, thread, sample, max_stack, false); } =20 -int thread__resolve_callchain(struct thread *thread, - struct callchain_cursor *cursor, - struct evsel *evsel, - struct perf_sample *sample, - struct symbol **parent, - struct addr_location *root_al, - int max_stack) +int __thread__resolve_callchain(struct thread *thread, + struct callchain_cursor *cursor, + struct evsel *evsel, + struct perf_sample *sample, + struct symbol **parent, + struct addr_location *root_al, + int max_stack, + bool symbols) { int ret =3D 0; =20 @@ -2942,22 +2956,22 @@ int thread__resolve_callchain(struct thread *thread, ret =3D thread__resolve_callchain_sample(thread, cursor, evsel, sample, parent, root_al, - max_stack); + max_stack, symbols); if (ret) return ret; ret =3D thread__resolve_callchain_unwind(thread, cursor, evsel, sample, - max_stack); + max_stack, symbols); } else { ret =3D thread__resolve_callchain_unwind(thread, cursor, evsel, sample, - max_stack); + max_stack, symbols); if (ret) return ret; ret =3D thread__resolve_callchain_sample(thread, cursor, evsel, sample, parent, root_al, - max_stack); + max_stack, symbols); } =20 return ret; diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index a687876e3453..2e5a4cb342d8 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -178,13 +178,32 @@ struct mem_info *sample__resolve_mem(struct perf_samp= le *sample, =20 struct callchain_cursor; =20 -int thread__resolve_callchain(struct thread *thread, - struct callchain_cursor *cursor, - struct evsel *evsel, - struct perf_sample *sample, - struct symbol **parent, - struct addr_location *root_al, - int max_stack); +int __thread__resolve_callchain(struct thread *thread, + struct callchain_cursor *cursor, + struct evsel *evsel, + struct perf_sample *sample, + struct symbol **parent, + struct addr_location *root_al, + int max_stack, + bool symbols); + +static inline int thread__resolve_callchain(struct thread *thread, + struct callchain_cursor *cursor, + struct evsel *evsel, + struct perf_sample *sample, + struct symbol **parent, + struct addr_location *root_al, + int max_stack) +{ + return __thread__resolve_callchain(thread, + cursor, + evsel, + sample, + parent, + root_al, + max_stack, + /*symbols=3D*/true); +} =20 /* * Default guest kernel is defined by parameter --guestkallsyms --=20 2.46.0.598.g6f2099f65c-goog