Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
bc4b473f
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 3 年多
通知
13
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
bc4b473f
编写于
4月 30, 2010
作者:
I
Ingo Molnar
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'perf' of
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6
into perf/core
上级
3ca50496
1c6a800c
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
725 addition
and
351 deletion
+725
-351
tools/perf/Documentation/perf-test.txt
tools/perf/Documentation/perf-test.txt
+22
-0
tools/perf/Makefile
tools/perf/Makefile
+3
-0
tools/perf/builtin-annotate.c
tools/perf/builtin-annotate.c
+1
-1
tools/perf/builtin-buildid-list.c
tools/perf/builtin-buildid-list.c
+1
-1
tools/perf/builtin-kmem.c
tools/perf/builtin-kmem.c
+4
-6
tools/perf/builtin-record.c
tools/perf/builtin-record.c
+17
-19
tools/perf/builtin-report.c
tools/perf/builtin-report.c
+1
-1
tools/perf/builtin-test.c
tools/perf/builtin-test.c
+281
-0
tools/perf/builtin-top.c
tools/perf/builtin-top.c
+7
-8
tools/perf/builtin.h
tools/perf/builtin.h
+1
-0
tools/perf/command-list.txt
tools/perf/command-list.txt
+1
-0
tools/perf/perf.c
tools/perf/perf.c
+1
-0
tools/perf/util/event.c
tools/perf/util/event.c
+42
-47
tools/perf/util/event.h
tools/perf/util/event.h
+2
-2
tools/perf/util/header.c
tools/perf/util/header.c
+33
-37
tools/perf/util/header.h
tools/perf/util/header.h
+1
-1
tools/perf/util/map.c
tools/perf/util/map.c
+64
-57
tools/perf/util/map.h
tools/perf/util/map.h
+48
-38
tools/perf/util/probe-event.c
tools/perf/util/probe-event.c
+11
-9
tools/perf/util/session.c
tools/perf/util/session.c
+4
-5
tools/perf/util/session.h
tools/perf/util/session.h
+39
-1
tools/perf/util/symbol.c
tools/perf/util/symbol.c
+128
-108
tools/perf/util/symbol.h
tools/perf/util/symbol.h
+13
-10
未找到文件。
tools/perf/Documentation/perf-test.txt
0 → 100644
浏览文件 @
bc4b473f
perf-test(1)
============
NAME
----
perf-test - Runs sanity tests.
SYNOPSIS
--------
[verse]
'perf test <options>'
DESCRIPTION
-----------
This command does assorted sanity tests, initially thru linked routines but
also will look for a directory with more tests in the form of scripts.
OPTIONS
-------
-v::
--verbose::
Be more verbose.
tools/perf/Makefile
浏览文件 @
bc4b473f
...
...
@@ -187,6 +187,8 @@ ifeq ($(ARCH),x86_64)
ARCH
:=
x86
endif
$(shell
sh
-c
'mkdir -p $(OUTPUT)arch/$(ARCH)/util/'
2>
/dev/null)
# CFLAGS and LDFLAGS are for the users to override from the command line.
#
...
...
@@ -488,6 +490,7 @@ BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
BUILTIN_OBJS
+=
$(OUTPUT)
builtin-kmem.o
BUILTIN_OBJS
+=
$(OUTPUT)
builtin-lock.o
BUILTIN_OBJS
+=
$(OUTPUT)
builtin-kvm.o
BUILTIN_OBJS
+=
$(OUTPUT)
builtin-test.o
PERFLIBS
=
$(LIB_FILE)
...
...
tools/perf/builtin-annotate.c
浏览文件 @
bc4b473f
...
...
@@ -571,7 +571,7 @@ static int __cmd_annotate(void)
perf_session__fprintf
(
session
,
stdout
);
if
(
verbose
>
2
)
dsos__fprintf
(
&
session
->
kerninfo_root
,
stdout
);
perf_session__fprintf_dsos
(
session
,
stdout
);
perf_session__collapse_resort
(
&
session
->
hists
);
perf_session__output_resort
(
&
session
->
hists
,
session
->
event_total
[
0
]);
...
...
tools/perf/builtin-buildid-list.c
浏览文件 @
bc4b473f
...
...
@@ -46,7 +46,7 @@ static int __cmd_buildid_list(void)
if
(
with_hits
)
perf_session__process_events
(
session
,
&
build_id__mark_dso_hit_ops
);
dsos__fprintf_buildid
(
&
session
->
kerninfo_root
,
stdout
,
with_hits
);
perf_session__fprintf_dsos_buildid
(
session
,
stdout
,
with_hits
);
perf_session__delete
(
session
);
return
err
;
...
...
tools/perf/builtin-kmem.c
浏览文件 @
bc4b473f
...
...
@@ -352,7 +352,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
int
n_lines
,
int
is_caller
)
{
struct
rb_node
*
next
;
struct
kernel_info
*
kerninfo
;
struct
machine
*
machine
;
printf
(
"%.102s
\n
"
,
graph_dotted_line
);
printf
(
" %-34s |"
,
is_caller
?
"Callsite"
:
"Alloc Ptr"
);
...
...
@@ -361,8 +361,8 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
next
=
rb_first
(
root
);
kerninfo
=
kerninfo__findhost
(
&
session
->
kerninfo_root
);
if
(
!
kerninfo
)
{
machine
=
perf_session__find_host_machine
(
session
);
if
(
!
machine
)
{
pr_err
(
"__print_result: couldn't find kernel information
\n
"
);
return
;
}
...
...
@@ -370,7 +370,6 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
struct
alloc_stat
*
data
=
rb_entry
(
next
,
struct
alloc_stat
,
node
);
struct
symbol
*
sym
=
NULL
;
struct
map_groups
*
kmaps
=
&
kerninfo
->
kmaps
;
struct
map
*
map
;
char
buf
[
BUFSIZ
];
u64
addr
;
...
...
@@ -378,8 +377,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
if
(
is_caller
)
{
addr
=
data
->
call_site
;
if
(
!
raw_ip
)
sym
=
map_groups__find_function
(
kmaps
,
addr
,
&
map
,
NULL
);
sym
=
machine__find_kernel_function
(
machine
,
addr
,
&
map
,
NULL
);
}
else
addr
=
data
->
ptr
;
...
...
tools/perf/builtin-record.c
浏览文件 @
bc4b473f
...
...
@@ -456,14 +456,14 @@ static void atexit_header(void)
}
}
static
void
event__synthesize_guest_os
(
struct
kernel_info
*
kerninfo
,
void
*
data
__attribute__
((
unused
)))
static
void
event__synthesize_guest_os
(
struct
machine
*
machine
,
void
*
data
)
{
int
err
;
char
*
guest_kallsyms
;
char
path
[
PATH_MAX
];
struct
perf_session
*
psession
=
data
;
if
(
is_host_kernel
(
kerninfo
))
if
(
machine__is_host
(
machine
))
return
;
/*
...
...
@@ -475,16 +475,15 @@ static void event__synthesize_guest_os(struct kernel_info *kerninfo,
*in module instead of in guest kernel.
*/
err
=
event__synthesize_modules
(
process_synthesized_event
,
session
,
kerninfo
);
psession
,
machine
);
if
(
err
<
0
)
pr_err
(
"Couldn't record guest kernel [%d]'s reference"
" relocation symbol.
\n
"
,
kerninfo
->
pid
);
" relocation symbol.
\n
"
,
machine
->
pid
);
if
(
is_default_guest
(
kerninfo
))
if
(
machine__is_default_guest
(
machine
))
guest_kallsyms
=
(
char
*
)
symbol_conf
.
default_guest_kallsyms
;
else
{
sprintf
(
path
,
"%s/proc/kallsyms"
,
kerninfo
->
root_dir
);
sprintf
(
path
,
"%s/proc/kallsyms"
,
machine
->
root_dir
);
guest_kallsyms
=
path
;
}
...
...
@@ -493,13 +492,13 @@ static void event__synthesize_guest_os(struct kernel_info *kerninfo,
* have no _text sometimes.
*/
err
=
event__synthesize_kernel_mmap
(
process_synthesized_event
,
session
,
kerninfo
,
"_text"
);
psession
,
machine
,
"_text"
);
if
(
err
<
0
)
err
=
event__synthesize_kernel_mmap
(
process_synthesized_event
,
session
,
kerninfo
,
"_stext"
);
psession
,
machine
,
"_stext"
);
if
(
err
<
0
)
pr_err
(
"Couldn't record guest kernel [%d]'s reference"
" relocation symbol.
\n
"
,
kerninfo
->
pid
);
" relocation symbol.
\n
"
,
machine
->
pid
);
}
static
int
__cmd_record
(
int
argc
,
const
char
**
argv
)
...
...
@@ -513,7 +512,7 @@ static int __cmd_record(int argc, const char **argv)
int
child_ready_pipe
[
2
],
go_pipe
[
2
];
const
bool
forks
=
argc
>
0
;
char
buf
;
struct
kernel_info
*
kerninfo
;
struct
machine
*
machine
;
page_size
=
sysconf
(
_SC_PAGE_SIZE
);
...
...
@@ -682,31 +681,30 @@ static int __cmd_record(int argc, const char **argv)
advance_output
(
err
);
}
kerninfo
=
kerninfo__findhost
(
&
session
->
kerninfo_root
);
if
(
!
kerninfo
)
{
machine
=
perf_session__find_host_machine
(
session
);
if
(
!
machine
)
{
pr_err
(
"Couldn't find native kernel information.
\n
"
);
return
-
1
;
}
err
=
event__synthesize_kernel_mmap
(
process_synthesized_event
,
session
,
kerninfo
,
"_text"
);
session
,
machine
,
"_text"
);
if
(
err
<
0
)
err
=
event__synthesize_kernel_mmap
(
process_synthesized_event
,
session
,
kerninfo
,
"_stext"
);
session
,
machine
,
"_stext"
);
if
(
err
<
0
)
{
pr_err
(
"Couldn't record kernel reference relocation symbol.
\n
"
);
return
err
;
}
err
=
event__synthesize_modules
(
process_synthesized_event
,
session
,
kerninfo
);
session
,
machine
);
if
(
err
<
0
)
{
pr_err
(
"Couldn't record kernel reference relocation symbol.
\n
"
);
return
err
;
}
if
(
perf_guest
)
kerninfo__process_allkernels
(
&
session
->
kerninfo_root
,
event__synthesize_guest_os
,
session
);
perf_session__process_machines
(
session
,
event__synthesize_guest_os
);
if
(
!
system_wide
&&
profile_cpu
==
-
1
)
event__synthesize_thread
(
target_tid
,
process_synthesized_event
,
...
...
tools/perf/builtin-report.c
浏览文件 @
bc4b473f
...
...
@@ -313,7 +313,7 @@ static int __cmd_report(void)
perf_session__fprintf
(
session
,
stdout
);
if
(
verbose
>
2
)
dsos__fprintf
(
&
session
->
kerninfo_root
,
stdout
);
perf_session__fprintf_dsos
(
session
,
stdout
);
next
=
rb_first
(
&
session
->
stats_by_id
);
while
(
next
)
{
...
...
tools/perf/builtin-test.c
0 → 100644
浏览文件 @
bc4b473f
/*
* builtin-test.c
*
* Builtin regression testing command: ever growing number of sanity tests
*/
#include "builtin.h"
#include "util/cache.h"
#include "util/debug.h"
#include "util/parse-options.h"
#include "util/session.h"
#include "util/symbol.h"
#include "util/thread.h"
static
long
page_size
;
static
int
vmlinux_matches_kallsyms_filter
(
struct
map
*
map
__used
,
struct
symbol
*
sym
)
{
bool
*
visited
=
symbol__priv
(
sym
);
*
visited
=
true
;
return
0
;
}
static
int
test__vmlinux_matches_kallsyms
(
void
)
{
int
err
=
-
1
;
struct
rb_node
*
nd
;
struct
symbol
*
sym
;
struct
map
*
kallsyms_map
,
*
vmlinux_map
;
struct
machine
kallsyms
,
vmlinux
;
enum
map_type
type
=
MAP__FUNCTION
;
struct
ref_reloc_sym
ref_reloc_sym
=
{
.
name
=
"_stext"
,
};
/*
* Step 1:
*
* Init the machines that will hold kernel, modules obtained from
* both vmlinux + .ko files and from /proc/kallsyms split by modules.
*/
machine__init
(
&
kallsyms
,
""
,
HOST_KERNEL_ID
);
machine__init
(
&
vmlinux
,
""
,
HOST_KERNEL_ID
);
/*
* Step 2:
*
* Create the kernel maps for kallsyms and the DSO where we will then
* load /proc/kallsyms. Also create the modules maps from /proc/modules
* and find the .ko files that match them in /lib/modules/`uname -r`/.
*/
if
(
machine__create_kernel_maps
(
&
kallsyms
)
<
0
)
{
pr_debug
(
"machine__create_kernel_maps "
);
return
-
1
;
}
/*
* Step 3:
*
* Load and split /proc/kallsyms into multiple maps, one per module.
*/
if
(
machine__load_kallsyms
(
&
kallsyms
,
"/proc/kallsyms"
,
type
,
NULL
)
<=
0
)
{
pr_debug
(
"dso__load_kallsyms "
);
goto
out
;
}
/*
* Step 4:
*
* kallsyms will be internally on demand sorted by name so that we can
* find the reference relocation * symbol, i.e. the symbol we will use
* to see if the running kernel was relocated by checking if it has the
* same value in the vmlinux file we load.
*/
kallsyms_map
=
machine__kernel_map
(
&
kallsyms
,
type
);
sym
=
map__find_symbol_by_name
(
kallsyms_map
,
ref_reloc_sym
.
name
,
NULL
);
if
(
sym
==
NULL
)
{
pr_debug
(
"dso__find_symbol_by_name "
);
goto
out
;
}
ref_reloc_sym
.
addr
=
sym
->
start
;
/*
* Step 5:
*
* Now repeat step 2, this time for the vmlinux file we'll auto-locate.
*/
if
(
machine__create_kernel_maps
(
&
vmlinux
)
<
0
)
{
pr_debug
(
"machine__create_kernel_maps "
);
goto
out
;
}
vmlinux_map
=
machine__kernel_map
(
&
vmlinux
,
type
);
map__kmap
(
vmlinux_map
)
->
ref_reloc_sym
=
&
ref_reloc_sym
;
/*
* Step 6:
*
* Locate a vmlinux file in the vmlinux path that has a buildid that
* matches the one of the running kernel.
*
* While doing that look if we find the ref reloc symbol, if we find it
* we'll have its ref_reloc_symbol.unrelocated_addr and then
* maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines
* to fixup the symbols.
*/
if
(
machine__load_vmlinux_path
(
&
vmlinux
,
type
,
vmlinux_matches_kallsyms_filter
)
<=
0
)
{
pr_debug
(
"machine__load_vmlinux_path "
);
goto
out
;
}
err
=
0
;
/*
* Step 7:
*
* Now look at the symbols in the vmlinux DSO and check if we find all of them
* in the kallsyms dso. For the ones that are in both, check its names and
* end addresses too.
*/
for
(
nd
=
rb_first
(
&
vmlinux_map
->
dso
->
symbols
[
type
]);
nd
;
nd
=
rb_next
(
nd
))
{
struct
symbol
*
pair
;
sym
=
rb_entry
(
nd
,
struct
symbol
,
rb_node
);
pair
=
machine__find_kernel_symbol
(
&
kallsyms
,
type
,
sym
->
start
,
NULL
,
NULL
);
if
(
pair
&&
pair
->
start
==
sym
->
start
)
{
next_pair:
if
(
strcmp
(
sym
->
name
,
pair
->
name
)
==
0
)
{
/*
* kallsyms don't have the symbol end, so we
* set that by using the next symbol start - 1,
* in some cases we get this up to a page
* wrong, trace_kmalloc when I was developing
* this code was one such example, 2106 bytes
* off the real size. More than that and we
* _really_ have a problem.
*/
s64
skew
=
sym
->
end
-
pair
->
end
;
if
(
llabs
(
skew
)
<
page_size
)
continue
;
pr_debug
(
"%#Lx: diff end addr for %s v: %#Lx k: %#Lx
\n
"
,
sym
->
start
,
sym
->
name
,
sym
->
end
,
pair
->
end
);
}
else
{
struct
rb_node
*
nnd
=
rb_prev
(
&
pair
->
rb_node
);
if
(
nnd
)
{
struct
symbol
*
next
=
rb_entry
(
nnd
,
struct
symbol
,
rb_node
);
if
(
next
->
start
==
sym
->
start
)
{
pair
=
next
;
goto
next_pair
;
}
}
pr_debug
(
"%#Lx: diff name v: %s k: %s
\n
"
,
sym
->
start
,
sym
->
name
,
pair
->
name
);
}
}
else
pr_debug
(
"%#Lx: %s not on kallsyms
\n
"
,
sym
->
start
,
sym
->
name
);
err
=
-
1
;
}
if
(
!
verbose
)
goto
out
;
pr_info
(
"Maps only in vmlinux:
\n
"
);
for
(
nd
=
rb_first
(
&
vmlinux
.
kmaps
.
maps
[
type
]);
nd
;
nd
=
rb_next
(
nd
))
{
struct
map
*
pos
=
rb_entry
(
nd
,
struct
map
,
rb_node
),
*
pair
;
/*
* If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
* the kernel will have the path for the vmlinux file being used,
* so use the short name, less descriptive but the same ("[kernel]" in
* both cases.
*/
pair
=
map_groups__find_by_name
(
&
kallsyms
.
kmaps
,
type
,
(
pos
->
dso
->
kernel
?
pos
->
dso
->
short_name
:
pos
->
dso
->
name
));
if
(
pair
)
pair
->
priv
=
1
;
else
map__fprintf
(
pos
,
stderr
);
}
pr_info
(
"Maps in vmlinux with a different name in kallsyms:
\n
"
);
for
(
nd
=
rb_first
(
&
vmlinux
.
kmaps
.
maps
[
type
]);
nd
;
nd
=
rb_next
(
nd
))
{
struct
map
*
pos
=
rb_entry
(
nd
,
struct
map
,
rb_node
),
*
pair
;
pair
=
map_groups__find
(
&
kallsyms
.
kmaps
,
type
,
pos
->
start
);
if
(
pair
==
NULL
||
pair
->
priv
)
continue
;
if
(
pair
->
start
==
pos
->
start
)
{
pair
->
priv
=
1
;
pr_info
(
" %Lx-%Lx %Lx %s in kallsyms as"
,
pos
->
start
,
pos
->
end
,
pos
->
pgoff
,
pos
->
dso
->
name
);
if
(
pos
->
pgoff
!=
pair
->
pgoff
||
pos
->
end
!=
pair
->
end
)
pr_info
(
":
\n
*%Lx-%Lx %Lx"
,
pair
->
start
,
pair
->
end
,
pair
->
pgoff
);
pr_info
(
" %s
\n
"
,
pair
->
dso
->
name
);
pair
->
priv
=
1
;
}
}
pr_info
(
"Maps only in kallsyms:
\n
"
);
for
(
nd
=
rb_first
(
&
kallsyms
.
kmaps
.
maps
[
type
]);
nd
;
nd
=
rb_next
(
nd
))
{
struct
map
*
pos
=
rb_entry
(
nd
,
struct
map
,
rb_node
);
if
(
!
pos
->
priv
)
map__fprintf
(
pos
,
stderr
);
}
out:
return
err
;
}
static
struct
test
{
const
char
*
desc
;
int
(
*
func
)(
void
);
}
tests
[]
=
{
{
.
desc
=
"vmlinux symtab matches kallsyms"
,
.
func
=
test__vmlinux_matches_kallsyms
,
},
{
.
func
=
NULL
,
},
};
static
int
__cmd_test
(
void
)
{
int
i
=
0
;
page_size
=
sysconf
(
_SC_PAGE_SIZE
);
while
(
tests
[
i
].
func
)
{
int
err
;
pr_info
(
"%2d: %s:"
,
i
+
1
,
tests
[
i
].
desc
);
pr_debug
(
"
\n
--- start ---
\n
"
);
err
=
tests
[
i
].
func
();
pr_debug
(
"---- end ----
\n
%s:"
,
tests
[
i
].
desc
);
pr_info
(
" %s
\n
"
,
err
?
"FAILED!
\n
"
:
"Ok"
);
++
i
;
}
return
0
;
}
static
const
char
*
const
test_usage
[]
=
{
"perf test [<options>]"
,
NULL
,
};
static
const
struct
option
test_options
[]
=
{
OPT_BOOLEAN
(
'v'
,
"verbose"
,
&
verbose
,
"be more verbose (show symbol address, etc)"
),
OPT_END
()
};
int
cmd_test
(
int
argc
,
const
char
**
argv
,
const
char
*
prefix
__used
)
{
argc
=
parse_options
(
argc
,
argv
,
test_options
,
test_usage
,
0
);
if
(
argc
)
usage_with_options
(
test_usage
,
test_options
);
symbol_conf
.
priv_size
=
sizeof
(
int
);
symbol_conf
.
sort_by_name
=
true
;
symbol_conf
.
try_vmlinux_path
=
true
;
if
(
symbol__init
()
<
0
)
return
-
1
;
setup_pager
();
return
__cmd_test
();
}
tools/perf/builtin-top.c
浏览文件 @
bc4b473f
...
...
@@ -854,7 +854,7 @@ static void handle_keypress(struct perf_session *session, int c)
case
'Q'
:
printf
(
"exiting.
\n
"
);
if
(
dump_symtab
)
dsos__fprintf
(
&
session
->
kerninfo_root
,
stderr
);
perf_session__fprintf_dsos
(
session
,
stderr
);
exit
(
0
);
case
's'
:
prompt_symbol
(
&
sym_filter_entry
,
"Enter details symbol"
);
...
...
@@ -982,7 +982,7 @@ static void event__process_sample(const event_t *self,
u64
ip
=
self
->
ip
.
ip
;
struct
sym_entry
*
syme
;
struct
addr_location
al
;
struct
kernel_info
*
kerninfo
;
struct
machine
*
machine
;
u8
origin
=
self
->
header
.
misc
&
PERF_RECORD_MISC_CPUMODE_MASK
;
++
samples
;
...
...
@@ -992,18 +992,17 @@ static void event__process_sample(const event_t *self,
++
us_samples
;
if
(
hide_user_symbols
)
return
;
kerninfo
=
kerninfo__findhost
(
&
session
->
kerninfo_root
);
machine
=
perf_session__find_host_machine
(
session
);
break
;
case
PERF_RECORD_MISC_KERNEL
:
++
kernel_samples
;
if
(
hide_kernel_symbols
)
return
;
kerninfo
=
kerninfo__findhost
(
&
session
->
kerninfo_root
);
machine
=
perf_session__find_host_machine
(
session
);
break
;
case
PERF_RECORD_MISC_GUEST_KERNEL
:
++
guest_kernel_samples
;
kerninfo
=
kerninfo__find
(
&
session
->
kerninfo_root
,
self
->
ip
.
pid
);
machine
=
perf_session__find_machine
(
session
,
self
->
ip
.
pid
);
break
;
case
PERF_RECORD_MISC_GUEST_USER
:
++
guest_us_samples
;
...
...
@@ -1016,7 +1015,7 @@ static void event__process_sample(const event_t *self,
return
;
}
if
(
!
kerninfo
&&
perf_guest
)
{
if
(
!
machine
&&
perf_guest
)
{
pr_err
(
"Can't find guest [%d]'s kernel information
\n
"
,
self
->
ip
.
pid
);
return
;
...
...
@@ -1041,7 +1040,7 @@ static void event__process_sample(const event_t *self,
* --hide-kernel-symbols, even if the user specifies an
* invalid --vmlinux ;-)
*/
if
(
al
.
map
==
kerninfo
->
vmlinux_maps
[
MAP__FUNCTION
]
&&
if
(
al
.
map
==
machine
->
vmlinux_maps
[
MAP__FUNCTION
]
&&
RB_EMPTY_ROOT
(
&
al
.
map
->
dso
->
symbols
[
MAP__FUNCTION
]))
{
pr_err
(
"The %s file can't be used
\n
"
,
symbol_conf
.
vmlinux_name
);
...
...
tools/perf/builtin.h
浏览文件 @
bc4b473f
...
...
@@ -33,5 +33,6 @@ extern int cmd_probe(int argc, const char **argv, const char *prefix);
extern
int
cmd_kmem
(
int
argc
,
const
char
**
argv
,
const
char
*
prefix
);
extern
int
cmd_lock
(
int
argc
,
const
char
**
argv
,
const
char
*
prefix
);
extern
int
cmd_kvm
(
int
argc
,
const
char
**
argv
,
const
char
*
prefix
);
extern
int
cmd_test
(
int
argc
,
const
char
**
argv
,
const
char
*
prefix
);
#endif
tools/perf/command-list.txt
浏览文件 @
bc4b473f
...
...
@@ -20,3 +20,4 @@ perf-probe mainporcelain common
perf-kmem mainporcelain common
perf-lock mainporcelain common
perf-kvm mainporcelain common
perf-test mainporcelain common
tools/perf/perf.c
浏览文件 @
bc4b473f
...
...
@@ -308,6 +308,7 @@ static void handle_internal_command(int argc, const char **argv)
{
"kmem"
,
cmd_kmem
,
0
},
{
"lock"
,
cmd_lock
,
0
},
{
"kvm"
,
cmd_kvm
,
0
},
{
"test"
,
cmd_test
,
0
},
};
unsigned
int
i
;
static
const
char
ext
[]
=
STRIP_EXTENSION
;
...
...
tools/perf/util/event.c
浏览文件 @
bc4b473f
...
...
@@ -172,17 +172,17 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
int
event__synthesize_modules
(
event__handler_t
process
,
struct
perf_session
*
session
,
struct
kernel_info
*
kerninfo
)
struct
machine
*
machine
)
{
struct
rb_node
*
nd
;
struct
map_groups
*
kmaps
=
&
kerninfo
->
kmaps
;
struct
map_groups
*
kmaps
=
&
machine
->
kmaps
;
u16
misc
;
/*
* kernel uses 0 for user space maps, see kernel/perf_event.c
* __perf_event_mmap
*/
if
(
is_host_kernel
(
kerninfo
))
if
(
machine__is_host
(
machine
))
misc
=
PERF_RECORD_MISC_KERNEL
;
else
misc
=
PERF_RECORD_MISC_GUEST_KERNEL
;
...
...
@@ -204,7 +204,7 @@ int event__synthesize_modules(event__handler_t process,
(
sizeof
(
ev
.
mmap
.
filename
)
-
size
));
ev
.
mmap
.
start
=
pos
->
start
;
ev
.
mmap
.
len
=
pos
->
end
-
pos
->
start
;
ev
.
mmap
.
pid
=
kerninfo
->
pid
;
ev
.
mmap
.
pid
=
machine
->
pid
;
memcpy
(
ev
.
mmap
.
filename
,
pos
->
dso
->
long_name
,
pos
->
dso
->
long_name_len
+
1
);
...
...
@@ -267,7 +267,7 @@ static int find_symbol_cb(void *arg, const char *name, char type, u64 start)
int
event__synthesize_kernel_mmap
(
event__handler_t
process
,
struct
perf_session
*
session
,
struct
kernel_info
*
kerninfo
,
struct
machine
*
machine
,
const
char
*
symbol_name
)
{
size_t
size
;
...
...
@@ -288,8 +288,8 @@ int event__synthesize_kernel_mmap(event__handler_t process,
*/
struct
process_symbol_args
args
=
{
.
name
=
symbol_name
,
};
mmap_name
=
kern_mmap_name
(
kerninfo
,
name_buff
);
if
(
is_host_kernel
(
kerninfo
))
{
mmap_name
=
machine__mmap_name
(
machine
,
name_buff
,
sizeof
(
name_buff
)
);
if
(
machine__is_host
(
machine
))
{
/*
* kernel uses PERF_RECORD_MISC_USER for user space maps,
* see kernel/perf_event.c __perf_event_mmap
...
...
@@ -298,10 +298,10 @@ int event__synthesize_kernel_mmap(event__handler_t process,
filename
=
"/proc/kallsyms"
;
}
else
{
ev
.
header
.
misc
=
PERF_RECORD_MISC_GUEST_KERNEL
;
if
(
is_default_guest
(
kerninfo
))
if
(
machine__is_default_guest
(
machine
))
filename
=
(
char
*
)
symbol_conf
.
default_guest_kallsyms
;
else
{
sprintf
(
path
,
"%s/proc/kallsyms"
,
kerninfo
->
root_dir
);
sprintf
(
path
,
"%s/proc/kallsyms"
,
machine
->
root_dir
);
filename
=
path
;
}
}
...
...
@@ -309,7 +309,7 @@ int event__synthesize_kernel_mmap(event__handler_t process,
if
(
kallsyms__parse
(
filename
,
&
args
,
find_symbol_cb
)
<=
0
)
return
-
ENOENT
;
map
=
kerninfo
->
vmlinux_maps
[
MAP__FUNCTION
];
map
=
machine
->
vmlinux_maps
[
MAP__FUNCTION
];
size
=
snprintf
(
ev
.
mmap
.
filename
,
sizeof
(
ev
.
mmap
.
filename
),
"%s%s"
,
mmap_name
,
symbol_name
)
+
1
;
size
=
ALIGN
(
size
,
sizeof
(
u64
));
...
...
@@ -318,7 +318,7 @@ int event__synthesize_kernel_mmap(event__handler_t process,
ev
.
mmap
.
pgoff
=
args
.
start
;
ev
.
mmap
.
start
=
map
->
start
;
ev
.
mmap
.
len
=
map
->
end
-
ev
.
mmap
.
start
;
ev
.
mmap
.
pid
=
kerninfo
->
pid
;
ev
.
mmap
.
pid
=
machine
->
pid
;
return
process
(
&
ev
,
session
);
}
...
...
@@ -389,18 +389,18 @@ static int event__process_kernel_mmap(event_t *self,
{
struct
map
*
map
;
char
kmmap_prefix
[
PATH_MAX
];
struct
kernel_info
*
kerninfo
;
struct
machine
*
machine
;
enum
dso_kernel_type
kernel_type
;
bool
is_kernel_mmap
;
kerninfo
=
kerninfo__findnew
(
&
session
->
kerninfo_root
,
self
->
mmap
.
pid
);
if
(
!
kerninfo
)
{
pr_err
(
"Can't find id %d's
kerninfo
\n
"
,
self
->
mmap
.
pid
);
machine
=
perf_session__findnew_machine
(
session
,
self
->
mmap
.
pid
);
if
(
!
machine
)
{
pr_err
(
"Can't find id %d's
machine
\n
"
,
self
->
mmap
.
pid
);
goto
out_problem
;
}
kern_mmap_name
(
kerninfo
,
kmmap_prefix
);
if
(
is_host_kernel
(
kerninfo
))
machine__mmap_name
(
machine
,
kmmap_prefix
,
sizeof
(
kmmap_prefix
)
);
if
(
machine__is_host
(
machine
))
kernel_type
=
DSO_TYPE_KERNEL
;
else
kernel_type
=
DSO_TYPE_GUEST_KERNEL
;
...
...
@@ -429,10 +429,8 @@ static int event__process_kernel_mmap(event_t *self,
}
else
strcpy
(
short_module_name
,
self
->
mmap
.
filename
);
map
=
map_groups__new_module
(
&
kerninfo
->
kmaps
,
self
->
mmap
.
start
,
self
->
mmap
.
filename
,
kerninfo
);
map
=
machine__new_module
(
machine
,
self
->
mmap
.
start
,
self
->
mmap
.
filename
);
if
(
map
==
NULL
)
goto
out_problem
;
...
...
@@ -449,27 +447,25 @@ static int event__process_kernel_mmap(event_t *self,
* Should be there already, from the build-id table in
* the header.
*/
struct
dso
*
kernel
=
__dsos__findnew
(
&
kerninfo
->
dsos__kernel
,
kmmap_prefix
);
struct
dso
*
kernel
=
__dsos__findnew
(
&
machine
->
kernel_dsos
,
kmmap_prefix
);
if
(
kernel
==
NULL
)
goto
out_problem
;
kernel
->
kernel
=
kernel_type
;
if
(
__map_groups__create_kernel_maps
(
&
kerninfo
->
kmaps
,
kerninfo
->
vmlinux_maps
,
kernel
)
<
0
)
if
(
__machine__create_kernel_maps
(
machine
,
kernel
)
<
0
)
goto
out_problem
;
event_set_kernel_mmap_len
(
kerninfo
->
vmlinux_maps
,
self
);
perf_session__set_kallsyms_ref_reloc_sym
(
kerninfo
->
vmlinux_maps
,
symbol_name
,
self
->
mmap
.
pgoff
);
if
(
is_default_guest
(
kerninfo
))
{
event_set_kernel_mmap_len
(
machine
->
vmlinux_maps
,
self
);
perf_session__set_kallsyms_ref_reloc_sym
(
machine
->
vmlinux_maps
,
symbol_name
,
self
->
mmap
.
pgoff
);
if
(
machine__is_default_guest
(
machine
))
{
/*
* preload dso of guest kernel and modules
*/
dso__load
(
kernel
,
kerninfo
->
vmlinux_maps
[
MAP__FUNCTION
],
NULL
);
dso__load
(
kernel
,
machine
->
vmlinux_maps
[
MAP__FUNCTION
],
NULL
);
}
}
return
0
;
...
...
@@ -479,7 +475,7 @@ static int event__process_kernel_mmap(event_t *self,
int
event__process_mmap
(
event_t
*
self
,
struct
perf_session
*
session
)
{
struct
kernel_info
*
kerninfo
;
struct
machine
*
machine
;
struct
thread
*
thread
;
struct
map
*
map
;
u8
cpumode
=
self
->
header
.
misc
&
PERF_RECORD_MISC_CPUMODE_MASK
;
...
...
@@ -498,8 +494,8 @@ int event__process_mmap(event_t *self, struct perf_session *session)
}
thread
=
perf_session__findnew
(
session
,
self
->
mmap
.
pid
);
kerninfo
=
kerninfo__findhost
(
&
session
->
kerninfo_root
);
map
=
map__new
(
&
kerninfo
->
dsos__user
,
self
->
mmap
.
start
,
machine
=
perf_session__find_host_machine
(
session
);
map
=
map__new
(
&
machine
->
user_dsos
,
self
->
mmap
.
start
,
self
->
mmap
.
len
,
self
->
mmap
.
pgoff
,
self
->
mmap
.
pid
,
self
->
mmap
.
filename
,
MAP__FUNCTION
,
session
->
cwd
,
session
->
cwdlen
);
...
...
@@ -546,7 +542,7 @@ void thread__find_addr_map(struct thread *self,
struct
addr_location
*
al
)
{
struct
map_groups
*
mg
=
&
self
->
mg
;
struct
kernel_info
*
kerninfo
=
NULL
;
struct
machine
*
machine
=
NULL
;
al
->
thread
=
self
;
al
->
addr
=
addr
;
...
...
@@ -555,19 +551,19 @@ void thread__find_addr_map(struct thread *self,
if
(
cpumode
==
PERF_RECORD_MISC_KERNEL
&&
perf_host
)
{
al
->
level
=
'k'
;
kerninfo
=
kerninfo__findhost
(
&
session
->
kerninfo_root
);
mg
=
&
kerninfo
->
kmaps
;
machine
=
perf_session__find_host_machine
(
session
);
mg
=
&
machine
->
kmaps
;
}
else
if
(
cpumode
==
PERF_RECORD_MISC_USER
&&
perf_host
)
{
al
->
level
=
'.'
;
kerninfo
=
kerninfo__findhost
(
&
session
->
kerninfo_root
);
machine
=
perf_session__find_host_machine
(
session
);
}
else
if
(
cpumode
==
PERF_RECORD_MISC_GUEST_KERNEL
&&
perf_guest
)
{
al
->
level
=
'g'
;
kerninfo
=
kerninfo__find
(
&
session
->
kerninfo_root
,
pid
);
if
(
!
kerninfo
)
{
machine
=
perf_session__find_machine
(
session
,
pid
);
if
(
!
machine
)
{
al
->
map
=
NULL
;
return
;
}
mg
=
&
kerninfo
->
kmaps
;
mg
=
&
machine
->
kmaps
;
}
else
{
/*
* 'u' means guest os user space.
...
...
@@ -603,10 +599,9 @@ void thread__find_addr_map(struct thread *self,
* in the whole kernel symbol list.
*/
if
((
long
long
)
al
->
addr
<
0
&&
cpumode
==
PERF_RECORD_MISC_KERNEL
&&
kerninfo
&&
mg
!=
&
kerninfo
->
kmaps
)
{
mg
=
&
kerninfo
->
kmaps
;
cpumode
==
PERF_RECORD_MISC_KERNEL
&&
machine
&&
mg
!=
&
machine
->
kmaps
)
{
mg
=
&
machine
->
kmaps
;
goto
try_again
;
}
}
else
...
...
tools/perf/util/event.h
浏览文件 @
bc4b473f
...
...
@@ -156,12 +156,12 @@ void event__synthesize_threads(event__handler_t process,
struct
perf_session
*
session
);
int
event__synthesize_kernel_mmap
(
event__handler_t
process
,
struct
perf_session
*
session
,
struct
kernel_info
*
kerninfo
,
struct
machine
*
machine
,
const
char
*
symbol_name
);
int
event__synthesize_modules
(
event__handler_t
process
,
struct
perf_session
*
session
,
struct
kernel_info
*
kerninfo
);
struct
machine
*
machine
);
int
event__process_comm
(
event_t
*
self
,
struct
perf_session
*
session
);
int
event__process_lost
(
event_t
*
self
,
struct
perf_session
*
session
);
...
...
tools/perf/util/header.c
浏览文件 @
bc4b473f
...
...
@@ -229,10 +229,9 @@ static int dsos__write_buildid_table(struct perf_header *header, int fd)
int
err
=
0
;
u16
kmisc
,
umisc
;
for
(
nd
=
rb_first
(
&
session
->
kerninfo_root
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
kernel_info
*
pos
=
rb_entry
(
nd
,
struct
kernel_info
,
rb_node
);
if
(
is_host_kernel
(
pos
))
{
for
(
nd
=
rb_first
(
&
session
->
machines
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
machine
*
pos
=
rb_entry
(
nd
,
struct
machine
,
rb_node
);
if
(
machine__is_host
(
pos
))
{
kmisc
=
PERF_RECORD_MISC_KERNEL
;
umisc
=
PERF_RECORD_MISC_USER
;
}
else
{
...
...
@@ -240,11 +239,11 @@ static int dsos__write_buildid_table(struct perf_header *header, int fd)
umisc
=
PERF_RECORD_MISC_GUEST_USER
;
}
err
=
__dsos__write_buildid_table
(
&
pos
->
dsos__kernel
,
pos
->
pid
,
kmisc
,
fd
);
err
=
__dsos__write_buildid_table
(
&
pos
->
kernel_dsos
,
pos
->
pid
,
kmisc
,
fd
);
if
(
err
==
0
)
err
=
__dsos__write_buildid_table
(
&
pos
->
dsos__user
,
pos
->
pid
,
umisc
,
fd
);
err
=
__dsos__write_buildid_table
(
&
pos
->
user_dsos
,
pos
->
pid
,
umisc
,
fd
);
if
(
err
)
break
;
}
...
...
@@ -378,11 +377,10 @@ static int dsos__cache_build_ids(struct perf_header *self)
if
(
mkdir
(
debugdir
,
0755
)
!=
0
&&
errno
!=
EEXIST
)
return
-
1
;
for
(
nd
=
rb_first
(
&
session
->
kerninfo_root
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
kernel_info
*
pos
=
rb_entry
(
nd
,
struct
kernel_info
,
rb_node
);
ret
|=
__dsos__cache_build_ids
(
&
pos
->
dsos__kernel
,
debugdir
);
ret
|=
__dsos__cache_build_ids
(
&
pos
->
dsos__user
,
debugdir
);
for
(
nd
=
rb_first
(
&
session
->
machines
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
machine
*
pos
=
rb_entry
(
nd
,
struct
machine
,
rb_node
);
ret
|=
__dsos__cache_build_ids
(
&
pos
->
kernel_dsos
,
debugdir
);
ret
|=
__dsos__cache_build_ids
(
&
pos
->
user_dsos
,
debugdir
);
}
return
ret
?
-
1
:
0
;
}
...
...
@@ -394,11 +392,10 @@ static bool dsos__read_build_ids(struct perf_header *self, bool with_hits)
struct
perf_session
,
header
);
struct
rb_node
*
nd
;
for
(
nd
=
rb_first
(
&
session
->
kerninfo_root
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
kernel_info
*
pos
=
rb_entry
(
nd
,
struct
kernel_info
,
rb_node
);
ret
|=
__dsos__read_build_ids
(
&
pos
->
dsos__kernel
,
with_hits
);
ret
|=
__dsos__read_build_ids
(
&
pos
->
dsos__user
,
with_hits
);
for
(
nd
=
rb_first
(
&
session
->
machines
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
machine
*
pos
=
rb_entry
(
nd
,
struct
machine
,
rb_node
);
ret
|=
__dsos__read_build_ids
(
&
pos
->
kernel_dsos
,
with_hits
);
ret
|=
__dsos__read_build_ids
(
&
pos
->
user_dsos
,
with_hits
);
}
return
ret
;
...
...
@@ -685,13 +682,13 @@ static int __event_process_build_id(struct build_id_event *bev,
{
int
err
=
-
1
;
struct
list_head
*
head
;
struct
kernel_info
*
kerninfo
;
struct
machine
*
machine
;
u16
misc
;
struct
dso
*
dso
;
enum
dso_kernel_type
dso_type
;
kerninfo
=
kerninfo__findnew
(
&
session
->
kerninfo_root
,
bev
->
pid
);
if
(
!
kerninfo
)
machine
=
perf_session__findnew_machine
(
session
,
bev
->
pid
);
if
(
!
machine
)
goto
out
;
misc
=
bev
->
header
.
misc
&
PERF_RECORD_MISC_CPUMODE_MASK
;
...
...
@@ -699,16 +696,16 @@ static int __event_process_build_id(struct build_id_event *bev,
switch
(
misc
)
{
case
PERF_RECORD_MISC_KERNEL
:
dso_type
=
DSO_TYPE_KERNEL
;
head
=
&
kerninfo
->
dsos__kernel
;
head
=
&
machine
->
kernel_dsos
;
break
;
case
PERF_RECORD_MISC_GUEST_KERNEL
:
dso_type
=
DSO_TYPE_GUEST_KERNEL
;
head
=
&
kerninfo
->
dsos__kernel
;
head
=
&
machine
->
kernel_dsos
;
break
;
case
PERF_RECORD_MISC_USER
:
case
PERF_RECORD_MISC_GUEST_USER
:
dso_type
=
DSO_TYPE_USER
;
head
=
&
kerninfo
->
dsos__user
;
head
=
&
machine
->
user_dsos
;
break
;
default:
goto
out
;
...
...
@@ -1113,8 +1110,7 @@ int event__process_tracing_data(event_t *self,
}
int
event__synthesize_build_id
(
struct
dso
*
pos
,
u16
misc
,
event__handler_t
process
,
struct
kernel_info
*
kerninfo
,
event__handler_t
process
,
struct
machine
*
machine
,
struct
perf_session
*
session
)
{
event_t
ev
;
...
...
@@ -1131,7 +1127,7 @@ int event__synthesize_build_id(struct dso *pos, u16 misc,
memcpy
(
&
ev
.
build_id
.
build_id
,
pos
->
build_id
,
sizeof
(
pos
->
build_id
));
ev
.
build_id
.
header
.
type
=
PERF_RECORD_HEADER_BUILD_ID
;
ev
.
build_id
.
header
.
misc
=
misc
;
ev
.
build_id
.
pid
=
kerninfo
->
pid
;
ev
.
build_id
.
pid
=
machine
->
pid
;
ev
.
build_id
.
header
.
size
=
sizeof
(
ev
.
build_id
)
+
len
;
memcpy
(
&
ev
.
build_id
.
filename
,
pos
->
long_name
,
pos
->
long_name_len
);
...
...
@@ -1142,7 +1138,7 @@ int event__synthesize_build_id(struct dso *pos, u16 misc,
static
int
__event_synthesize_build_ids
(
struct
list_head
*
head
,
u16
misc
,
event__handler_t
process
,
struct
kernel_info
*
kerninfo
,
struct
machine
*
machine
,
struct
perf_session
*
session
)
{
struct
dso
*
pos
;
...
...
@@ -1153,7 +1149,7 @@ static int __event_synthesize_build_ids(struct list_head *head, u16 misc,
continue
;
err
=
event__synthesize_build_id
(
pos
,
misc
,
process
,
kerninfo
,
session
);
machine
,
session
);
if
(
err
<
0
)
return
err
;
}
...
...
@@ -1166,15 +1162,15 @@ int event__synthesize_build_ids(event__handler_t process,
{
int
err
=
0
;
u16
kmisc
,
umisc
;
struct
kernel_info
*
pos
;
struct
machine
*
pos
;
struct
rb_node
*
nd
;
if
(
!
dsos__read_build_ids
(
&
session
->
header
,
true
))
return
0
;
for
(
nd
=
rb_first
(
&
session
->
kerninfo_root
);
nd
;
nd
=
rb_next
(
nd
))
{
pos
=
rb_entry
(
nd
,
struct
kernel_info
,
rb_node
);
if
(
is_host_kernel
(
pos
))
{
for
(
nd
=
rb_first
(
&
session
->
machines
);
nd
;
nd
=
rb_next
(
nd
))
{
pos
=
rb_entry
(
nd
,
struct
machine
,
rb_node
);
if
(
machine__is_host
(
pos
))
{
kmisc
=
PERF_RECORD_MISC_KERNEL
;
umisc
=
PERF_RECORD_MISC_USER
;
}
else
{
...
...
@@ -1182,11 +1178,11 @@ int event__synthesize_build_ids(event__handler_t process,
umisc
=
PERF_RECORD_MISC_GUEST_USER
;
}
err
=
__event_synthesize_build_ids
(
&
pos
->
dsos__kernel
,
kmisc
,
process
,
pos
,
session
);
err
=
__event_synthesize_build_ids
(
&
pos
->
kernel_dsos
,
kmisc
,
process
,
pos
,
session
);
if
(
err
==
0
)
err
=
__event_synthesize_build_ids
(
&
pos
->
dsos__user
,
umisc
,
process
,
pos
,
session
);
err
=
__event_synthesize_build_ids
(
&
pos
->
user_dsos
,
umisc
,
process
,
pos
,
session
);
if
(
err
)
break
;
}
...
...
tools/perf/util/header.h
浏览文件 @
bc4b473f
...
...
@@ -120,7 +120,7 @@ int event__process_tracing_data(event_t *self,
int
event__synthesize_build_id
(
struct
dso
*
pos
,
u16
misc
,
event__handler_t
process
,
struct
kernel_info
*
kerninfo
,
struct
machine
*
machine
,
struct
perf_session
*
session
);
int
event__synthesize_build_ids
(
event__handler_t
process
,
struct
perf_session
*
session
);
...
...
tools/perf/util/map.c
浏览文件 @
bc4b473f
...
...
@@ -245,7 +245,7 @@ void map_groups__init(struct map_groups *self)
self
->
maps
[
i
]
=
RB_ROOT
;
INIT_LIST_HEAD
(
&
self
->
removed_maps
[
i
]);
}
self
->
this_kerninfo
=
NULL
;
self
->
machine
=
NULL
;
}
void
map_groups__flush
(
struct
map_groups
*
self
)
...
...
@@ -513,133 +513,140 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
return
NULL
;
}
struct
kernel_info
*
add_new_kernel_info
(
struct
rb_root
*
kerninfo_root
,
pid_t
pid
,
const
char
*
root_dir
)
int
machine__init
(
struct
machine
*
self
,
const
char
*
root_dir
,
pid_t
pid
)
{
struct
rb_node
**
p
=
&
kerninfo_root
->
rb_node
;
map_groups__init
(
&
self
->
kmaps
);
RB_CLEAR_NODE
(
&
self
->
rb_node
);
INIT_LIST_HEAD
(
&
self
->
user_dsos
);
INIT_LIST_HEAD
(
&
self
->
kernel_dsos
);
self
->
kmaps
.
machine
=
self
;
self
->
pid
=
pid
;
self
->
root_dir
=
strdup
(
root_dir
);
return
self
->
root_dir
==
NULL
?
-
ENOMEM
:
0
;
}
struct
machine
*
machines__add
(
struct
rb_root
*
self
,
pid_t
pid
,
const
char
*
root_dir
)
{
struct
rb_node
**
p
=
&
self
->
rb_node
;
struct
rb_node
*
parent
=
NULL
;
struct
kernel_info
*
kerninfo
,
*
pos
;
struct
machine
*
pos
,
*
machine
=
malloc
(
sizeof
(
*
machine
))
;
kerninfo
=
malloc
(
sizeof
(
struct
kernel_info
));
if
(
!
kerninfo
)
if
(
!
machine
)
return
NULL
;
kerninfo
->
pid
=
pid
;
map_groups__init
(
&
kerninfo
->
kmaps
);
kerninfo
->
root_dir
=
strdup
(
root_dir
);
RB_CLEAR_NODE
(
&
kerninfo
->
rb_node
);
INIT_LIST_HEAD
(
&
kerninfo
->
dsos__user
);
INIT_LIST_HEAD
(
&
kerninfo
->
dsos__kernel
);
kerninfo
->
kmaps
.
this_kerninfo
=
kerninfo
;
if
(
machine__init
(
machine
,
root_dir
,
pid
)
!=
0
)
{
free
(
machine
);
return
NULL
;
}
while
(
*
p
!=
NULL
)
{
parent
=
*
p
;
pos
=
rb_entry
(
parent
,
struct
kernel_info
,
rb_node
);
pos
=
rb_entry
(
parent
,
struct
machine
,
rb_node
);
if
(
pid
<
pos
->
pid
)
p
=
&
(
*
p
)
->
rb_left
;
else
p
=
&
(
*
p
)
->
rb_right
;
}
rb_link_node
(
&
kerninfo
->
rb_node
,
parent
,
p
);
rb_insert_color
(
&
kerninfo
->
rb_node
,
kerninfo_root
);
rb_link_node
(
&
machine
->
rb_node
,
parent
,
p
);
rb_insert_color
(
&
machine
->
rb_node
,
self
);
return
kerninfo
;
return
machine
;
}
struct
kernel_info
*
kerninfo__find
(
struct
rb_root
*
kerninfo_root
,
pid_t
pid
)
struct
machine
*
machines__find
(
struct
rb_root
*
self
,
pid_t
pid
)
{
struct
rb_node
**
p
=
&
kerninfo_root
->
rb_node
;
struct
rb_node
**
p
=
&
self
->
rb_node
;
struct
rb_node
*
parent
=
NULL
;
struct
kernel_info
*
kerninfo
;
struct
kernel_info
*
default_kerninfo
=
NULL
;
struct
machine
*
machine
;
struct
machine
*
default_machine
=
NULL
;
while
(
*
p
!=
NULL
)
{
parent
=
*
p
;
kerninfo
=
rb_entry
(
parent
,
struct
kernel_info
,
rb_node
);
if
(
pid
<
kerninfo
->
pid
)
machine
=
rb_entry
(
parent
,
struct
machine
,
rb_node
);
if
(
pid
<
machine
->
pid
)
p
=
&
(
*
p
)
->
rb_left
;
else
if
(
pid
>
kerninfo
->
pid
)
else
if
(
pid
>
machine
->
pid
)
p
=
&
(
*
p
)
->
rb_right
;
else
return
kerninfo
;
if
(
!
kerninfo
->
pid
)
default_
kerninfo
=
kerninfo
;
return
machine
;
if
(
!
machine
->
pid
)
default_
machine
=
machine
;
}
return
default_
kerninfo
;
return
default_
machine
;
}
struct
kernel_info
*
kerninfo__findhost
(
struct
rb_root
*
kerninfo_root
)
/*
* FIXME: Why repeatedly search for this?
*/
struct
machine
*
machines__find_host
(
struct
rb_root
*
self
)
{
struct
rb_node
**
p
=
&
kerninfo_root
->
rb_node
;
struct
rb_node
**
p
=
&
self
->
rb_node
;
struct
rb_node
*
parent
=
NULL
;
struct
kernel_info
*
kerninfo
;
struct
machine
*
machine
;
pid_t
pid
=
HOST_KERNEL_ID
;
while
(
*
p
!=
NULL
)
{
parent
=
*
p
;
kerninfo
=
rb_entry
(
parent
,
struct
kernel_info
,
rb_node
);
if
(
pid
<
kerninfo
->
pid
)
machine
=
rb_entry
(
parent
,
struct
machine
,
rb_node
);
if
(
pid
<
machine
->
pid
)
p
=
&
(
*
p
)
->
rb_left
;
else
if
(
pid
>
kerninfo
->
pid
)
else
if
(
pid
>
machine
->
pid
)
p
=
&
(
*
p
)
->
rb_right
;
else
return
kerninfo
;
return
machine
;
}
return
NULL
;
}
struct
kernel_info
*
kerninfo__findnew
(
struct
rb_root
*
kerninfo_root
,
pid_t
pid
)
struct
machine
*
machines__findnew
(
struct
rb_root
*
self
,
pid_t
pid
)
{
char
path
[
PATH_MAX
];
const
char
*
root_dir
;
int
ret
;
struct
kernel_info
*
kerninfo
=
kerninfo__find
(
kerninfo_root
,
pid
);
struct
machine
*
machine
=
machines__find
(
self
,
pid
);
if
(
!
kerninfo
||
kerninfo
->
pid
!=
pid
)
{
if
(
!
machine
||
machine
->
pid
!=
pid
)
{
if
(
pid
==
HOST_KERNEL_ID
||
pid
==
DEFAULT_GUEST_KERNEL_ID
)
root_dir
=
""
;
else
{
if
(
!
symbol_conf
.
guestmount
)
goto
out
;
sprintf
(
path
,
"%s/%d"
,
symbol_conf
.
guestmount
,
pid
);
ret
=
access
(
path
,
R_OK
);
if
(
ret
)
{
if
(
access
(
path
,
R_OK
))
{
pr_err
(
"Can't access file %s
\n
"
,
path
);
goto
out
;
}
root_dir
=
path
;
}
kerninfo
=
add_new_kernel_info
(
kerninfo_root
,
pid
,
root_dir
);
machine
=
machines__add
(
self
,
pid
,
root_dir
);
}
out:
return
kerninfo
;
return
machine
;
}
void
kerninfo__process_allkernels
(
struct
rb_root
*
kerninfo_root
,
process_kernel_info
process
,
void
*
data
)
void
machines__process
(
struct
rb_root
*
self
,
machine__process_t
process
,
void
*
data
)
{
struct
rb_node
*
nd
;
for
(
nd
=
rb_first
(
kerninfo_root
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
kernel_info
*
pos
=
rb_entry
(
nd
,
struct
kernel_info
,
rb_node
);
for
(
nd
=
rb_first
(
self
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
machine
*
pos
=
rb_entry
(
nd
,
struct
machine
,
rb_node
);
process
(
pos
,
data
);
}
}
char
*
kern_mmap_name
(
struct
kernel_info
*
kerninfo
,
char
*
buff
)
char
*
machine__mmap_name
(
struct
machine
*
self
,
char
*
bf
,
size_t
size
)
{
if
(
is_host_kernel
(
kerninfo
))
s
printf
(
buff
,
"[%s]"
,
"kernel.kallsyms"
);
else
if
(
is_default_guest
(
kerninfo
))
s
printf
(
buff
,
"[%s]"
,
"guest.kernel.kallsyms"
);
if
(
machine__is_host
(
self
))
s
nprintf
(
bf
,
size
,
"[%s]"
,
"kernel.kallsyms"
);
else
if
(
machine__is_default_guest
(
self
))
s
nprintf
(
bf
,
size
,
"[%s]"
,
"guest.kernel.kallsyms"
);
else
s
printf
(
buff
,
"[%s.%d]"
,
"guest.kernel.kallsyms"
,
kerninfo
->
pid
);
s
nprintf
(
bf
,
size
,
"[%s.%d]"
,
"guest.kernel.kallsyms"
,
self
->
pid
);
return
b
uf
f
;
return
bf
;
}
tools/perf/util/map.h
浏览文件 @
bc4b473f
...
...
@@ -5,6 +5,7 @@
#include <linux/list.h>
#include <linux/rbtree.h>
#include <stdio.h>
#include <stdbool.h>
#include "types.h"
enum
map_type
{
...
...
@@ -19,7 +20,7 @@ extern const char *map_type__name[MAP__NR_TYPES];
struct
dso
;
struct
ref_reloc_sym
;
struct
map_groups
;
struct
kernel_info
;
struct
machine
;
struct
map
{
union
{
...
...
@@ -29,6 +30,7 @@ struct map {
u64
start
;
u64
end
;
enum
map_type
type
;
u32
priv
;
u64
pgoff
;
/* ip -> dso rip */
...
...
@@ -46,25 +48,31 @@ struct kmap {
};
struct
map_groups
{
struct
rb_root
maps
[
MAP__NR_TYPES
];
struct
list_head
removed_maps
[
MAP__NR_TYPES
];
struct
kernel_info
*
this_kerninfo
;
struct
rb_root
maps
[
MAP__NR_TYPES
];
struct
list_head
removed_maps
[
MAP__NR_TYPES
];
struct
machine
*
machine
;
};
/* Native host kernel uses -1 as pid index in
kernel_info
*/
/* Native host kernel uses -1 as pid index in
machine
*/
#define HOST_KERNEL_ID (-1)
#define DEFAULT_GUEST_KERNEL_ID (0)
struct
kernel_info
{
struct
rb_node
rb_node
;
pid_t
pid
;
char
*
root_dir
;
struct
list_head
dsos__user
;
struct
list_head
dsos__kernel
;
struct
machine
{
struct
rb_node
rb_node
;
pid_t
pid
;
char
*
root_dir
;
struct
list_head
user_dsos
;
struct
list_head
kernel_dsos
;
struct
map_groups
kmaps
;
struct
map
*
vmlinux_maps
[
MAP__NR_TYPES
];
struct
map
*
vmlinux_maps
[
MAP__NR_TYPES
];
};
static
inline
struct
map
*
machine__kernel_map
(
struct
machine
*
self
,
enum
map_type
type
)
{
return
self
->
vmlinux_maps
[
type
];
}
static
inline
struct
kmap
*
map__kmap
(
struct
map
*
self
)
{
return
(
struct
kmap
*
)(
self
+
1
);
...
...
@@ -124,36 +132,31 @@ int map_groups__clone(struct map_groups *self,
size_t
map_groups__fprintf
(
struct
map_groups
*
self
,
int
verbose
,
FILE
*
fp
);
size_t
map_groups__fprintf_maps
(
struct
map_groups
*
self
,
int
verbose
,
FILE
*
fp
);
struct
kernel_info
*
add_new_kernel_info
(
struct
rb_root
*
kerninfo_root
,
pid_t
pid
,
const
char
*
root_dir
);
struct
kernel_info
*
kerninfo__find
(
struct
rb_root
*
kerninfo_root
,
pid_t
pid
);
struct
kernel_info
*
kerninfo__findnew
(
struct
rb_root
*
kerninfo_root
,
pid_t
pid
);
struct
kernel_info
*
kerninfo__findhost
(
struct
rb_root
*
kerninfo_root
);
char
*
kern_mmap_name
(
struct
kernel_info
*
kerninfo
,
char
*
buff
);
typedef
void
(
*
machine__process_t
)(
struct
machine
*
self
,
void
*
data
);
void
machines__process
(
struct
rb_root
*
self
,
machine__process_t
process
,
void
*
data
);
struct
machine
*
machines__add
(
struct
rb_root
*
self
,
pid_t
pid
,
const
char
*
root_dir
);
struct
machine
*
machines__find_host
(
struct
rb_root
*
self
);
struct
machine
*
machines__find
(
struct
rb_root
*
self
,
pid_t
pid
);
struct
machine
*
machines__findnew
(
struct
rb_root
*
self
,
pid_t
pid
);
char
*
machine__mmap_name
(
struct
machine
*
self
,
char
*
bf
,
size_t
size
);
int
machine__init
(
struct
machine
*
self
,
const
char
*
root_dir
,
pid_t
pid
);
/*
* Default guest kernel is defined by parameter --guestkallsyms
* and --guestmodules
*/
static
inline
int
is_default_guest
(
struct
kernel_info
*
kerninfo
)
static
inline
bool
machine__is_default_guest
(
struct
machine
*
self
)
{
if
(
!
kerninfo
)
return
0
;
return
kerninfo
->
pid
==
DEFAULT_GUEST_KERNEL_ID
;
return
self
?
self
->
pid
==
DEFAULT_GUEST_KERNEL_ID
:
false
;
}
static
inline
int
is_host_kernel
(
struct
kernel_info
*
kerninfo
)
static
inline
bool
machine__is_host
(
struct
machine
*
self
)
{
if
(
!
kerninfo
)
return
0
;
return
kerninfo
->
pid
==
HOST_KERNEL_ID
;
return
self
?
self
->
pid
==
HOST_KERNEL_ID
:
false
;
}
typedef
void
(
*
process_kernel_info
)(
struct
kernel_info
*
kerninfo
,
void
*
data
);
void
kerninfo__process_allkernels
(
struct
rb_root
*
kerninfo_root
,
process_kernel_info
process
,
void
*
data
);
static
inline
void
map_groups__insert
(
struct
map_groups
*
self
,
struct
map
*
map
)
{
maps__insert
(
&
self
->
maps
[
map
->
type
],
map
);
...
...
@@ -178,10 +181,20 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
symbol_filter_t
filter
);
static
inline
struct
symbol
*
map_groups__find_function
(
struct
map_groups
*
self
,
u64
addr
,
struct
map
**
mapp
,
symbol_filter_t
filter
)
struct
symbol
*
machine__find_kernel_symbol
(
struct
machine
*
self
,
enum
map_type
type
,
u64
addr
,
struct
map
**
mapp
,
symbol_filter_t
filter
)
{
return
map_groups__find_symbol
(
&
self
->
kmaps
,
type
,
addr
,
mapp
,
filter
);
}
static
inline
struct
symbol
*
machine__find_kernel_function
(
struct
machine
*
self
,
u64
addr
,
struct
map
**
mapp
,
symbol_filter_t
filter
)
{
return
ma
p_groups__find
_symbol
(
self
,
MAP__FUNCTION
,
addr
,
mapp
,
filter
);
return
ma
chine__find_kernel
_symbol
(
self
,
MAP__FUNCTION
,
addr
,
mapp
,
filter
);
}
static
inline
...
...
@@ -197,10 +210,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
struct
map
*
map_groups__find_by_name
(
struct
map_groups
*
self
,
enum
map_type
type
,
const
char
*
name
);
struct
map
*
map_groups__new_module
(
struct
map_groups
*
self
,
u64
start
,
const
char
*
filename
,
struct
kernel_info
*
kerninfo
);
struct
map
*
machine__new_module
(
struct
machine
*
self
,
u64
start
,
const
char
*
filename
);
void
map_groups__flush
(
struct
map_groups
*
self
);
...
...
tools/perf/util/probe-event.c
浏览文件 @
bc4b473f
...
...
@@ -72,8 +72,7 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
}
static
char
*
synthesize_perf_probe_point
(
struct
perf_probe_point
*
pp
);
static
struct
map_groups
kmap_groups
;
static
struct
map
*
kmaps
[
MAP__NR_TYPES
];
static
struct
machine
machine
;
/* Initialize symbol maps and path of vmlinux */
static
int
init_vmlinux
(
void
)
...
...
@@ -92,12 +91,15 @@ static int init_vmlinux(void)
goto
out
;
}
ret
=
machine__init
(
&
machine
,
"/"
,
0
);
if
(
ret
<
0
)
goto
out
;
kernel
=
dso__new_kernel
(
symbol_conf
.
vmlinux_name
);
if
(
kernel
==
NULL
)
die
(
"Failed to create kernel dso."
);
map_groups__init
(
&
kmap_groups
);
ret
=
__map_groups__create_kernel_maps
(
&
kmap_groups
,
kmaps
,
kernel
);
ret
=
__machine__create_kernel_maps
(
&
machine
,
kernel
);
if
(
ret
<
0
)
pr_debug
(
"Failed to create kernel maps.
\n
"
);
...
...
@@ -110,12 +112,12 @@ static int init_vmlinux(void)
#ifdef DWARF_SUPPORT
static
int
open_vmlinux
(
void
)
{
if
(
map__load
(
k
maps
[
MAP__FUNCTION
],
NULL
)
<
0
)
{
if
(
map__load
(
machine
.
vmlinux_
maps
[
MAP__FUNCTION
],
NULL
)
<
0
)
{
pr_debug
(
"Failed to load kernel map.
\n
"
);
return
-
EINVAL
;
}
pr_debug
(
"Try to open %s
\n
"
,
k
maps
[
MAP__FUNCTION
]
->
dso
->
long_name
);
return
open
(
k
maps
[
MAP__FUNCTION
]
->
dso
->
long_name
,
O_RDONLY
);
pr_debug
(
"Try to open %s
\n
"
,
machine
.
vmlinux_
maps
[
MAP__FUNCTION
]
->
dso
->
long_name
);
return
open
(
machine
.
vmlinux_
maps
[
MAP__FUNCTION
]
->
dso
->
long_name
,
O_RDONLY
);
}
/* Convert trace point to probe point with debuginfo */
...
...
@@ -125,7 +127,7 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
struct
symbol
*
sym
;
int
fd
,
ret
=
-
ENOENT
;
sym
=
map__find_symbol_by_name
(
k
maps
[
MAP__FUNCTION
],
sym
=
map__find_symbol_by_name
(
machine
.
vmlinux_
maps
[
MAP__FUNCTION
],
tp
->
symbol
,
NULL
);
if
(
sym
)
{
fd
=
open_vmlinux
();
...
...
@@ -1466,7 +1468,7 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
}
/* Currently just checking function name from symbol map */
sym
=
map__find_symbol_by_name
(
k
maps
[
MAP__FUNCTION
],
sym
=
map__find_symbol_by_name
(
machine
.
vmlinux_
maps
[
MAP__FUNCTION
],
tev
->
point
.
symbol
,
NULL
);
if
(
!
sym
)
{
pr_warning
(
"Kernel symbol
\'
%s
\'
not found.
\n
"
,
...
...
tools/perf/util/session.c
浏览文件 @
bc4b473f
...
...
@@ -69,12 +69,11 @@ void perf_session__update_sample_type(struct perf_session *self)
int
perf_session__create_kernel_maps
(
struct
perf_session
*
self
)
{
int
ret
;
struct
rb_root
*
root
=
&
self
->
kerninfo_root
;
struct
rb_root
*
machines
=
&
self
->
machines
;
int
ret
=
machines__create_kernel_maps
(
machines
,
HOST_KERNEL_ID
)
;
ret
=
map_groups__create_kernel_maps
(
root
,
HOST_KERNEL_ID
);
if
(
ret
>=
0
)
ret
=
ma
p_groups__create_guest_kernel_maps
(
root
);
ret
=
ma
chines__create_guest_kernel_maps
(
machines
);
return
ret
;
}
...
...
@@ -97,7 +96,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
self
->
cwd
=
NULL
;
self
->
cwdlen
=
0
;
self
->
unknown_events
=
0
;
self
->
kerninfo_root
=
RB_ROOT
;
self
->
machines
=
RB_ROOT
;
self
->
ordered_samples
.
flush_limit
=
ULLONG_MAX
;
INIT_LIST_HEAD
(
&
self
->
ordered_samples
.
samples_head
);
...
...
tools/perf/util/session.h
浏览文件 @
bc4b473f
...
...
@@ -25,7 +25,7 @@ struct perf_session {
unsigned
long
mmap_window
;
struct
rb_root
threads
;
struct
thread
*
last_match
;
struct
rb_root
kerninfo_root
;
struct
rb_root
machines
;
struct
events_stats
events_stats
;
struct
rb_root
stats_by_id
;
unsigned
long
event_total
[
PERF_RECORD_MAX
];
...
...
@@ -102,4 +102,42 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
u64
session_total
,
const
char
*
helpline
,
const
char
*
input_name
);
#endif
static
inline
struct
machine
*
perf_session__find_host_machine
(
struct
perf_session
*
self
)
{
return
machines__find_host
(
&
self
->
machines
);
}
static
inline
struct
machine
*
perf_session__find_machine
(
struct
perf_session
*
self
,
pid_t
pid
)
{
return
machines__find
(
&
self
->
machines
,
pid
);
}
static
inline
struct
machine
*
perf_session__findnew_machine
(
struct
perf_session
*
self
,
pid_t
pid
)
{
return
machines__findnew
(
&
self
->
machines
,
pid
);
}
static
inline
void
perf_session__process_machines
(
struct
perf_session
*
self
,
machine__process_t
process
)
{
return
machines__process
(
&
self
->
machines
,
process
,
self
);
}
static
inline
size_t
perf_session__fprintf_dsos
(
struct
perf_session
*
self
,
FILE
*
fp
)
{
return
machines__fprintf_dsos
(
&
self
->
machines
,
fp
);
}
static
inline
size_t
perf_session__fprintf_dsos_buildid
(
struct
perf_session
*
self
,
FILE
*
fp
,
bool
with_hits
)
{
return
machines__fprintf_dsos_buildid
(
&
self
->
machines
,
fp
,
with_hits
);
}
#endif
/* __PERF_SESSION_H */
tools/perf/util/symbol.c
浏览文件 @
bc4b473f
...
...
@@ -485,7 +485,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
symbol_filter_t
filter
)
{
struct
map_groups
*
kmaps
=
map__kmap
(
map
)
->
kmaps
;
struct
kernel_info
*
kerninfo
=
kmaps
->
this_kerninfo
;
struct
machine
*
machine
=
kmaps
->
machine
;
struct
map
*
curr_map
=
map
;
struct
symbol
*
pos
;
int
count
=
0
;
...
...
@@ -508,8 +508,8 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
if
(
strcmp
(
curr_map
->
dso
->
short_name
,
module
))
{
if
(
curr_map
!=
map
&&
self
->
kernel
==
DSO_TYPE_GUEST_KERNEL
&&
is_default_guest
(
kerninfo
))
{
self
->
kernel
==
DSO_TYPE_GUEST_KERNEL
&&
machine__is_default_guest
(
machine
))
{
/*
* We assume all symbols of a module are
* continuous in * kallsyms, so curr_map
...
...
@@ -527,13 +527,13 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
pr_err
(
"%s/proc/{kallsyms,modules} "
"inconsistency while looking "
"for
\"
%s
\"
module!
\n
"
,
kerninfo
->
root_dir
,
module
);
machine
->
root_dir
,
module
);
curr_map
=
map
;
goto
discard_symbol
;
}
if
(
curr_map
->
dso
->
loaded
&&
!
is_default_guest
(
kmaps
->
this_kerninfo
))
!
machine__is_default_guest
(
machine
))
goto
discard_symbol
;
}
/*
...
...
@@ -586,7 +586,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);
if
(
curr_map
!=
map
&&
self
->
kernel
==
DSO_TYPE_GUEST_KERNEL
&&
is_default_guest
(
kmaps
->
this_kerninfo
))
{
machine__is_default_guest
(
kmaps
->
machine
))
{
dso__set_loaded
(
curr_map
->
dso
,
curr_map
->
type
);
}
...
...
@@ -1291,7 +1291,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
char
build_id_hex
[
BUILD_ID_SIZE
*
2
+
1
];
int
ret
=
-
1
;
int
fd
;
struct
kernel_info
*
kerninfo
;
struct
machine
*
machine
;
const
char
*
root_dir
;
dso__set_loaded
(
self
,
map
->
type
);
...
...
@@ -1301,10 +1301,10 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
else
if
(
self
->
kernel
==
DSO_TYPE_GUEST_KERNEL
)
return
dso__load_guest_kernel_sym
(
self
,
map
,
filter
);
if
(
map
->
groups
&&
map
->
groups
->
this_kerninfo
)
kerninfo
=
map
->
groups
->
this_kerninfo
;
if
(
map
->
groups
&&
map
->
groups
->
machine
)
machine
=
map
->
groups
->
machine
;
else
kerninfo
=
NULL
;
machine
=
NULL
;
name
=
malloc
(
size
);
if
(
!
name
)
...
...
@@ -1359,8 +1359,8 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
snprintf
(
name
,
size
,
"%s"
,
self
->
long_name
);
break
;
case
DSO__ORIG_GUEST_KMODULE
:
if
(
map
->
groups
&&
map
->
groups
->
this_kerninfo
)
root_dir
=
map
->
groups
->
this_kerninfo
->
root_dir
;
if
(
map
->
groups
&&
map
->
groups
->
machine
)
root_dir
=
map
->
groups
->
machine
->
root_dir
;
else
root_dir
=
""
;
snprintf
(
name
,
size
,
"%s%s"
,
root_dir
,
self
->
long_name
);
...
...
@@ -1528,21 +1528,20 @@ static char *get_kernel_version(const char *root_dir)
return
strdup
(
name
);
}
static
int
map_groups__set_modules_path
(
struct
map_groups
*
self
,
const
char
*
root_dir
)
static
int
machine__set_modules_path
(
struct
machine
*
self
)
{
char
*
version
;
char
modules_path
[
PATH_MAX
];
version
=
get_kernel_version
(
root_dir
);
version
=
get_kernel_version
(
self
->
root_dir
);
if
(
!
version
)
return
-
1
;
snprintf
(
modules_path
,
sizeof
(
modules_path
),
"%s/lib/modules/%s/kernel"
,
root_dir
,
version
);
self
->
root_dir
,
version
);
free
(
version
);
return
map_groups__set_modules_path_dir
(
self
,
modules_path
);
return
map_groups__set_modules_path_dir
(
&
self
->
kmaps
,
modules_path
);
}
/*
...
...
@@ -1564,14 +1563,12 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
return
self
;
}
struct
map
*
map_groups__new_module
(
struct
map_groups
*
self
,
u64
start
,
const
char
*
filename
,
struct
kernel_info
*
kerninfo
)
struct
map
*
machine__new_module
(
struct
machine
*
self
,
u64
start
,
const
char
*
filename
)
{
struct
map
*
map
;
struct
dso
*
dso
;
struct
dso
*
dso
=
__dsos__findnew
(
&
self
->
kernel_dsos
,
filename
)
;
dso
=
__dsos__findnew
(
&
kerninfo
->
dsos__kernel
,
filename
);
if
(
dso
==
NULL
)
return
NULL
;
...
...
@@ -1579,28 +1576,27 @@ struct map *map_groups__new_module(struct map_groups *self, u64 start,
if
(
map
==
NULL
)
return
NULL
;
if
(
is_host_kernel
(
kerninfo
))
if
(
machine__is_host
(
self
))
dso
->
origin
=
DSO__ORIG_KMODULE
;
else
dso
->
origin
=
DSO__ORIG_GUEST_KMODULE
;
map_groups__insert
(
self
,
map
);
map_groups__insert
(
&
self
->
kmaps
,
map
);
return
map
;
}
static
int
ma
p_groups__create_modules
(
struct
kernel_info
*
kerninfo
)
static
int
ma
chine__create_modules
(
struct
machine
*
self
)
{
char
*
line
=
NULL
;
size_t
n
;
FILE
*
file
;
struct
map
*
map
;
const
char
*
root_dir
;
const
char
*
modules
;
char
path
[
PATH_MAX
];
if
(
is_default_guest
(
kerninfo
))
if
(
machine__is_default_guest
(
self
))
modules
=
symbol_conf
.
default_guest_modules
;
else
{
sprintf
(
path
,
"%s/proc/modules"
,
kerninfo
->
root_dir
);
sprintf
(
path
,
"%s/proc/modules"
,
self
->
root_dir
);
modules
=
path
;
}
...
...
@@ -1608,8 +1604,6 @@ static int map_groups__create_modules(struct kernel_info *kerninfo)
if
(
file
==
NULL
)
return
-
1
;
root_dir
=
kerninfo
->
root_dir
;
while
(
!
feof
(
file
))
{
char
name
[
PATH_MAX
];
u64
start
;
...
...
@@ -1638,17 +1632,16 @@ static int map_groups__create_modules(struct kernel_info *kerninfo)
*
sep
=
'\0'
;
snprintf
(
name
,
sizeof
(
name
),
"[%s]"
,
line
);
map
=
map_groups__new_module
(
&
kerninfo
->
kmaps
,
start
,
name
,
kerninfo
);
map
=
machine__new_module
(
self
,
start
,
name
);
if
(
map
==
NULL
)
goto
out_delete_line
;
dso__kernel_module_get_build_id
(
map
->
dso
,
root_dir
);
dso__kernel_module_get_build_id
(
map
->
dso
,
self
->
root_dir
);
}
free
(
line
);
fclose
(
file
);
return
ma
p_groups__set_modules_path
(
&
kerninfo
->
kmaps
,
root_dir
);
return
ma
chine__set_modules_path
(
self
);
out_delete_line:
free
(
line
);
...
...
@@ -1820,16 +1813,16 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
{
int
err
;
const
char
*
kallsyms_filename
=
NULL
;
struct
kernel_info
*
kerninfo
;
struct
machine
*
machine
;
char
path
[
PATH_MAX
];
if
(
!
map
->
groups
)
{
pr_debug
(
"Guest kernel map hasn't the point to groups
\n
"
);
return
-
1
;
}
kerninfo
=
map
->
groups
->
this_kerninfo
;
machine
=
map
->
groups
->
machine
;
if
(
is_default_guest
(
kerninfo
))
{
if
(
machine__is_default_guest
(
machine
))
{
/*
* if the user specified a vmlinux filename, use it and only
* it, reporting errors to the user if it cannot be used.
...
...
@@ -1845,7 +1838,7 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
if
(
!
kallsyms_filename
)
return
-
1
;
}
else
{
sprintf
(
path
,
"%s/proc/kallsyms"
,
kerninfo
->
root_dir
);
sprintf
(
path
,
"%s/proc/kallsyms"
,
machine
->
root_dir
);
kallsyms_filename
=
path
;
}
...
...
@@ -1856,9 +1849,8 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
out_try_fixup:
if
(
err
>
0
)
{
if
(
kallsyms_filename
!=
NULL
)
{
kern_mmap_name
(
kerninfo
,
path
);
dso__set_long_name
(
self
,
strdup
(
path
));
machine__mmap_name
(
machine
,
path
,
sizeof
(
path
));
dso__set_long_name
(
self
,
strdup
(
path
));
}
map__fixup_start
(
map
);
map__fixup_end
(
map
);
...
...
@@ -1897,27 +1889,32 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name)
return
dso
;
}
static
void
__dsos__fprintf
(
struct
list_head
*
head
,
FILE
*
fp
)
static
size_t
__dsos__fprintf
(
struct
list_head
*
head
,
FILE
*
fp
)
{
struct
dso
*
pos
;
size_t
ret
=
0
;
list_for_each_entry
(
pos
,
head
,
node
)
{
int
i
;
for
(
i
=
0
;
i
<
MAP__NR_TYPES
;
++
i
)
dso__fprintf
(
pos
,
i
,
fp
);
ret
+=
dso__fprintf
(
pos
,
i
,
fp
);
}
return
ret
;
}
void
dsos__fprintf
(
struct
rb_root
*
kerninfo_root
,
FILE
*
fp
)
size_t
machines__fprintf_dsos
(
struct
rb_root
*
self
,
FILE
*
fp
)
{
struct
rb_node
*
nd
;
size_t
ret
=
0
;
for
(
nd
=
rb_first
(
kerninfo_root
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
kernel_info
*
pos
=
rb_entry
(
nd
,
struct
kernel_info
,
rb_node
);
__dsos__fprintf
(
&
pos
->
dsos__kernel
,
fp
);
__dsos__fprintf
(
&
pos
->
dsos__user
,
fp
);
for
(
nd
=
rb_first
(
self
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
machine
*
pos
=
rb_entry
(
nd
,
struct
machine
,
rb_node
);
ret
+=
__dsos__fprintf
(
&
pos
->
kernel_dsos
,
fp
);
ret
+=
__dsos__fprintf
(
&
pos
->
user_dsos
,
fp
);
}
return
ret
;
}
static
size_t
__dsos__fprintf_buildid
(
struct
list_head
*
head
,
FILE
*
fp
,
...
...
@@ -1935,19 +1932,15 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
return
ret
;
}
size_t
dsos__fprintf_buildid
(
struct
rb_root
*
kerninfo_root
,
FILE
*
fp
,
bool
with_hits
)
size_t
machines__fprintf_dsos_buildid
(
struct
rb_root
*
self
,
FILE
*
fp
,
bool
with_hits
)
{
struct
rb_node
*
nd
;
size_t
ret
=
0
;
for
(
nd
=
rb_first
(
kerninfo_root
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
kernel_info
*
pos
=
rb_entry
(
nd
,
struct
kernel_info
,
rb_node
);
ret
+=
__dsos__fprintf_buildid
(
&
pos
->
dsos__kernel
,
fp
,
with_hits
);
ret
+=
__dsos__fprintf_buildid
(
&
pos
->
dsos__user
,
fp
,
with_hits
);
for
(
nd
=
rb_first
(
self
);
nd
;
nd
=
rb_next
(
nd
))
{
struct
machine
*
pos
=
rb_entry
(
nd
,
struct
machine
,
rb_node
);
ret
+=
__dsos__fprintf_buildid
(
&
pos
->
kernel_dsos
,
fp
,
with_hits
);
ret
+=
__dsos__fprintf_buildid
(
&
pos
->
user_dsos
,
fp
,
with_hits
);
}
return
ret
;
}
...
...
@@ -1964,14 +1957,12 @@ struct dso *dso__new_kernel(const char *name)
return
self
;
}
static
struct
dso
*
dso__new_guest_kernel
(
struct
kernel_info
*
kerninfo
,
static
struct
dso
*
dso__new_guest_kernel
(
struct
machine
*
machine
,
const
char
*
name
)
{
char
b
uf
f
[
PATH_MAX
];
struct
dso
*
self
;
char
bf
[
PATH_MAX
];
struct
dso
*
self
=
dso__new
(
name
?:
machine__mmap_name
(
machine
,
bf
,
sizeof
(
bf
)))
;
kern_mmap_name
(
kerninfo
,
buff
);
self
=
dso__new
(
name
?:
buff
);
if
(
self
!=
NULL
)
{
dso__set_short_name
(
self
,
"[guest.kernel]"
);
self
->
kernel
=
DSO_TYPE_GUEST_KERNEL
;
...
...
@@ -1980,64 +1971,78 @@ static struct dso *dso__new_guest_kernel(struct kernel_info *kerninfo,
return
self
;
}
void
dso__read_running_kernel_build_id
(
struct
dso
*
self
,
struct
kernel_info
*
kerninfo
)
void
dso__read_running_kernel_build_id
(
struct
dso
*
self
,
struct
machine
*
machine
)
{
char
path
[
PATH_MAX
];
if
(
is_default_guest
(
kerninfo
))
if
(
machine__is_default_guest
(
machine
))
return
;
sprintf
(
path
,
"%s/sys/kernel/notes"
,
kerninfo
->
root_dir
);
sprintf
(
path
,
"%s/sys/kernel/notes"
,
machine
->
root_dir
);
if
(
sysfs__read_build_id
(
path
,
self
->
build_id
,
sizeof
(
self
->
build_id
))
==
0
)
self
->
has_build_id
=
true
;
}
static
struct
dso
*
dsos__create_kernel
(
struct
kernel_info
*
kerninfo
)
static
struct
dso
*
machine__create_kernel
(
struct
machine
*
self
)
{
const
char
*
vmlinux_name
=
NULL
;
struct
dso
*
kernel
;
if
(
is_host_kernel
(
kerninfo
))
{
if
(
machine__is_host
(
self
))
{
vmlinux_name
=
symbol_conf
.
vmlinux_name
;
kernel
=
dso__new_kernel
(
vmlinux_name
);
}
else
{
if
(
is_default_guest
(
kerninfo
))
if
(
machine__is_default_guest
(
self
))
vmlinux_name
=
symbol_conf
.
default_guest_vmlinux_name
;
kernel
=
dso__new_guest_kernel
(
kerninfo
,
vmlinux_name
);
kernel
=
dso__new_guest_kernel
(
self
,
vmlinux_name
);
}
if
(
kernel
!=
NULL
)
{
dso__read_running_kernel_build_id
(
kernel
,
kerninfo
);
dsos__add
(
&
kerninfo
->
dsos__kernel
,
kernel
);
dso__read_running_kernel_build_id
(
kernel
,
self
);
dsos__add
(
&
self
->
kernel_dsos
,
kernel
);
}
return
kernel
;
}
int
__map_groups__create_kernel_maps
(
struct
map_groups
*
self
,
struct
map
*
vmlinux_maps
[
MAP__NR_TYPES
],
struct
dso
*
kernel
)
int
__machine__create_kernel_maps
(
struct
machine
*
self
,
struct
dso
*
kernel
)
{
enum
map_type
type
;
for
(
type
=
0
;
type
<
MAP__NR_TYPES
;
++
type
)
{
struct
kmap
*
kmap
;
vmlinux_maps
[
type
]
=
map__new2
(
0
,
kernel
,
type
);
if
(
vmlinux_maps
[
type
]
==
NULL
)
self
->
vmlinux_maps
[
type
]
=
map__new2
(
0
,
kernel
,
type
);
if
(
self
->
vmlinux_maps
[
type
]
==
NULL
)
return
-
1
;
vmlinux_maps
[
type
]
->
map_ip
=
vmlinux_maps
[
type
]
->
unmap_ip
=
identity__map_ip
;
self
->
vmlinux_maps
[
type
]
->
map_ip
=
self
->
vmlinux_maps
[
type
]
->
unmap_ip
=
identity__map_ip
;
kmap
=
map__kmap
(
vmlinux_maps
[
type
]);
kmap
->
kmaps
=
self
;
map_groups__insert
(
self
,
vmlinux_maps
[
type
]);
kmap
=
map__kmap
(
self
->
vmlinux_maps
[
type
]);
kmap
->
kmaps
=
&
self
->
kmaps
;
map_groups__insert
(
&
self
->
kmaps
,
self
->
vmlinux_maps
[
type
]);
}
return
0
;
}
int
machine__create_kernel_maps
(
struct
machine
*
self
)
{
struct
dso
*
kernel
=
machine__create_kernel
(
self
);
if
(
kernel
==
NULL
||
__machine__create_kernel_maps
(
self
,
kernel
)
<
0
)
return
-
1
;
if
(
symbol_conf
.
use_modules
&&
machine__create_modules
(
self
)
<
0
)
pr_debug
(
"Problems creating module maps, continuing anyway...
\n
"
);
/*
* Now that we have all the maps created, just set the ->end of them:
*/
map_groups__fixup_end
(
&
self
->
kmaps
);
return
0
;
}
static
void
vmlinux_path__exit
(
void
)
{
while
(
--
vmlinux_path__nr_entries
>=
0
)
{
...
...
@@ -2154,30 +2159,14 @@ int symbol__init(void)
return
-
1
;
}
int
ma
p_groups__create_kernel_maps
(
struct
rb_root
*
kerninfo_root
,
pid_t
pid
)
int
ma
chines__create_kernel_maps
(
struct
rb_root
*
self
,
pid_t
pid
)
{
struct
kernel_info
*
kerninfo
;
struct
dso
*
kernel
;
kerninfo
=
kerninfo__findnew
(
kerninfo_root
,
pid
);
if
(
kerninfo
==
NULL
)
return
-
1
;
kernel
=
dsos__create_kernel
(
kerninfo
);
if
(
kernel
==
NULL
)
return
-
1
;
struct
machine
*
machine
=
machines__findnew
(
self
,
pid
);
if
(
__map_groups__create_kernel_maps
(
&
kerninfo
->
kmaps
,
kerninfo
->
vmlinux_maps
,
kernel
)
<
0
)
if
(
machine
==
NULL
)
return
-
1
;
if
(
symbol_conf
.
use_modules
&&
map_groups__create_modules
(
kerninfo
)
<
0
)
pr_debug
(
"Problems creating module maps, continuing anyway...
\n
"
);
/*
* Now that we have all the maps created, just set the ->end of them:
*/
map_groups__fixup_end
(
&
kerninfo
->
kmaps
);
return
0
;
return
machine__create_kernel_maps
(
machine
);
}
static
int
hex
(
char
ch
)
...
...
@@ -2223,7 +2212,7 @@ char *strxfrchar(char *s, char from, char to)
return
s
;
}
int
ma
p_groups__create_guest_kernel_maps
(
struct
rb_root
*
kerninfo_root
)
int
ma
chines__create_guest_kernel_maps
(
struct
rb_root
*
self
)
{
int
ret
=
0
;
struct
dirent
**
namelist
=
NULL
;
...
...
@@ -2234,8 +2223,7 @@ int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root)
if
(
symbol_conf
.
default_guest_vmlinux_name
||
symbol_conf
.
default_guest_modules
||
symbol_conf
.
default_guest_kallsyms
)
{
map_groups__create_kernel_maps
(
kerninfo_root
,
DEFAULT_GUEST_KERNEL_ID
);
machines__create_kernel_maps
(
self
,
DEFAULT_GUEST_KERNEL_ID
);
}
if
(
symbol_conf
.
guestmount
)
{
...
...
@@ -2256,8 +2244,7 @@ int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root)
pr_debug
(
"Can't access file %s
\n
"
,
path
);
goto
failure
;
}
map_groups__create_kernel_maps
(
kerninfo_root
,
pid
);
machines__create_kernel_maps
(
self
,
pid
);
}
failure:
free
(
namelist
);
...
...
@@ -2265,3 +2252,36 @@ int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root)
return
ret
;
}
int
machine__load_kallsyms
(
struct
machine
*
self
,
const
char
*
filename
,
enum
map_type
type
,
symbol_filter_t
filter
)
{
struct
map
*
map
=
self
->
vmlinux_maps
[
type
];
int
ret
=
dso__load_kallsyms
(
map
->
dso
,
filename
,
map
,
filter
);
if
(
ret
>
0
)
{
dso__set_loaded
(
map
->
dso
,
type
);
/*
* Since /proc/kallsyms will have multiple sessions for the
* kernel, with modules between them, fixup the end of all
* sections.
*/
__map_groups__fixup_end
(
&
self
->
kmaps
,
type
);
}
return
ret
;
}
int
machine__load_vmlinux_path
(
struct
machine
*
self
,
enum
map_type
type
,
symbol_filter_t
filter
)
{
struct
map
*
map
=
self
->
vmlinux_maps
[
type
];
int
ret
=
dso__load_vmlinux_path
(
map
->
dso
,
map
,
filter
);
if
(
ret
>
0
)
{
dso__set_loaded
(
map
->
dso
,
type
);
map__reloc_vmlinux
(
map
);
}
return
ret
;
}
tools/perf/util/symbol.h
浏览文件 @
bc4b473f
...
...
@@ -162,9 +162,13 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map,
symbol_filter_t
filter
);
int
dso__load_kallsyms
(
struct
dso
*
self
,
const
char
*
filename
,
struct
map
*
map
,
symbol_filter_t
filter
);
void
dsos__fprintf
(
struct
rb_root
*
kerninfo_root
,
FILE
*
fp
);
size_t
dsos__fprintf_buildid
(
struct
rb_root
*
kerninfo_root
,
FILE
*
fp
,
bool
with_hits
);
int
machine__load_kallsyms
(
struct
machine
*
self
,
const
char
*
filename
,
enum
map_type
type
,
symbol_filter_t
filter
);
int
machine__load_vmlinux_path
(
struct
machine
*
self
,
enum
map_type
type
,
symbol_filter_t
filter
);
size_t
machines__fprintf_dsos
(
struct
rb_root
*
self
,
FILE
*
fp
);
size_t
machines__fprintf_dsos_buildid
(
struct
rb_root
*
self
,
FILE
*
fp
,
bool
with_hits
);
size_t
dso__fprintf_buildid
(
struct
dso
*
self
,
FILE
*
fp
);
size_t
dso__fprintf
(
struct
dso
*
self
,
enum
map_type
type
,
FILE
*
fp
);
...
...
@@ -186,8 +190,7 @@ enum dso_origin {
char
dso__symtab_origin
(
const
struct
dso
*
self
);
void
dso__set_long_name
(
struct
dso
*
self
,
char
*
name
);
void
dso__set_build_id
(
struct
dso
*
self
,
void
*
build_id
);
void
dso__read_running_kernel_build_id
(
struct
dso
*
self
,
struct
kernel_info
*
kerninfo
);
void
dso__read_running_kernel_build_id
(
struct
dso
*
self
,
struct
machine
*
machine
);
struct
symbol
*
dso__find_symbol
(
struct
dso
*
self
,
enum
map_type
type
,
u64
addr
);
struct
symbol
*
dso__find_symbol_by_name
(
struct
dso
*
self
,
enum
map_type
type
,
const
char
*
name
);
...
...
@@ -200,11 +203,11 @@ int kallsyms__parse(const char *filename, void *arg,
int
(
*
process_symbol
)(
void
*
arg
,
const
char
*
name
,
char
type
,
u64
start
));
int
__ma
p_groups__create_kernel_maps
(
struct
map_groups
*
self
,
struct
map
*
vmlinux_maps
[
MAP__NR_TYPES
],
struct
dso
*
kernel
);
int
ma
p_groups__create_kernel_maps
(
struct
rb_root
*
kerninfo_root
,
pid_t
pid
);
int
ma
p_groups__create_guest_kernel_maps
(
struct
rb_root
*
kerninfo_root
);
int
__ma
chine__create_kernel_maps
(
struct
machine
*
self
,
struct
dso
*
kernel
);
int
machine__create_kernel_maps
(
struct
machine
*
self
);
int
ma
chines__create_kernel_maps
(
struct
rb_root
*
self
,
pid_t
pid
);
int
ma
chines__create_guest_kernel_maps
(
struct
rb_root
*
self
);
int
symbol__init
(
void
);
bool
symbol_type__is_a
(
char
symbol_type
,
enum
map_type
map_type
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录