Skip to content

Commit 64eed01

Browse files
captain5050acmel
authored andcommitted
perf inject: Lazy build-id mmap2 event insertion
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. Signed-off-by: Ian Rogers <[email protected]> Acked-by: Namhyung Kim <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Anne Macedo <[email protected]> Cc: Casey Chen <[email protected]> Cc: Colin Ian King <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Sun Haiyong <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent d762ba0 commit 64eed01

File tree

4 files changed

+63
-12
lines changed

4 files changed

+63
-12
lines changed

tools/perf/builtin-inject.c

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ enum build_id_rewrite_style {
108108
BID_RWS__INJECT_HEADER_LAZY,
109109
BID_RWS__INJECT_HEADER_ALL,
110110
BID_RWS__MMAP2_BUILDID_ALL,
111+
BID_RWS__MMAP2_BUILDID_LAZY,
111112
};
112113

113114
struct perf_inject {
@@ -527,7 +528,8 @@ static int perf_event__repipe_common_mmap(const struct perf_tool *tool,
527528
* Remember the evsel for lazy build id generation. It is used
528529
* for the sample id header type.
529530
*/
530-
if (inject->build_id_style == BID_RWS__INJECT_HEADER_LAZY &&
531+
if ((inject->build_id_style == BID_RWS__INJECT_HEADER_LAZY ||
532+
inject->build_id_style == BID_RWS__MMAP2_BUILDID_LAZY) &&
531533
!inject->mmap_evsel)
532534
inject->mmap_evsel = evlist__event2evsel(inject->session->evlist, event);
533535

@@ -560,6 +562,9 @@ static int perf_event__repipe_common_mmap(const struct perf_tool *tool,
560562
}
561563
}
562564
dso__put(dso);
565+
if (inject->build_id_style == BID_RWS__MMAP2_BUILDID_LAZY)
566+
return 0;
567+
563568
return perf_event__repipe(tool, event, sample, machine);
564569
}
565570

@@ -825,7 +830,8 @@ static int tool__inject_mmap2_build_id(const struct perf_tool *tool,
825830
return 0;
826831
}
827832

828-
static int mark_dso_hit(const struct perf_tool *tool,
833+
static int mark_dso_hit(const struct perf_inject *inject,
834+
const struct perf_tool *tool,
829835
struct perf_sample *sample,
830836
struct machine *machine,
831837
const struct evsel *mmap_evsel,
@@ -854,16 +860,39 @@ static int mark_dso_hit(const struct perf_tool *tool,
854860
}
855861
}
856862
dso = map__dso(map);
857-
if (dso && !dso__hit(dso)) {
858-
dso__set_hit(dso);
859-
tool__inject_build_id(tool, sample, machine,
860-
mmap_evsel, misc, dso__long_name(dso), dso,
861-
map__flags(map));
863+
if (inject->build_id_style == BID_RWS__INJECT_HEADER_LAZY) {
864+
if (dso && !dso__hit(dso)) {
865+
dso__set_hit(dso);
866+
tool__inject_build_id(tool, sample, machine,
867+
mmap_evsel, misc, dso__long_name(dso), dso,
868+
map__flags(map));
869+
}
870+
} else if (inject->build_id_style == BID_RWS__MMAP2_BUILDID_LAZY) {
871+
if (!map__hit(map)) {
872+
const struct build_id null_bid = { .size = 0 };
873+
const struct build_id *bid = dso ? dso__bid(dso) : &null_bid;
874+
const char *filename = dso ? dso__long_name(dso) : "";
875+
876+
map__set_hit(map);
877+
perf_event__synthesize_mmap2_build_id(tool, sample, machine,
878+
perf_event__repipe,
879+
mmap_evsel,
880+
misc,
881+
sample->pid, sample->tid,
882+
map__start(map),
883+
map__end(map) - map__start(map),
884+
map__pgoff(map),
885+
bid,
886+
map__prot(map),
887+
map__flags(map),
888+
filename);
889+
}
862890
}
863891
return 0;
864892
}
865893

866894
struct mark_dso_hit_args {
895+
const struct perf_inject *inject;
867896
const struct perf_tool *tool;
868897
struct perf_sample *sample;
869898
struct machine *machine;
@@ -875,7 +904,7 @@ static int mark_dso_hit_callback(struct callchain_cursor_node *node, void *data)
875904
struct mark_dso_hit_args *args = data;
876905
struct map *map = node->ms.map;
877906

878-
return mark_dso_hit(args->tool, args->sample, args->machine,
907+
return mark_dso_hit(args->inject, args->tool, args->sample, args->machine,
879908
args->mmap_evsel, map, /*sample_in_dso=*/false);
880909
}
881910

@@ -888,6 +917,7 @@ int perf_event__inject_buildid(const struct perf_tool *tool, union perf_event *e
888917
struct thread *thread;
889918
struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
890919
struct mark_dso_hit_args args = {
920+
.inject = inject,
891921
.tool = tool,
892922
/*
893923
* 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
907937
}
908938

909939
if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) {
910-
mark_dso_hit(tool, sample, machine, args.mmap_evsel, al.map,
940+
mark_dso_hit(inject, tool, sample, machine, args.mmap_evsel, al.map,
911941
/*sample_in_dso=*/true);
912942
}
913943

@@ -2155,7 +2185,8 @@ static int __cmd_inject(struct perf_inject *inject)
21552185
#endif
21562186
}
21572187

2158-
if (inject->build_id_style == BID_RWS__INJECT_HEADER_LAZY) {
2188+
if (inject->build_id_style == BID_RWS__INJECT_HEADER_LAZY ||
2189+
inject->build_id_style == BID_RWS__MMAP2_BUILDID_LAZY) {
21592190
inject->tool.sample = perf_event__inject_buildid;
21602191
} else if (inject->sched_stat) {
21612192
struct evsel *evsel;
@@ -2338,13 +2369,16 @@ int cmd_inject(int argc, const char **argv)
23382369
const char *known_build_ids = NULL;
23392370
bool build_ids;
23402371
bool build_id_all;
2372+
bool mmap2_build_ids;
23412373
bool mmap2_build_id_all;
23422374

23432375
struct option options[] = {
23442376
OPT_BOOLEAN('b', "build-ids", &build_ids,
23452377
"Inject build-ids into the output stream"),
23462378
OPT_BOOLEAN(0, "buildid-all", &build_id_all,
23472379
"Inject build-ids of all DSOs into the output stream"),
2380+
OPT_BOOLEAN('B', "mmap2-buildids", &mmap2_build_ids,
2381+
"Drop unused mmap events, make others mmap2 with build IDs"),
23482382
OPT_BOOLEAN(0, "mmap2-buildid-all", &mmap2_build_id_all,
23492383
"Rewrite all mmap events as mmap2 events with build IDs"),
23502384
OPT_STRING(0, "known-build-ids", &known_build_ids,
@@ -2443,6 +2477,8 @@ int cmd_inject(int argc, const char **argv)
24432477
return -1;
24442478
}
24452479
}
2480+
if (mmap2_build_ids)
2481+
inject.build_id_style = BID_RWS__MMAP2_BUILDID_LAZY;
24462482
if (mmap2_build_id_all)
24472483
inject.build_id_style = BID_RWS__MMAP2_BUILDID_ALL;
24482484
if (build_ids)
@@ -2453,7 +2489,8 @@ int cmd_inject(int argc, const char **argv)
24532489
data.path = inject.input_name;
24542490

24552491
ordered_events = inject.jit_mode || inject.sched_stat ||
2456-
(inject.build_id_style == BID_RWS__INJECT_HEADER_LAZY);
2492+
inject.build_id_style == BID_RWS__INJECT_HEADER_LAZY ||
2493+
inject.build_id_style == BID_RWS__MMAP2_BUILDID_LAZY;
24572494
perf_tool__init(&inject.tool, ordered_events);
24582495
inject.tool.sample = perf_event__repipe_sample;
24592496
inject.tool.read = perf_event__repipe_sample;
@@ -2532,7 +2569,8 @@ int cmd_inject(int argc, const char **argv)
25322569
}
25332570
}
25342571

2535-
if (inject.build_id_style == BID_RWS__INJECT_HEADER_LAZY) {
2572+
if (inject.build_id_style == BID_RWS__INJECT_HEADER_LAZY ||
2573+
inject.build_id_style == BID_RWS__MMAP2_BUILDID_LAZY) {
25362574
/*
25372575
* to make sure the mmap records are ordered correctly
25382576
* and so that the correct especially due to jitted code

tools/perf/tests/shell/pipe_test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ test_inject_bids() {
116116
}
117117

118118
test_record_report
119+
test_inject_bids -B
119120
test_inject_bids -b
120121
test_inject_bids --buildid-all
121122
test_inject_bids --mmap2-buildid-all

tools/perf/util/map.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ static void map__init(struct map *map, u64 start, u64 end, u64 pgoff,
116116
map__set_mapping_type(map, MAPPING_TYPE__DSO);
117117
assert(map__erange_warned(map) == false);
118118
assert(map__priv(map) == false);
119+
assert(map__hit(map) == false);
119120
}
120121

121122
struct map *map__new(struct machine *machine, u64 start, u64 len,

tools/perf/util/map.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ DECLARE_RC_STRUCT(map) {
3535
enum mapping_type mapping_type:8;
3636
bool erange_warned;
3737
bool priv;
38+
bool hit;
3839
};
3940

4041
struct kmap;
@@ -83,6 +84,11 @@ static inline bool map__priv(const struct map *map)
8384
return RC_CHK_ACCESS(map)->priv;
8485
}
8586

87+
static inline bool map__hit(const struct map *map)
88+
{
89+
return RC_CHK_ACCESS(map)->hit;
90+
}
91+
8692
static inline refcount_t *map__refcnt(struct map *map)
8793
{
8894
return &RC_CHK_ACCESS(map)->refcnt;
@@ -287,6 +293,11 @@ static inline void map__set_priv(struct map *map)
287293
RC_CHK_ACCESS(map)->priv = true;
288294
}
289295

296+
static inline void map__set_hit(struct map *map)
297+
{
298+
RC_CHK_ACCESS(map)->hit = true;
299+
}
300+
290301
static inline void map__set_erange_warned(struct map *map)
291302
{
292303
RC_CHK_ACCESS(map)->erange_warned = true;

0 commit comments

Comments
 (0)