perf tools: Handle PERF_RECORD_KSYMBOL
This patch handles PERF_RECORD_KSYMBOL in perf record/report. Specifically, map and symbol are created for ksymbol register, and removed for ksymbol unregister. This patch also sets perf_event_attr.ksymbol properly. The flag is ON by default. Committer notes: Use proper inttypes.h for u64, fixing the build in some environments like in the android NDK r15c targetting ARM 32-bit. I.e. fixing this build error: util/event.c: In function 'perf_event__fprintf_ksymbol': util/event.c:1489:10: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'u64' [-Werror=format=] event->ksymbol_event.flags, event->ksymbol_event.name); ^ cc1: all warnings being treated as errors Signed-off-by: Song Liu <songliubraving@fb.com> Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Peter Zijlstra <peterz@infradead.org> Cc: kernel-team@fb.com Cc: netdev@vger.kernel.org Link: http://lkml.kernel.org/r/20190117161521.1341602-6-songliubraving@fb.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:

committed by
Arnaldo Carvalho de Melo

parent
df063c83aa
commit
9aa0bfa370
@@ -681,6 +681,59 @@ int machine__process_switch_event(struct machine *machine __maybe_unused,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int machine__process_ksymbol_register(struct machine *machine,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample __maybe_unused)
|
||||
{
|
||||
struct symbol *sym;
|
||||
struct map *map;
|
||||
|
||||
map = map_groups__find(&machine->kmaps, event->ksymbol_event.addr);
|
||||
if (!map) {
|
||||
map = dso__new_map(event->ksymbol_event.name);
|
||||
if (!map)
|
||||
return -ENOMEM;
|
||||
|
||||
map->start = event->ksymbol_event.addr;
|
||||
map->pgoff = map->start;
|
||||
map->end = map->start + event->ksymbol_event.len;
|
||||
map_groups__insert(&machine->kmaps, map);
|
||||
}
|
||||
|
||||
sym = symbol__new(event->ksymbol_event.addr, event->ksymbol_event.len,
|
||||
0, 0, event->ksymbol_event.name);
|
||||
if (!sym)
|
||||
return -ENOMEM;
|
||||
dso__insert_symbol(map->dso, sym);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int machine__process_ksymbol_unregister(struct machine *machine,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample __maybe_unused)
|
||||
{
|
||||
struct map *map;
|
||||
|
||||
map = map_groups__find(&machine->kmaps, event->ksymbol_event.addr);
|
||||
if (map)
|
||||
map_groups__remove(&machine->kmaps, map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int machine__process_ksymbol(struct machine *machine __maybe_unused,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
if (dump_trace)
|
||||
perf_event__fprintf_ksymbol(event, stdout);
|
||||
|
||||
if (event->ksymbol_event.flags & PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER)
|
||||
return machine__process_ksymbol_unregister(machine, event,
|
||||
sample);
|
||||
return machine__process_ksymbol_register(machine, event, sample);
|
||||
}
|
||||
|
||||
static void dso__adjust_kmod_long_name(struct dso *dso, const char *filename)
|
||||
{
|
||||
const char *dup_filename;
|
||||
@@ -1812,6 +1865,8 @@ int machine__process_event(struct machine *machine, union perf_event *event,
|
||||
case PERF_RECORD_SWITCH:
|
||||
case PERF_RECORD_SWITCH_CPU_WIDE:
|
||||
ret = machine__process_switch_event(machine, event); break;
|
||||
case PERF_RECORD_KSYMBOL:
|
||||
ret = machine__process_ksymbol(machine, event, sample); break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
|
Reference in New Issue
Block a user