mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-20 11:13:58 +08:00
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and refactorings from Arnaldo Carvalho de Melo: New features: . In perf timechart: - Add backtrace support to CPU info . Print pid along the name . Add support for CPU topology . Add new option --highlight'ing threads, be it by name or, if a numeric value is provided, that run more than given duration. From Stanislav Fomichev. Refactorings: . Rename some struct DSO binary_type related members and methods, to clarify its purpose and need for differentiation from symtab_type, i.e. one is about the files .text, CFI, etc, i.e. its binary contents, and the other is about where the symbol table came from. . Convert to new topic libraries, starting with an API one (sysfs, debugfs, etc), renaming liblk in the process, from Borislav Petkov. . Get rid of some more panic() like error handling in libtraceevent, from Namhyung Kim. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
fa6e8e5f7c
@ -39,10 +39,10 @@ cpupower: FORCE
|
||||
cgroup firewire guest usb virtio vm net: FORCE
|
||||
$(call descend,$@)
|
||||
|
||||
liblk: FORCE
|
||||
$(call descend,lib/lk)
|
||||
libapikfs: FORCE
|
||||
$(call descend,lib/api)
|
||||
|
||||
perf: liblk FORCE
|
||||
perf: libapikfs FORCE
|
||||
$(call descend,$@)
|
||||
|
||||
selftests: FORCE
|
||||
@ -80,10 +80,10 @@ cpupower_clean:
|
||||
cgroup_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean:
|
||||
$(call descend,$(@:_clean=),clean)
|
||||
|
||||
liblk_clean:
|
||||
$(call descend,lib/lk,clean)
|
||||
libapikfs_clean:
|
||||
$(call descend,lib/api,clean)
|
||||
|
||||
perf_clean: liblk_clean
|
||||
perf_clean: libapikfs_clean
|
||||
$(call descend,$(@:_clean=),clean)
|
||||
|
||||
selftests_clean:
|
||||
|
@ -1,4 +1,5 @@
|
||||
include ../../scripts/Makefile.include
|
||||
include ../../perf/config/utilities.mak # QUIET_CLEAN
|
||||
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
@ -7,11 +8,11 @@ AR = $(CROSS_COMPILE)ar
|
||||
LIB_H=
|
||||
LIB_OBJS=
|
||||
|
||||
LIB_H += debugfs.h
|
||||
LIB_H += fs/debugfs.h
|
||||
|
||||
LIB_OBJS += $(OUTPUT)debugfs.o
|
||||
LIB_OBJS += $(OUTPUT)fs/debugfs.o
|
||||
|
||||
LIBFILE = liblk.a
|
||||
LIBFILE = libapikfs.a
|
||||
|
||||
CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC
|
||||
EXTLIBS = -lelf -lpthread -lrt -lm
|
||||
@ -25,14 +26,17 @@ $(LIBFILE): $(LIB_OBJS)
|
||||
|
||||
$(LIB_OBJS): $(LIB_H)
|
||||
|
||||
$(OUTPUT)%.o: %.c
|
||||
libapi_dirs:
|
||||
$(QUIET_MKDIR)mkdir -p $(OUTPUT)fs/
|
||||
|
||||
$(OUTPUT)%.o: %.c libapi_dirs
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
|
||||
$(OUTPUT)%.s: %.c
|
||||
$(OUTPUT)%.s: %.c libapi_dirs
|
||||
$(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
|
||||
$(OUTPUT)%.o: %.S
|
||||
$(OUTPUT)%.o: %.S libapi_dirs
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
|
||||
|
||||
clean:
|
||||
$(RM) $(LIB_OBJS) $(LIBFILE)
|
||||
$(call QUIET_CLEAN, libapi) $(RM) $(LIB_OBJS) $(LIBFILE)
|
||||
|
||||
.PHONY: clean
|
@ -1,5 +1,5 @@
|
||||
#ifndef __LK_DEBUGFS_H__
|
||||
#define __LK_DEBUGFS_H__
|
||||
#ifndef __API_DEBUGFS_H__
|
||||
#define __API_DEBUGFS_H__
|
||||
|
||||
#define _STR(x) #x
|
||||
#define STR(x) _STR(x)
|
||||
@ -26,4 +26,4 @@ char *debugfs_mount(const char *mountpoint);
|
||||
|
||||
extern char debugfs_mountpoint[];
|
||||
|
||||
#endif /* __LK_DEBUGFS_H__ */
|
||||
#endif /* __API_DEBUGFS_H__ */
|
@ -1361,10 +1361,12 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
|
||||
if (ret >= 0 && pevent->test_filters) {
|
||||
char *test;
|
||||
test = pevent_filter_make_string(filter, event->event->id);
|
||||
if (test) {
|
||||
printf(" '%s: %s'\n", event->event->name, test);
|
||||
free(test);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_events(events);
|
||||
|
||||
@ -2050,7 +2052,6 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
int left_val = -1;
|
||||
int right_val = -1;
|
||||
int val;
|
||||
int len;
|
||||
|
||||
switch (arg->op.type) {
|
||||
case FILTER_OP_AND:
|
||||
@ -2097,11 +2098,7 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
str = malloc_or_die(6);
|
||||
if (val)
|
||||
strcpy(str, "TRUE");
|
||||
else
|
||||
strcpy(str, "FALSE");
|
||||
asprintf(&str, val ? "TRUE" : "FALSE");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2119,10 +2116,7 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
len = strlen(left) + strlen(right) + strlen(op) + 10;
|
||||
str = malloc_or_die(len);
|
||||
snprintf(str, len, "(%s) %s (%s)",
|
||||
left, op, right);
|
||||
asprintf(&str, "(%s) %s (%s)", left, op, right);
|
||||
break;
|
||||
|
||||
case FILTER_OP_NOT:
|
||||
@ -2138,16 +2132,10 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
right_val = 0;
|
||||
if (right_val >= 0) {
|
||||
/* just return the opposite */
|
||||
str = malloc_or_die(6);
|
||||
if (right_val)
|
||||
strcpy(str, "FALSE");
|
||||
else
|
||||
strcpy(str, "TRUE");
|
||||
asprintf(&str, right_val ? "FALSE" : "TRUE");
|
||||
break;
|
||||
}
|
||||
len = strlen(right) + strlen(op) + 3;
|
||||
str = malloc_or_die(len);
|
||||
snprintf(str, len, "%s(%s)", op, right);
|
||||
asprintf(&str, "%s(%s)", op, right);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2161,11 +2149,9 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
|
||||
static char *val_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
{
|
||||
char *str;
|
||||
char *str = NULL;
|
||||
|
||||
str = malloc_or_die(30);
|
||||
|
||||
snprintf(str, 30, "%lld", arg->value.val);
|
||||
asprintf(&str, "%lld", arg->value.val);
|
||||
|
||||
return str;
|
||||
}
|
||||
@ -2181,7 +2167,6 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
char *rstr;
|
||||
char *op;
|
||||
char *str = NULL;
|
||||
int len;
|
||||
|
||||
lstr = arg_to_str(filter, arg->exp.left);
|
||||
rstr = arg_to_str(filter, arg->exp.right);
|
||||
@ -2220,12 +2205,11 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
op = "^";
|
||||
break;
|
||||
default:
|
||||
die("oops in exp");
|
||||
op = "[ERROR IN EXPRESSION TYPE]";
|
||||
break;
|
||||
}
|
||||
|
||||
len = strlen(op) + strlen(lstr) + strlen(rstr) + 4;
|
||||
str = malloc_or_die(len);
|
||||
snprintf(str, len, "%s %s %s", lstr, op, rstr);
|
||||
asprintf(&str, "%s %s %s", lstr, op, rstr);
|
||||
out:
|
||||
free(lstr);
|
||||
free(rstr);
|
||||
@ -2239,7 +2223,6 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
char *rstr;
|
||||
char *str = NULL;
|
||||
char *op = NULL;
|
||||
int len;
|
||||
|
||||
lstr = arg_to_str(filter, arg->num.left);
|
||||
rstr = arg_to_str(filter, arg->num.right);
|
||||
@ -2270,10 +2253,7 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
if (!op)
|
||||
op = "<=";
|
||||
|
||||
len = strlen(lstr) + strlen(op) + strlen(rstr) + 4;
|
||||
str = malloc_or_die(len);
|
||||
sprintf(str, "%s %s %s", lstr, op, rstr);
|
||||
|
||||
asprintf(&str, "%s %s %s", lstr, op, rstr);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2291,7 +2271,6 @@ static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
{
|
||||
char *str = NULL;
|
||||
char *op = NULL;
|
||||
int len;
|
||||
|
||||
switch (arg->str.type) {
|
||||
case FILTER_CMP_MATCH:
|
||||
@ -2309,12 +2288,8 @@ static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
if (!op)
|
||||
op = "!~";
|
||||
|
||||
len = strlen(arg->str.field->name) + strlen(op) +
|
||||
strlen(arg->str.val) + 6;
|
||||
str = malloc_or_die(len);
|
||||
snprintf(str, len, "%s %s \"%s\"",
|
||||
arg->str.field->name,
|
||||
op, arg->str.val);
|
||||
asprintf(&str, "%s %s \"%s\"",
|
||||
arg->str.field->name, op, arg->str.val);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2326,15 +2301,11 @@ static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
|
||||
static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
{
|
||||
char *str;
|
||||
char *str = NULL;
|
||||
|
||||
switch (arg->type) {
|
||||
case FILTER_ARG_BOOLEAN:
|
||||
str = malloc_or_die(6);
|
||||
if (arg->boolean.value)
|
||||
strcpy(str, "TRUE");
|
||||
else
|
||||
strcpy(str, "FALSE");
|
||||
asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE");
|
||||
return str;
|
||||
|
||||
case FILTER_ARG_OP:
|
||||
@ -2369,7 +2340,7 @@ static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
|
||||
*
|
||||
* Returns a string that displays the filter contents.
|
||||
* This string must be freed with free(str).
|
||||
* NULL is returned if no filter is found.
|
||||
* NULL is returned if no filter is found or allocation failed.
|
||||
*/
|
||||
char *
|
||||
pevent_filter_make_string(struct event_filter *filter, int event_id)
|
||||
|
@ -56,9 +56,25 @@ $ perf timechart
|
||||
|
||||
Written 10.2 seconds of trace to output.svg.
|
||||
|
||||
Record system-wide timechart:
|
||||
|
||||
$ perf timechart record
|
||||
|
||||
then generate timechart and highlight 'gcc' tasks:
|
||||
|
||||
$ perf timechart --highlight gcc
|
||||
|
||||
-n::
|
||||
--proc-num::
|
||||
Print task info for at least given number of tasks.
|
||||
-t::
|
||||
--topology::
|
||||
Sort CPUs according to topology.
|
||||
--highlight=<duration_nsecs|task_name>::
|
||||
Highlight tasks (using different color) that run more than given
|
||||
duration or tasks with given name. If number is given it's interpreted
|
||||
as number of nanoseconds. If non-numeric string is given it's
|
||||
interpreted as task name.
|
||||
|
||||
RECORD OPTIONS
|
||||
--------------
|
||||
|
@ -86,7 +86,7 @@ FLEX = flex
|
||||
BISON = bison
|
||||
STRIP = strip
|
||||
|
||||
LK_DIR = $(srctree)/tools/lib/lk/
|
||||
LIB_DIR = $(srctree)/tools/lib/api/
|
||||
TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
|
||||
|
||||
# include config/Makefile by default and rule out
|
||||
@ -127,20 +127,20 @@ strip-libs = $(filter-out -l%,$(1))
|
||||
ifneq ($(OUTPUT),)
|
||||
TE_PATH=$(OUTPUT)
|
||||
ifneq ($(subdir),)
|
||||
LK_PATH=$(OUTPUT)/../lib/lk/
|
||||
LIB_PATH=$(OUTPUT)/../lib/api/
|
||||
else
|
||||
LK_PATH=$(OUTPUT)
|
||||
LIB_PATH=$(OUTPUT)
|
||||
endif
|
||||
else
|
||||
TE_PATH=$(TRACE_EVENT_DIR)
|
||||
LK_PATH=$(LK_DIR)
|
||||
LIB_PATH=$(LIB_DIR)
|
||||
endif
|
||||
|
||||
LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
|
||||
export LIBTRACEEVENT
|
||||
|
||||
LIBLK = $(LK_PATH)liblk.a
|
||||
export LIBLK
|
||||
LIBAPIKFS = $(LIB_PATH)libapikfs.a
|
||||
export LIBAPIKFS
|
||||
|
||||
# python extension build directories
|
||||
PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/
|
||||
@ -151,7 +151,7 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
|
||||
python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
|
||||
|
||||
PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
|
||||
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBLK)
|
||||
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPIKFS)
|
||||
|
||||
$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
|
||||
$(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
|
||||
@ -441,7 +441,7 @@ BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
|
||||
BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-mem.o
|
||||
|
||||
PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
|
||||
PERFLIBS = $(LIB_FILE) $(LIBAPIKFS) $(LIBTRACEEVENT)
|
||||
|
||||
# We choose to avoid "if .. else if .. else .. endif endif"
|
||||
# because maintaining the nesting to match is a pain. If
|
||||
@ -730,19 +730,19 @@ $(LIBTRACEEVENT)-clean:
|
||||
install-traceevent-plugins: $(LIBTRACEEVENT)
|
||||
$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) install_plugins
|
||||
|
||||
LIBLK_SOURCES = $(wildcard $(LK_PATH)*.[ch])
|
||||
LIBAPIKFS_SOURCES = $(wildcard $(LIB_PATH)fs/*.[ch])
|
||||
|
||||
# if subdir is set, we've been called from above so target has been built
|
||||
# already
|
||||
$(LIBLK): $(LIBLK_SOURCES)
|
||||
$(LIBAPIKFS): $(LIBAPIKFS_SOURCES)
|
||||
ifeq ($(subdir),)
|
||||
$(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) liblk.a
|
||||
$(QUIET_SUBDIR0)$(LIB_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libapikfs.a
|
||||
endif
|
||||
|
||||
$(LIBLK)-clean:
|
||||
$(LIBAPIKFS)-clean:
|
||||
ifeq ($(subdir),)
|
||||
$(call QUIET_CLEAN, liblk)
|
||||
@$(MAKE) -C $(LK_DIR) O=$(OUTPUT) clean >/dev/null
|
||||
$(call QUIET_CLEAN, libapikfs)
|
||||
@$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null
|
||||
endif
|
||||
|
||||
help:
|
||||
@ -881,12 +881,11 @@ config-clean:
|
||||
$(call QUIET_CLEAN, config)
|
||||
@$(MAKE) -C config/feature-checks clean >/dev/null
|
||||
|
||||
clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean
|
||||
clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean
|
||||
$(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS)
|
||||
$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf
|
||||
$(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex*
|
||||
$(call QUIET_CLEAN, Documentation)
|
||||
@$(MAKE) -C Documentation O=$(OUTPUT) clean >/dev/null
|
||||
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
|
||||
$(python-clean)
|
||||
|
||||
#
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "util/parse-options.h"
|
||||
#include "util/trace-event.h"
|
||||
#include "util/debug.h"
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include "util/tool.h"
|
||||
#include "util/stat.h"
|
||||
#include "util/top.h"
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "util/strfilter.h"
|
||||
#include "util/symbol.h"
|
||||
#include "util/debug.h"
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include "util/parse-options.h"
|
||||
#include "util/probe-finder.h"
|
||||
#include "util/probe-event.h"
|
||||
|
@ -58,7 +58,8 @@ struct timechart {
|
||||
first_time, last_time;
|
||||
bool power_only,
|
||||
tasks_only,
|
||||
with_backtrace;
|
||||
with_backtrace,
|
||||
topology;
|
||||
};
|
||||
|
||||
struct per_pidcomm;
|
||||
@ -531,12 +532,10 @@ static int process_sample_event(struct perf_tool *tool,
|
||||
tchart->last_time = sample->time;
|
||||
}
|
||||
|
||||
if (sample->cpu > tchart->numcpus)
|
||||
tchart->numcpus = sample->cpu;
|
||||
|
||||
if (evsel->handler != NULL) {
|
||||
tracepoint_handler f = evsel->handler;
|
||||
return f(tchart, evsel, sample, cat_backtrace(event, sample, machine));
|
||||
return f(tchart, evsel, sample,
|
||||
cat_backtrace(event, sample, machine));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -837,8 +836,14 @@ static void draw_cpu_usage(struct timechart *tchart)
|
||||
while (c) {
|
||||
sample = c->samples;
|
||||
while (sample) {
|
||||
if (sample->type == TYPE_RUNNING)
|
||||
svg_process(sample->cpu, sample->start_time, sample->end_time, "sample", c->comm);
|
||||
if (sample->type == TYPE_RUNNING) {
|
||||
svg_process(sample->cpu,
|
||||
sample->start_time,
|
||||
sample->end_time,
|
||||
p->pid,
|
||||
c->comm,
|
||||
sample->backtrace);
|
||||
}
|
||||
|
||||
sample = sample->next;
|
||||
}
|
||||
@ -1031,8 +1036,6 @@ static void write_svg_file(struct timechart *tchart, const char *filename)
|
||||
int count;
|
||||
int thresh = TIME_THRESH;
|
||||
|
||||
tchart->numcpus++;
|
||||
|
||||
if (tchart->power_only)
|
||||
tchart->proc_num = 0;
|
||||
|
||||
@ -1062,6 +1065,37 @@ static void write_svg_file(struct timechart *tchart, const char *filename)
|
||||
svg_close();
|
||||
}
|
||||
|
||||
static int process_header(struct perf_file_section *section __maybe_unused,
|
||||
struct perf_header *ph,
|
||||
int feat,
|
||||
int fd __maybe_unused,
|
||||
void *data)
|
||||
{
|
||||
struct timechart *tchart = data;
|
||||
|
||||
switch (feat) {
|
||||
case HEADER_NRCPUS:
|
||||
tchart->numcpus = ph->env.nr_cpus_avail;
|
||||
break;
|
||||
|
||||
case HEADER_CPU_TOPOLOGY:
|
||||
if (!tchart->topology)
|
||||
break;
|
||||
|
||||
if (svg_build_topology_map(ph->env.sibling_cores,
|
||||
ph->env.nr_sibling_cores,
|
||||
ph->env.sibling_threads,
|
||||
ph->env.nr_sibling_threads))
|
||||
fprintf(stderr, "problem building topology\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cmd_timechart(struct timechart *tchart, const char *output_name)
|
||||
{
|
||||
const struct perf_evsel_str_handler power_tracepoints[] = {
|
||||
@ -1087,6 +1121,11 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)
|
||||
if (session == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
(void)perf_header__process_sections(&session->header,
|
||||
perf_data_file__fd(session->file),
|
||||
tchart,
|
||||
process_header);
|
||||
|
||||
if (!perf_session__has_traces(session, "timechart record"))
|
||||
goto out_delete;
|
||||
|
||||
@ -1212,6 +1251,23 @@ parse_process(const struct option *opt __maybe_unused, const char *arg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_highlight(const struct option *opt __maybe_unused, const char *arg,
|
||||
int __maybe_unused unset)
|
||||
{
|
||||
unsigned long duration = strtoul(arg, NULL, 0);
|
||||
|
||||
if (svg_highlight || svg_highlight_name)
|
||||
return -1;
|
||||
|
||||
if (duration)
|
||||
svg_highlight = duration;
|
||||
else
|
||||
svg_highlight_name = strdup(arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_timechart(int argc, const char **argv,
|
||||
const char *prefix __maybe_unused)
|
||||
{
|
||||
@ -1230,6 +1286,9 @@ int cmd_timechart(int argc, const char **argv,
|
||||
OPT_STRING('i', "input", &input_name, "file", "input file name"),
|
||||
OPT_STRING('o', "output", &output_name, "file", "output file name"),
|
||||
OPT_INTEGER('w', "width", &svg_page_width, "page width"),
|
||||
OPT_CALLBACK(0, "highlight", NULL, "duration or task name",
|
||||
"highlight tasks. Pass duration in ns or process name.",
|
||||
parse_highlight),
|
||||
OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"),
|
||||
OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only,
|
||||
"output processes data only"),
|
||||
@ -1240,6 +1299,8 @@ int cmd_timechart(int argc, const char **argv,
|
||||
"Look for files with symbols relative to this directory"),
|
||||
OPT_INTEGER('n', "proc-num", &tchart.proc_num,
|
||||
"min. number of tasks to print"),
|
||||
OPT_BOOLEAN('t', "topology", &tchart.topology,
|
||||
"sort CPUs according to topology"),
|
||||
OPT_END()
|
||||
};
|
||||
const char * const timechart_usage[] = {
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "util/quote.h"
|
||||
#include "util/run-command.h"
|
||||
#include "util/parse-events.h"
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include <pthread.h>
|
||||
|
||||
const char perf_usage_string[] =
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "evsel.h"
|
||||
#include "evlist.h"
|
||||
#include "fs.h"
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include "tests.h"
|
||||
#include <linux/hw_breakpoint.h>
|
||||
|
||||
|
@ -28,7 +28,8 @@ char dso__symtab_origin(const struct dso *dso)
|
||||
return origin[dso->symtab_type];
|
||||
}
|
||||
|
||||
int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type,
|
||||
int dso__read_binary_type_filename(const struct dso *dso,
|
||||
enum dso_binary_type type,
|
||||
char *root_dir, char *filename, size_t size)
|
||||
{
|
||||
char build_id_hex[BUILD_ID_SIZE * 2 + 1];
|
||||
@ -137,18 +138,17 @@ int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type,
|
||||
|
||||
static int open_dso(struct dso *dso, struct machine *machine)
|
||||
{
|
||||
char *root_dir = (char *) "";
|
||||
char *name;
|
||||
int fd;
|
||||
char *root_dir = (char *)"";
|
||||
char *name = malloc(PATH_MAX);
|
||||
|
||||
name = malloc(PATH_MAX);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
if (machine)
|
||||
root_dir = machine->root_dir;
|
||||
|
||||
if (dso__binary_type_file(dso, dso->data_type,
|
||||
if (dso__read_binary_type_filename(dso, dso->binary_type,
|
||||
root_dir, name, PATH_MAX)) {
|
||||
free(name);
|
||||
return -EINVAL;
|
||||
@ -161,26 +161,26 @@ static int open_dso(struct dso *dso, struct machine *machine)
|
||||
|
||||
int dso__data_fd(struct dso *dso, struct machine *machine)
|
||||
{
|
||||
static enum dso_binary_type binary_type_data[] = {
|
||||
enum dso_binary_type binary_type_data[] = {
|
||||
DSO_BINARY_TYPE__BUILD_ID_CACHE,
|
||||
DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
|
||||
DSO_BINARY_TYPE__NOT_FOUND,
|
||||
};
|
||||
int i = 0;
|
||||
|
||||
if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND)
|
||||
if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND)
|
||||
return open_dso(dso, machine);
|
||||
|
||||
do {
|
||||
int fd;
|
||||
|
||||
dso->data_type = binary_type_data[i++];
|
||||
dso->binary_type = binary_type_data[i++];
|
||||
|
||||
fd = open_dso(dso, machine);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
|
||||
} while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND);
|
||||
} while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -475,7 +475,7 @@ struct dso *dso__new(const char *name)
|
||||
dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
|
||||
dso->cache = RB_ROOT;
|
||||
dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
|
||||
dso->data_type = DSO_BINARY_TYPE__NOT_FOUND;
|
||||
dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
|
||||
dso->loaded = 0;
|
||||
dso->rel = 0;
|
||||
dso->sorted_by_name = 0;
|
||||
|
@ -83,7 +83,7 @@ struct dso {
|
||||
enum dso_kernel_type kernel;
|
||||
enum dso_swap_type needs_swap;
|
||||
enum dso_binary_type symtab_type;
|
||||
enum dso_binary_type data_type;
|
||||
enum dso_binary_type binary_type;
|
||||
u8 adjust_symbols:1;
|
||||
u8 has_build_id:1;
|
||||
u8 has_srcline:1;
|
||||
@ -128,7 +128,7 @@ void dso__read_running_kernel_build_id(struct dso *dso,
|
||||
int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
|
||||
|
||||
char dso__symtab_origin(const struct dso *dso);
|
||||
int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type,
|
||||
int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type,
|
||||
char *root_dir, char *filename, size_t size);
|
||||
|
||||
int dso__data_fd(struct dso *dso, struct machine *machine);
|
||||
@ -159,14 +159,14 @@ size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
|
||||
|
||||
static inline bool dso__is_vmlinux(struct dso *dso)
|
||||
{
|
||||
return dso->data_type == DSO_BINARY_TYPE__VMLINUX ||
|
||||
dso->data_type == DSO_BINARY_TYPE__GUEST_VMLINUX;
|
||||
return dso->binary_type == DSO_BINARY_TYPE__VMLINUX ||
|
||||
dso->binary_type == DSO_BINARY_TYPE__GUEST_VMLINUX;
|
||||
}
|
||||
|
||||
static inline bool dso__is_kcore(struct dso *dso)
|
||||
{
|
||||
return dso->data_type == DSO_BINARY_TYPE__KCORE ||
|
||||
dso->data_type == DSO_BINARY_TYPE__GUEST_KCORE;
|
||||
return dso->binary_type == DSO_BINARY_TYPE__KCORE ||
|
||||
dso->binary_type == DSO_BINARY_TYPE__GUEST_KCORE;
|
||||
}
|
||||
|
||||
void dso__free_a2l(struct dso *dso);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Released under the GPL v2. (and only v2, not any later version)
|
||||
*/
|
||||
#include "util.h"
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include <poll.h>
|
||||
#include "cpumap.h"
|
||||
#include "thread_map.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include <traceevent/event-parse.h>
|
||||
#include <linux/hw_breakpoint.h>
|
||||
#include <linux/perf_event.h>
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "symbol.h"
|
||||
#include "cache.h"
|
||||
#include "header.h"
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include "parse-events-bison.h"
|
||||
#define YY_EXTRA_TYPE int
|
||||
#include "parse-events-flex.h"
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "color.h"
|
||||
#include "symbol.h"
|
||||
#include "thread.h"
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include "trace-event.h" /* For __maybe_unused */
|
||||
#include "probe-event.h"
|
||||
#include "probe-finder.h"
|
||||
|
@ -25,7 +25,7 @@ cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter'
|
||||
build_lib = getenv('PYTHON_EXTBUILD_LIB')
|
||||
build_tmp = getenv('PYTHON_EXTBUILD_TMP')
|
||||
libtraceevent = getenv('LIBTRACEEVENT')
|
||||
liblk = getenv('LIBLK')
|
||||
libapikfs = getenv('LIBAPIKFS')
|
||||
|
||||
ext_sources = [f.strip() for f in file('util/python-ext-sources')
|
||||
if len(f.strip()) > 0 and f[0] != '#']
|
||||
@ -34,7 +34,7 @@ perf = Extension('perf',
|
||||
sources = ext_sources,
|
||||
include_dirs = ['util/include'],
|
||||
extra_compile_args = cflags,
|
||||
extra_objects = [libtraceevent, liblk],
|
||||
extra_objects = [libtraceevent, libapikfs],
|
||||
)
|
||||
|
||||
setup(name='perf',
|
||||
|
@ -17,8 +17,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include "perf.h"
|
||||
#include "svghelper.h"
|
||||
#include "cpumap.h"
|
||||
|
||||
static u64 first_time, last_time;
|
||||
static u64 turbo_frequency, max_freq;
|
||||
@ -28,6 +31,8 @@ static u64 turbo_frequency, max_freq;
|
||||
#define SLOT_HEIGHT 25.0
|
||||
|
||||
int svg_page_width = 1000;
|
||||
u64 svg_highlight;
|
||||
const char *svg_highlight_name;
|
||||
|
||||
#define MIN_TEXT_SIZE 0.01
|
||||
|
||||
@ -39,8 +44,13 @@ static double cpu2slot(int cpu)
|
||||
return 2 * cpu + 1;
|
||||
}
|
||||
|
||||
static int *topology_map;
|
||||
|
||||
static double cpu2y(int cpu)
|
||||
{
|
||||
if (topology_map)
|
||||
return cpu2slot(topology_map[cpu]) * SLOT_MULT;
|
||||
else
|
||||
return cpu2slot(cpu) * SLOT_MULT;
|
||||
}
|
||||
|
||||
@ -104,6 +114,7 @@ void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end)
|
||||
fprintf(svgfile, " rect.process { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:1; stroke:rgb( 0, 0, 0); } \n");
|
||||
fprintf(svgfile, " rect.process2 { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
|
||||
fprintf(svgfile, " rect.sample { fill:rgb( 0, 0,255); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
|
||||
fprintf(svgfile, " rect.sample_hi{ fill:rgb(255,128, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
|
||||
fprintf(svgfile, " rect.blocked { fill:rgb(255, 0, 0); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
|
||||
fprintf(svgfile, " rect.waiting { fill:rgb(224,214, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
|
||||
fprintf(svgfile, " rect.WAITING { fill:rgb(255,214, 48); fill-opacity:0.6; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
|
||||
@ -147,17 +158,24 @@ void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
|
||||
void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
|
||||
{
|
||||
double text_size;
|
||||
const char *type;
|
||||
|
||||
if (!svgfile)
|
||||
return;
|
||||
|
||||
if (svg_highlight && end - start > svg_highlight)
|
||||
type = "sample_hi";
|
||||
else
|
||||
type = "sample";
|
||||
fprintf(svgfile, "<g>\n");
|
||||
|
||||
fprintf(svgfile, "<title>#%d running %s</title>\n",
|
||||
cpu, time_to_string(end - start));
|
||||
if (backtrace)
|
||||
fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace);
|
||||
fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"sample\"/>\n",
|
||||
time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT);
|
||||
fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"%s\"/>\n",
|
||||
time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT,
|
||||
type);
|
||||
|
||||
text_size = (time2pixels(end)-time2pixels(start));
|
||||
if (cpu > 9)
|
||||
@ -275,7 +293,7 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
|
||||
time2pixels(last_time)-time2pixels(first_time),
|
||||
cpu2y(cpu), SLOT_MULT+SLOT_HEIGHT);
|
||||
|
||||
sprintf(cpu_string, "CPU %i", (int)cpu+1);
|
||||
sprintf(cpu_string, "CPU %i", (int)cpu);
|
||||
fprintf(svgfile, "<text x=\"%4.8f\" y=\"%4.8f\">%s</text>\n",
|
||||
10+time2pixels(first_time), cpu2y(cpu) + SLOT_HEIGHT/2, cpu_string);
|
||||
|
||||
@ -285,16 +303,25 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
|
||||
fprintf(svgfile, "</g>\n");
|
||||
}
|
||||
|
||||
void svg_process(int cpu, u64 start, u64 end, const char *type, const char *name)
|
||||
void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace)
|
||||
{
|
||||
double width;
|
||||
const char *type;
|
||||
|
||||
if (!svgfile)
|
||||
return;
|
||||
|
||||
if (svg_highlight && end - start >= svg_highlight)
|
||||
type = "sample_hi";
|
||||
else if (svg_highlight_name && strstr(name, svg_highlight_name))
|
||||
type = "sample_hi";
|
||||
else
|
||||
type = "sample";
|
||||
|
||||
fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\">\n", time2pixels(start), cpu2y(cpu));
|
||||
fprintf(svgfile, "<title>%s %s</title>\n", name, time_to_string(end - start));
|
||||
fprintf(svgfile, "<title>%d %s running %s</title>\n", pid, name, time_to_string(end - start));
|
||||
if (backtrace)
|
||||
fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace);
|
||||
fprintf(svgfile, "<rect x=\"0\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n",
|
||||
time2pixels(end)-time2pixels(start), SLOT_MULT+SLOT_HEIGHT, type);
|
||||
width = time2pixels(end)-time2pixels(start);
|
||||
@ -566,3 +593,123 @@ void svg_close(void)
|
||||
svgfile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define cpumask_bits(maskp) ((maskp)->bits)
|
||||
typedef struct { DECLARE_BITMAP(bits, MAX_NR_CPUS); } cpumask_t;
|
||||
|
||||
struct topology {
|
||||
cpumask_t *sib_core;
|
||||
int sib_core_nr;
|
||||
cpumask_t *sib_thr;
|
||||
int sib_thr_nr;
|
||||
};
|
||||
|
||||
static void scan_thread_topology(int *map, struct topology *t, int cpu, int *pos)
|
||||
{
|
||||
int i;
|
||||
int thr;
|
||||
|
||||
for (i = 0; i < t->sib_thr_nr; i++) {
|
||||
if (!test_bit(cpu, cpumask_bits(&t->sib_thr[i])))
|
||||
continue;
|
||||
|
||||
for_each_set_bit(thr,
|
||||
cpumask_bits(&t->sib_thr[i]),
|
||||
MAX_NR_CPUS)
|
||||
if (map[thr] == -1)
|
||||
map[thr] = (*pos)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void scan_core_topology(int *map, struct topology *t)
|
||||
{
|
||||
int pos = 0;
|
||||
int i;
|
||||
int cpu;
|
||||
|
||||
for (i = 0; i < t->sib_core_nr; i++)
|
||||
for_each_set_bit(cpu,
|
||||
cpumask_bits(&t->sib_core[i]),
|
||||
MAX_NR_CPUS)
|
||||
scan_thread_topology(map, t, cpu, &pos);
|
||||
}
|
||||
|
||||
static int str_to_bitmap(char *s, cpumask_t *b)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
struct cpu_map *m;
|
||||
int c;
|
||||
|
||||
m = cpu_map__new(s);
|
||||
if (!m)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < m->nr; i++) {
|
||||
c = m->map[i];
|
||||
if (c >= MAX_NR_CPUS) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
set_bit(c, cpumask_bits(b));
|
||||
}
|
||||
|
||||
cpu_map__delete(m);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int svg_build_topology_map(char *sib_core, int sib_core_nr,
|
||||
char *sib_thr, int sib_thr_nr)
|
||||
{
|
||||
int i;
|
||||
struct topology t;
|
||||
|
||||
t.sib_core_nr = sib_core_nr;
|
||||
t.sib_thr_nr = sib_thr_nr;
|
||||
t.sib_core = calloc(sib_core_nr, sizeof(cpumask_t));
|
||||
t.sib_thr = calloc(sib_thr_nr, sizeof(cpumask_t));
|
||||
|
||||
if (!t.sib_core || !t.sib_thr) {
|
||||
fprintf(stderr, "topology: no memory\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < sib_core_nr; i++) {
|
||||
if (str_to_bitmap(sib_core, &t.sib_core[i])) {
|
||||
fprintf(stderr, "topology: can't parse siblings map\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sib_core += strlen(sib_core) + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < sib_thr_nr; i++) {
|
||||
if (str_to_bitmap(sib_thr, &t.sib_thr[i])) {
|
||||
fprintf(stderr, "topology: can't parse siblings map\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sib_thr += strlen(sib_thr) + 1;
|
||||
}
|
||||
|
||||
topology_map = malloc(sizeof(int) * MAX_NR_CPUS);
|
||||
if (!topology_map) {
|
||||
fprintf(stderr, "topology: no memory\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_NR_CPUS; i++)
|
||||
topology_map[i] = -1;
|
||||
|
||||
scan_core_topology(topology_map, &t);
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
free(t.sib_core);
|
||||
free(t.sib_thr);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ extern void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *back
|
||||
extern void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency);
|
||||
|
||||
|
||||
extern void svg_process(int cpu, u64 start, u64 end, const char *type, const char *name);
|
||||
extern void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace);
|
||||
extern void svg_cstate(int cpu, u64 start, u64 end, int type);
|
||||
extern void svg_pstate(int cpu, u64 start, u64 end, u64 freq);
|
||||
|
||||
@ -23,7 +23,11 @@ extern void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, cha
|
||||
extern void svg_interrupt(u64 start, int row, const char *backtrace);
|
||||
extern void svg_text(int Yslot, u64 start, const char *text);
|
||||
extern void svg_close(void);
|
||||
extern int svg_build_topology_map(char *sib_core, int sib_core_nr,
|
||||
char *sib_thr, int sib_thr_nr);
|
||||
|
||||
extern int svg_page_width;
|
||||
extern u64 svg_highlight;
|
||||
extern const char *svg_highlight_name;
|
||||
|
||||
#endif /* __PERF_SVGHELPER_H */
|
||||
|
@ -1089,9 +1089,9 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
|
||||
* dso__data_read_addr().
|
||||
*/
|
||||
if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
|
||||
dso->data_type = DSO_BINARY_TYPE__GUEST_KCORE;
|
||||
dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE;
|
||||
else
|
||||
dso->data_type = DSO_BINARY_TYPE__KCORE;
|
||||
dso->binary_type = DSO_BINARY_TYPE__KCORE;
|
||||
dso__set_long_name(dso, strdup(kcore_filename), true);
|
||||
|
||||
close(fd);
|
||||
@ -1258,7 +1258,7 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
|
||||
|
||||
enum dso_binary_type symtab_type = binary_type_symtab[i];
|
||||
|
||||
if (dso__binary_type_file(dso, symtab_type,
|
||||
if (dso__read_binary_type_filename(dso, symtab_type,
|
||||
root_dir, name, PATH_MAX))
|
||||
continue;
|
||||
|
||||
@ -1368,9 +1368,9 @@ int dso__load_vmlinux(struct dso *dso, struct map *map,
|
||||
|
||||
if (err > 0) {
|
||||
if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
|
||||
dso->data_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
|
||||
dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
|
||||
else
|
||||
dso->data_type = DSO_BINARY_TYPE__VMLINUX;
|
||||
dso->binary_type = DSO_BINARY_TYPE__VMLINUX;
|
||||
dso__set_long_name(dso, vmlinux, vmlinux_allocated);
|
||||
dso__set_loaded(dso, map->type);
|
||||
pr_debug("Using %s for symbols\n", symfs_vmlinux);
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
#include "../perf.h"
|
||||
#include "trace-event.h"
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include "evsel.h"
|
||||
|
||||
#define VERSION "0.5"
|
||||
|
@ -71,7 +71,7 @@
|
||||
#include <linux/magic.h>
|
||||
#include "types.h"
|
||||
#include <sys/ttydefaults.h>
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
#include <termios.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
|
@ -2,21 +2,21 @@
|
||||
#
|
||||
TARGETS=page-types slabinfo
|
||||
|
||||
LK_DIR = ../lib/lk
|
||||
LIBLK = $(LK_DIR)/liblk.a
|
||||
LIB_DIR = ../lib/api
|
||||
LIBS = $(LIB_DIR)/libapikfs.a
|
||||
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
CFLAGS = -Wall -Wextra -I../lib/
|
||||
LDFLAGS = $(LIBLK)
|
||||
LDFLAGS = $(LIBS)
|
||||
|
||||
$(TARGETS): liblk
|
||||
$(TARGETS): $(LIBS)
|
||||
|
||||
liblk:
|
||||
make -C $(LK_DIR)
|
||||
$(LIBS):
|
||||
make -C $(LIB_DIR)
|
||||
|
||||
%: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
$(RM) page-types slabinfo
|
||||
make -C ../lib/lk clean
|
||||
make -C $(LIB_DIR) clean
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <sys/statfs.h>
|
||||
#include "../../include/uapi/linux/magic.h"
|
||||
#include "../../include/uapi/linux/kernel-page-flags.h"
|
||||
#include <lk/debugfs.h>
|
||||
#include <api/fs/debugfs.h>
|
||||
|
||||
#ifndef MAX_PATH
|
||||
# define MAX_PATH 256
|
||||
|
Loading…
Reference in New Issue
Block a user