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

perf inject: Lazily allocate event_copy

The event_copy is 64kb (PERF_SAMPLE_SIZE_MAX) and stack allocated in
struct perf_inject. It is used for aux events that may not exist in a
file. Make the array allocation lazy to cut down on the stack usage.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20230527034324.2597593-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
d3944f0e e590e46b

+13 -3
+13 -3
tools/perf/builtin-inject.c
··· 122 122 u64 aux_id; 123 123 struct list_head samples; 124 124 struct itrace_synth_opts itrace_synth_opts; 125 - char event_copy[PERF_SAMPLE_MAX_SIZE]; 125 + char *event_copy; 126 126 struct perf_file_section secs[HEADER_FEAT_BITS]; 127 127 struct guest_session guest_session; 128 128 struct strlist *known_build_ids; ··· 320 320 { 321 321 size_t sz1 = sample->aux_sample.data - (void *)event; 322 322 size_t sz2 = event->header.size - sample->aux_sample.size - sz1; 323 - union perf_event *ev = (union perf_event *)inject->event_copy; 323 + union perf_event *ev; 324 324 325 + if (inject->event_copy == NULL) { 326 + inject->event_copy = malloc(PERF_SAMPLE_MAX_SIZE); 327 + if (!inject->event_copy) 328 + return ERR_PTR(-ENOMEM); 329 + } 330 + ev = (union perf_event *)inject->event_copy; 325 331 if (sz1 > event->header.size || sz2 > event->header.size || 326 332 sz1 + sz2 > event->header.size || 327 333 sz1 < sizeof(struct perf_event_header) + sizeof(u64)) ··· 363 357 364 358 build_id__mark_dso_hit(tool, event, sample, evsel, machine); 365 359 366 - if (inject->itrace_synth_opts.set && sample->aux_sample.size) 360 + if (inject->itrace_synth_opts.set && sample->aux_sample.size) { 367 361 event = perf_inject__cut_auxtrace_sample(inject, event, sample); 362 + if (IS_ERR(event)) 363 + return PTR_ERR(event); 364 + } 368 365 369 366 return perf_event__repipe_synth(tool, event); 370 367 } ··· 2400 2391 if (!inject.in_place_update) 2401 2392 perf_data__close(&inject.output); 2402 2393 free(inject.itrace_synth_opts.vm_tm_corr_args); 2394 + free(inject.event_copy); 2403 2395 return ret; 2404 2396 }