Messages in this thread | | | Date | Mon, 16 Jan 2023 08:14:29 +0200 | Subject | Re: [RFC 3/4] perf tool: Introduce PERF_RECORD_KMOD_SEC_MAP | From | Adrian Hunter <> |
| |
On 10/01/23 07:58, Ravi Bangoria wrote: > Introduce, perf tool only, synthetic event type PERF_RECORD_KMOD_SEC_MAP. > Also add stub code for it. This event will be used to save/restore kernel > module section maps to/from perf.data file. This is needed because kernel > module elfs does not contain program header table and thus there is no > easy way to find out how kernel would have loaded module sections in the > memory.
Currently machine__addnew_module_map() adds a map for a module, and then perf_event__synthesize_modules() creates an MMAP/MMAP2 event for it. Why can't we do that for the sections?
> > Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com> > --- > tools/lib/perf/Documentation/libperf.txt | 1 + > tools/lib/perf/include/perf/event.h | 25 ++++++++++++++++++++++++ > tools/perf/util/event.c | 1 + > tools/perf/util/session.c | 12 ++++++++++++ > tools/perf/util/tool.h | 3 ++- > 5 files changed, 41 insertions(+), 1 deletion(-) > > diff --git a/tools/lib/perf/Documentation/libperf.txt b/tools/lib/perf/Documentation/libperf.txt > index a8f1a237931b..b62730b84cc5 100644 > --- a/tools/lib/perf/Documentation/libperf.txt > +++ b/tools/lib/perf/Documentation/libperf.txt > @@ -211,6 +211,7 @@ SYNOPSIS > struct perf_record_time_conv; > struct perf_record_header_feature; > struct perf_record_compressed; > + struct perf_record_kmod_sec_maps; > -- > > DESCRIPTION > diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/perf/event.h > index ad47d7b31046..404b23b6902b 100644 > --- a/tools/lib/perf/include/perf/event.h > +++ b/tools/lib/perf/include/perf/event.h > @@ -438,6 +438,29 @@ struct perf_record_compressed { > char data[]; > }; > > +/* Kernel module elf section maps */ > +struct perf_record_kmod_sec_map { > + struct perf_event_header header; > + /* Machine id. Same as synthesized PERF_RECORD_MMAP */ > + __u32 pid; > + /* Section start ip address */ > + __u64 start; > + /* Section length */ > + __u64 len; > + /* Section page offset in kernel module elf file */ > + __u64 pgoff; > + /* Section name length, including '\0' */ > + __u16 sec_name_len; > + /* Kernel module filename(path) length, including '\0' */ > + __u16 filename_len; > + /* > + * Section name and filename stored as: "sec_name\0filename\0". i.e: > + * data[0]: Section name > + * data[sec_name_len + 1]: File name > + */ > + char data[]; > +}; > + > enum perf_user_event_type { /* above any possible kernel type */ > PERF_RECORD_USER_TYPE_START = 64, > PERF_RECORD_HEADER_ATTR = 64, > @@ -459,6 +482,7 @@ enum perf_user_event_type { /* above any possible kernel type */ > PERF_RECORD_HEADER_FEATURE = 80, > PERF_RECORD_COMPRESSED = 81, > PERF_RECORD_FINISHED_INIT = 82, > + PERF_RECORD_KMOD_SEC_MAP = 83, > PERF_RECORD_HEADER_MAX > }; > > @@ -499,6 +523,7 @@ union perf_event { > struct perf_record_time_conv time_conv; > struct perf_record_header_feature feat; > struct perf_record_compressed pack; > + struct perf_record_kmod_sec_map kmod_sec_map; > }; > > #endif /* __LIBPERF_EVENT_H */ > diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c > index 1fa14598b916..1b03061440bc 100644 > --- a/tools/perf/util/event.c > +++ b/tools/perf/util/event.c > @@ -77,6 +77,7 @@ static const char *perf_event__names[] = { > [PERF_RECORD_HEADER_FEATURE] = "FEATURE", > [PERF_RECORD_COMPRESSED] = "COMPRESSED", > [PERF_RECORD_FINISHED_INIT] = "FINISHED_INIT", > + [PERF_RECORD_KMOD_SEC_MAP] = "KMOD_SEC_MAP", > }; > > const char *perf_event__name(unsigned int id) > diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c > index 7c021c6cedb9..4f5165cd58de 100644 > --- a/tools/perf/util/session.c > +++ b/tools/perf/util/session.c > @@ -563,6 +563,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) > tool->compressed = perf_session__process_compressed_event; > if (tool->finished_init == NULL) > tool->finished_init = process_event_op2_stub; > + if (tool->kmod_sec_map == NULL) > + tool->kmod_sec_map = process_event_stub; > } > > static void swap_sample_id_all(union perf_event *event, void *data) > @@ -997,6 +999,12 @@ static void perf_event__time_conv_swap(union perf_event *event, > } > } > > +static void perf_event_kmod_sec_map_swap(union perf_event *event __maybe_unused, > + bool sample_id_all __maybe_unused) > +{ > + /* FIXME */ > +} > + > typedef void (*perf_event__swap_op)(union perf_event *event, > bool sample_id_all); > > @@ -1035,6 +1043,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { > [PERF_RECORD_STAT_ROUND] = perf_event__stat_round_swap, > [PERF_RECORD_EVENT_UPDATE] = perf_event__event_update_swap, > [PERF_RECORD_TIME_CONV] = perf_event__time_conv_swap, > + [PERF_RECORD_KMOD_SEC_MAP] = perf_event_kmod_sec_map_swap, > [PERF_RECORD_HEADER_MAX] = NULL, > }; > > @@ -1727,6 +1736,9 @@ static s64 perf_session__process_user_event(struct perf_session *session, > return err; > case PERF_RECORD_FINISHED_INIT: > return tool->finished_init(session, event); > + case PERF_RECORD_KMOD_SEC_MAP: > + /* Currently PERF_RECORD_KMOD_SEC_MAP is supported only for host */ > + return tool->kmod_sec_map(tool, event, &sample, &session->machines.host); > default: > return -EINVAL; > } > diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h > index c957fb849ac6..8ea7fb85c196 100644 > --- a/tools/perf/util/tool.h > +++ b/tools/perf/util/tool.h > @@ -60,7 +60,8 @@ struct perf_tool { > unthrottle, > ksymbol, > bpf, > - text_poke; > + text_poke, > + kmod_sec_map; > > event_attr_op attr; > event_attr_op event_update;
| |