mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
perf sched: Handle missing trace samples in pipe mode
For pipe mode streams, event attributes are received dynamically during
event processing, meaning session->evlist is not populated prior to
perf_session__process_events(). To handle pipe input correctly:
- Register the missing .attr, .tracing_data, .build_id, and .feature
callbacks in cmd_sched()
- Promote the handlers array to file-scope (latency_handlers[]) and
dynamically assign matching tracepoint handlers
(or process_sched_ignore) inside
perf_sched__process_tracepoint_sample() when evsel->handler is NULL;
replace process_sched_wakeup_ignore() with process_sched_ignore()
- Perform the trace check post-processing when handling pipe data
Fixes: 27295592c2 ("perf session: Share the common trace sample_check routine as perf_session__has_traces")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
parent
4a81d59a9d
commit
44f8dd1ee1
|
|
@ -1581,12 +1581,6 @@ static int process_sched_wakeup_event(const struct perf_tool *tool,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int process_sched_wakeup_ignore(const struct perf_tool *tool __maybe_unused,
|
||||
struct perf_sample *sample __maybe_unused,
|
||||
struct machine *machine __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool thread__has_color(struct thread *thread)
|
||||
{
|
||||
|
|
@ -1938,6 +1932,22 @@ typedef int (*tracepoint_handler)(const struct perf_tool *tool,
|
|||
struct perf_sample *sample,
|
||||
struct machine *machine);
|
||||
|
||||
static struct evsel_str_handler latency_handlers[] = {
|
||||
{ "sched:sched_switch", process_sched_switch_event, },
|
||||
{ "sched:sched_stat_runtime", process_sched_runtime_event, },
|
||||
{ "sched:sched_wakeup", process_sched_wakeup_event, },
|
||||
{ "sched:sched_waking", process_sched_wakeup_event, },
|
||||
{ "sched:sched_wakeup_new", process_sched_wakeup_event, },
|
||||
{ "sched:sched_migrate_task", process_sched_migrate_task_event, },
|
||||
};
|
||||
|
||||
static int process_sched_ignore(const struct perf_tool *tool __maybe_unused,
|
||||
struct perf_sample *sample __maybe_unused,
|
||||
struct machine *machine __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int perf_sched__process_tracepoint_sample(const struct perf_tool *tool __maybe_unused,
|
||||
union perf_event *event __maybe_unused,
|
||||
struct perf_sample *sample,
|
||||
|
|
@ -1946,7 +1956,23 @@ static int perf_sched__process_tracepoint_sample(const struct perf_tool *tool __
|
|||
struct evsel *evsel = sample->evsel;
|
||||
int err = 0;
|
||||
|
||||
if (evsel->handler != NULL) {
|
||||
if (evsel->handler == NULL) {
|
||||
evsel->handler = process_sched_ignore;
|
||||
for (size_t i = 0; i < ARRAY_SIZE(latency_handlers); i++) {
|
||||
if (!evsel__name_is(evsel, latency_handlers[i].name))
|
||||
continue;
|
||||
|
||||
if (!strcmp(latency_handlers[i].name, "sched:sched_wakeup") &&
|
||||
sample->evsel->evlist &&
|
||||
evlist__find_tracepoint_by_name(sample->evsel->evlist, "sched:sched_waking"))
|
||||
break;
|
||||
|
||||
evsel->handler = latency_handlers[i].handler;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (evsel->handler != process_sched_ignore) {
|
||||
tracepoint_handler f = evsel->handler;
|
||||
err = f(tool, sample, machine);
|
||||
}
|
||||
|
|
@ -1987,14 +2013,6 @@ static int perf_sched__process_comm(const struct perf_tool *tool __maybe_unused,
|
|||
|
||||
static int perf_sched__read_events(struct perf_sched *sched)
|
||||
{
|
||||
struct evsel_str_handler handlers[] = {
|
||||
{ "sched:sched_switch", process_sched_switch_event, },
|
||||
{ "sched:sched_stat_runtime", process_sched_runtime_event, },
|
||||
{ "sched:sched_wakeup", process_sched_wakeup_event, },
|
||||
{ "sched:sched_waking", process_sched_wakeup_event, },
|
||||
{ "sched:sched_wakeup_new", process_sched_wakeup_event, },
|
||||
{ "sched:sched_migrate_task", process_sched_migrate_task_event, },
|
||||
};
|
||||
struct perf_session *session;
|
||||
struct perf_data data = {
|
||||
.path = input_name,
|
||||
|
|
@ -2011,14 +2029,17 @@ static int perf_sched__read_events(struct perf_sched *sched)
|
|||
|
||||
symbol__init(perf_session__env(session));
|
||||
|
||||
/* prefer sched_waking if it is captured */
|
||||
if (evlist__find_tracepoint_by_name(session->evlist, "sched:sched_waking"))
|
||||
handlers[2].handler = process_sched_wakeup_ignore;
|
||||
if (!perf_data__is_pipe(session->data)) {
|
||||
/* prefer sched_waking if it is captured */
|
||||
if (evlist__find_tracepoint_by_name(session->evlist, "sched:sched_waking"))
|
||||
latency_handlers[2].handler = process_sched_ignore;
|
||||
|
||||
if (perf_session__set_tracepoints_handlers(session, handlers))
|
||||
goto out_delete;
|
||||
if (perf_session__set_tracepoints_handlers(session, latency_handlers))
|
||||
goto out_delete;
|
||||
}
|
||||
|
||||
if (!perf_session__has_traces(session, "record -R"))
|
||||
if (!perf_data__is_pipe(session->data) &&
|
||||
!perf_session__has_traces(session, "record -R"))
|
||||
goto out_delete;
|
||||
|
||||
err = perf_session__process_events(session);
|
||||
|
|
@ -2027,6 +2048,11 @@ static int perf_sched__read_events(struct perf_sched *sched)
|
|||
goto out_delete;
|
||||
}
|
||||
|
||||
if (perf_data__is_pipe(session->data) &&
|
||||
!perf_session__has_traces(session, "record -R")) {
|
||||
goto out_delete;
|
||||
}
|
||||
|
||||
sched->nr_events = evlist__stats(session->evlist)->nr_events[0];
|
||||
sched->nr_lost_events = evlist__stats(session->evlist)->total_lost;
|
||||
sched->nr_lost_chunks = evlist__stats(session->evlist)->nr_events[PERF_RECORD_LOST];
|
||||
|
|
@ -5176,6 +5202,10 @@ int cmd_sched(int argc, const char **argv)
|
|||
sched.tool.namespaces = perf_event__process_namespaces;
|
||||
sched.tool.lost = perf_event__process_lost;
|
||||
sched.tool.fork = perf_sched__process_fork_event;
|
||||
sched.tool.attr = perf_event__process_attr;
|
||||
sched.tool.tracing_data = perf_event__process_tracing_data;
|
||||
sched.tool.build_id = perf_event__process_build_id;
|
||||
sched.tool.feature = perf_event__process_feature;
|
||||
|
||||
argc = parse_options_subcommand(argc, argv, sched_options, sched_subcommands,
|
||||
sched_usage, PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user