Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
98580960
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
98580960
编写于
11月 16, 2008
作者:
I
Ingo Molnar
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'tracing/ftrace' into tracing/function-return-tracer
上级
c91add5f
1c80025a
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
284 addition
and
164 deletion
+284
-164
arch/x86/include/asm/ftrace.h
arch/x86/include/asm/ftrace.h
+8
-0
arch/x86/kernel/ftrace.c
arch/x86/kernel/ftrace.c
+26
-3
include/linux/ftrace.h
include/linux/ftrace.h
+41
-12
kernel/module.c
kernel/module.c
+1
-1
kernel/trace/ftrace.c
kernel/trace/ftrace.c
+109
-115
kernel/trace/trace.c
kernel/trace/trace.c
+14
-9
kernel/trace/trace.h
kernel/trace/trace.h
+2
-1
kernel/trace/trace_boot.c
kernel/trace/trace_boot.c
+2
-1
kernel/trace/trace_branch.c
kernel/trace/trace_branch.c
+2
-1
kernel/trace/trace_functions.c
kernel/trace/trace_functions.c
+2
-1
kernel/trace/trace_functions_return.c
kernel/trace/trace_functions_return.c
+2
-1
kernel/trace/trace_irqsoff.c
kernel/trace/trace_irqsoff.c
+6
-3
kernel/trace/trace_mmiotrace.c
kernel/trace/trace_mmiotrace.c
+2
-1
kernel/trace/trace_nop.c
kernel/trace/trace_nop.c
+2
-1
kernel/trace/trace_sched_switch.c
kernel/trace/trace_sched_switch.c
+2
-1
kernel/trace/trace_sched_wakeup.c
kernel/trace/trace_sched_wakeup.c
+2
-1
kernel/trace/trace_selftest.c
kernel/trace/trace_selftest.c
+59
-11
kernel/trace/trace_sysprof.c
kernel/trace/trace_sysprof.c
+2
-1
未找到文件。
arch/x86/include/asm/ftrace.h
浏览文件 @
98580960
...
...
@@ -17,6 +17,14 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
*/
return
addr
-
1
;
}
#ifdef CONFIG_DYNAMIC_FTRACE
struct
dyn_arch_ftrace
{
/* No extra data needed for x86 */
};
#endif
/* CONFIG_DYNAMIC_FTRACE */
#endif
/* __ASSEMBLY__ */
#endif
/* CONFIG_FUNCTION_TRACER */
...
...
arch/x86/kernel/ftrace.c
浏览文件 @
98580960
...
...
@@ -166,7 +166,7 @@ static int ftrace_calc_offset(long ip, long addr)
return
(
int
)(
addr
-
ip
);
}
unsigned
char
*
ftrace_call_replace
(
unsigned
long
ip
,
unsigned
long
addr
)
static
unsigned
char
*
ftrace_call_replace
(
unsigned
long
ip
,
unsigned
long
addr
)
{
static
union
ftrace_code_union
calc
;
...
...
@@ -311,12 +311,12 @@ do_ftrace_mod_code(unsigned long ip, void *new_code)
static
unsigned
char
ftrace_nop
[
MCOUNT_INSN_SIZE
];
unsigned
char
*
ftrace_nop_replace
(
void
)
static
unsigned
char
*
ftrace_nop_replace
(
void
)
{
return
ftrace_nop
;
}
int
static
int
ftrace_modify_code
(
unsigned
long
ip
,
unsigned
char
*
old_code
,
unsigned
char
*
new_code
)
{
...
...
@@ -349,6 +349,29 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
return
0
;
}
int
ftrace_make_nop
(
struct
module
*
mod
,
struct
dyn_ftrace
*
rec
,
unsigned
long
addr
)
{
unsigned
char
*
new
,
*
old
;
unsigned
long
ip
=
rec
->
ip
;
old
=
ftrace_call_replace
(
ip
,
addr
);
new
=
ftrace_nop_replace
();
return
ftrace_modify_code
(
rec
->
ip
,
old
,
new
);
}
int
ftrace_make_call
(
struct
dyn_ftrace
*
rec
,
unsigned
long
addr
)
{
unsigned
char
*
new
,
*
old
;
unsigned
long
ip
=
rec
->
ip
;
old
=
ftrace_nop_replace
();
new
=
ftrace_call_replace
(
ip
,
addr
);
return
ftrace_modify_code
(
rec
->
ip
,
old
,
new
);
}
int
ftrace_update_ftrace_func
(
ftrace_func_t
func
)
{
unsigned
long
ip
=
(
unsigned
long
)(
&
ftrace_call
);
...
...
include/linux/ftrace.h
浏览文件 @
98580960
...
...
@@ -74,6 +74,9 @@ static inline void ftrace_start(void) { }
#endif
/* CONFIG_FUNCTION_TRACER */
#ifdef CONFIG_DYNAMIC_FTRACE
/* asm/ftrace.h must be defined for archs supporting dynamic ftrace */
#include <asm/ftrace.h>
enum
{
FTRACE_FL_FREE
=
(
1
<<
0
),
FTRACE_FL_FAILED
=
(
1
<<
1
),
...
...
@@ -88,6 +91,7 @@ struct dyn_ftrace {
struct
list_head
list
;
unsigned
long
ip
;
/* address of mcount call-site */
unsigned
long
flags
;
struct
dyn_arch_ftrace
arch
;
};
int
ftrace_force_update
(
void
);
...
...
@@ -95,22 +99,40 @@ void ftrace_set_filter(unsigned char *buf, int len, int reset);
/* defined in arch */
extern
int
ftrace_ip_converted
(
unsigned
long
ip
);
extern
unsigned
char
*
ftrace_nop_replace
(
void
);
extern
unsigned
char
*
ftrace_call_replace
(
unsigned
long
ip
,
unsigned
long
addr
);
extern
int
ftrace_dyn_arch_init
(
void
*
data
);
extern
int
ftrace_update_ftrace_func
(
ftrace_func_t
func
);
extern
void
ftrace_caller
(
void
);
extern
void
ftrace_call
(
void
);
extern
void
mcount_call
(
void
);
/* May be defined in arch */
extern
int
ftrace_arch_read_dyn_info
(
char
*
buf
,
int
size
);
/**
* ftrace_make_nop - convert code into top
* @mod: module structure if called by module load initialization
* @rec: the mcount call site record
* @addr: the address that the call site should be calling
*
* This is a very sensitive operation and great care needs
* to be taken by the arch. The operation should carefully
* read the location, check to see if what is read is indeed
* what we expect it to be, and then on success of the compare,
* it should write to the location.
*
* The code segment at @rec->ip should be a caller to @addr
*
* Return must be:
* 0 on success
* -EFAULT on error reading the location
* -EINVAL on a failed compare of the contents
* -EPERM on error writing to the location
* Any other value will be considered a failure.
*/
extern
int
ftrace_make_nop
(
struct
module
*
mod
,
struct
dyn_ftrace
*
rec
,
unsigned
long
addr
);
/**
* ftrace_modify_code - modify code segment
* @ip: the address of the code segment
* @old_code: the contents of what is expected to be there
* @new_code: the code to patch in
* ftrace_make_call - convert a nop call site into a call to addr
* @rec: the mcount call site record
* @addr: the address that the call site should call
*
* This is a very sensitive operation and great care needs
* to be taken by the arch. The operation should carefully
...
...
@@ -118,6 +140,8 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
* what we expect it to be, and then on success of the compare,
* it should write to the location.
*
* The code segment at @rec->ip should be a nop
*
* Return must be:
* 0 on success
* -EFAULT on error reading the location
...
...
@@ -125,8 +149,11 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
* -EPERM on error writing to the location
* Any other value will be considered a failure.
*/
extern
int
ftrace_modify_code
(
unsigned
long
ip
,
unsigned
char
*
old_code
,
unsigned
char
*
new_code
);
extern
int
ftrace_make_call
(
struct
dyn_ftrace
*
rec
,
unsigned
long
addr
);
/* May be defined in arch */
extern
int
ftrace_arch_read_dyn_info
(
char
*
buf
,
int
size
);
extern
int
skip_trace
(
unsigned
long
ip
);
...
...
@@ -259,11 +286,13 @@ static inline void ftrace_dump(void) { }
#ifdef CONFIG_FTRACE_MCOUNT_RECORD
extern
void
ftrace_init
(
void
);
extern
void
ftrace_init_module
(
unsigned
long
*
start
,
unsigned
long
*
end
);
extern
void
ftrace_init_module
(
struct
module
*
mod
,
unsigned
long
*
start
,
unsigned
long
*
end
);
#else
static
inline
void
ftrace_init
(
void
)
{
}
static
inline
void
ftrace_init_module
(
unsigned
long
*
start
,
unsigned
long
*
end
)
{
}
ftrace_init_module
(
struct
module
*
mod
,
unsigned
long
*
start
,
unsigned
long
*
end
)
{
}
#endif
...
...
kernel/module.c
浏览文件 @
98580960
...
...
@@ -2201,7 +2201,7 @@ static noinline struct module *load_module(void __user *umod,
/* sechdrs[0].sh_size is always zero */
mseg
=
section_objs
(
hdr
,
sechdrs
,
secstrings
,
"__mcount_loc"
,
sizeof
(
*
mseg
),
&
num_mcount
);
ftrace_init_module
(
mseg
,
mseg
+
num_mcount
);
ftrace_init_module
(
m
od
,
m
seg
,
mseg
+
num_mcount
);
err
=
module_finalize
(
hdr
,
sechdrs
,
mod
);
if
(
err
<
0
)
...
...
kernel/trace/ftrace.c
浏览文件 @
98580960
...
...
@@ -334,7 +334,7 @@ ftrace_record_ip(unsigned long ip)
{
struct
dyn_ftrace
*
rec
;
if
(
!
ftrace_enabled
||
ftrace_disabled
)
if
(
ftrace_disabled
)
return
NULL
;
rec
=
ftrace_alloc_dyn_node
(
ip
);
...
...
@@ -348,107 +348,129 @@ ftrace_record_ip(unsigned long ip)
return
rec
;
}
static
void
print_ip_ins
(
const
char
*
fmt
,
unsigned
char
*
p
)
{
int
i
;
printk
(
KERN_CONT
"%s"
,
fmt
);
for
(
i
=
0
;
i
<
MCOUNT_INSN_SIZE
;
i
++
)
printk
(
KERN_CONT
"%s%02x"
,
i
?
":"
:
""
,
p
[
i
]);
}
static
void
ftrace_bug
(
int
failed
,
unsigned
long
ip
)
{
switch
(
failed
)
{
case
-
EFAULT
:
FTRACE_WARN_ON_ONCE
(
1
);
pr_info
(
"ftrace faulted on modifying "
);
print_ip_sym
(
ip
);
break
;
case
-
EINVAL
:
FTRACE_WARN_ON_ONCE
(
1
);
pr_info
(
"ftrace failed to modify "
);
print_ip_sym
(
ip
);
print_ip_ins
(
" actual: "
,
(
unsigned
char
*
)
ip
);
printk
(
KERN_CONT
"
\n
"
);
break
;
case
-
EPERM
:
FTRACE_WARN_ON_ONCE
(
1
);
pr_info
(
"ftrace faulted on writing "
);
print_ip_sym
(
ip
);
break
;
default:
FTRACE_WARN_ON_ONCE
(
1
);
pr_info
(
"ftrace faulted on unknown error "
);
print_ip_sym
(
ip
);
}
}
#define FTRACE_ADDR ((long)(ftrace_caller))
static
int
__ftrace_replace_code
(
struct
dyn_ftrace
*
rec
,
unsigned
char
*
old
,
unsigned
char
*
new
,
int
enable
)
__ftrace_replace_code
(
struct
dyn_ftrace
*
rec
,
int
enable
)
{
unsigned
long
ip
,
fl
;
ip
=
rec
->
ip
;
if
(
ftrace_filtered
&&
enable
)
{
/*
* If this record is not to be traced and
* it is not enabled then do nothing.
*
* If this record is not to be traced and
* it is enabled then disabled it.
*
*/
if
(
rec
->
flags
&
FTRACE_FL_NOTRACE
)
{
if
(
rec
->
flags
&
FTRACE_FL_ENABLED
)
rec
->
flags
&=
~
FTRACE_FL_ENABLED
;
else
return
0
;
}
else
if
(
ftrace_filtered
&&
enable
)
{
/*
* If filtering is on:
*
* If this record is set to be filtered and
* is enabled then do nothing.
*
* If this record is set to be filtered and
* it is not enabled, enable it.
*
* If this record is not set to be filtered
* and it is not enabled do nothing.
*
* If this record is set not to trace then
* do nothing.
*
* If this record is set not to trace and
* it is enabled then disable it.
*
* If this record is not set to be filtered and
* it is enabled, disable it.
* Filtering is on:
*/
fl
=
rec
->
flags
&
(
FTRACE_FL_FILTER
|
FTRACE_FL_NOTRACE
|
FTRACE_FL_ENABLED
);
fl
=
rec
->
flags
&
(
FTRACE_FL_FILTER
|
FTRACE_FL_ENABLED
);
if
((
fl
==
(
FTRACE_FL_FILTER
|
FTRACE_FL_ENABLED
))
||
(
fl
==
(
FTRACE_FL_FILTER
|
FTRACE_FL_NOTRACE
))
||
!
fl
||
(
fl
==
FTRACE_FL_NOTRACE
))
/* Record is filtered and enabled, do nothing */
if
(
fl
==
(
FTRACE_FL_FILTER
|
FTRACE_FL_ENABLED
))
return
0
;
/*
* If it is enabled disable it,
* otherwise enable it!
*/
if
(
fl
&
FTRACE_FL_ENABLED
)
{
/* swap new and old */
new
=
old
;
old
=
ftrace_call_replace
(
ip
,
FTRACE_ADDR
);
/* Record is not filtered and is not enabled do nothing */
if
(
!
fl
)
return
0
;
/* Record is not filtered but enabled, disable it */
if
(
fl
==
FTRACE_FL_ENABLED
)
rec
->
flags
&=
~
FTRACE_FL_ENABLED
;
}
else
{
new
=
ftrace_call_replace
(
ip
,
FTRACE_ADDR
);
else
/* Otherwise record is filtered but not enabled, enable it */
rec
->
flags
|=
FTRACE_FL_ENABLED
;
}
}
else
{
/* Disable or not filtered */
if
(
enable
)
{
/*
* If this record is set not to trace and is
* not enabled, do nothing.
*/
fl
=
rec
->
flags
&
(
FTRACE_FL_NOTRACE
|
FTRACE_FL_ENABLED
);
if
(
fl
==
FTRACE_FL_NOTRACE
)
return
0
;
new
=
ftrace_call_replace
(
ip
,
FTRACE_ADDR
);
}
else
old
=
ftrace_call_replace
(
ip
,
FTRACE_ADDR
);
if
(
enable
)
{
/* if record is enabled, do nothing */
if
(
rec
->
flags
&
FTRACE_FL_ENABLED
)
return
0
;
rec
->
flags
|=
FTRACE_FL_ENABLED
;
}
else
{
/* if record is not enabled do nothing */
if
(
!
(
rec
->
flags
&
FTRACE_FL_ENABLED
))
return
0
;
rec
->
flags
&=
~
FTRACE_FL_ENABLED
;
}
}
return
ftrace_modify_code
(
ip
,
old
,
new
);
if
(
rec
->
flags
&
FTRACE_FL_ENABLED
)
return
ftrace_make_call
(
rec
,
FTRACE_ADDR
);
else
return
ftrace_make_nop
(
NULL
,
rec
,
FTRACE_ADDR
);
}
static
void
ftrace_replace_code
(
int
enable
)
{
int
i
,
failed
;
unsigned
char
*
new
=
NULL
,
*
old
=
NULL
;
struct
dyn_ftrace
*
rec
;
struct
ftrace_page
*
pg
;
if
(
enable
)
old
=
ftrace_nop_replace
();
else
new
=
ftrace_nop_replace
();
for
(
pg
=
ftrace_pages_start
;
pg
;
pg
=
pg
->
next
)
{
for
(
i
=
0
;
i
<
pg
->
index
;
i
++
)
{
rec
=
&
pg
->
records
[
i
];
/* don't modify code that has already faulted */
if
(
rec
->
flags
&
FTRACE_FL_FAILED
)
/*
* Skip over free records and records that have
* failed.
*/
if
(
rec
->
flags
&
FTRACE_FL_FREE
||
rec
->
flags
&
FTRACE_FL_FAILED
)
continue
;
/* ignore updates to this record's mcount site */
...
...
@@ -459,68 +481,30 @@ static void ftrace_replace_code(int enable)
unfreeze_record
(
rec
);
}
failed
=
__ftrace_replace_code
(
rec
,
old
,
new
,
enable
);
failed
=
__ftrace_replace_code
(
rec
,
enable
);
if
(
failed
&&
(
rec
->
flags
&
FTRACE_FL_CONVERTED
))
{
rec
->
flags
|=
FTRACE_FL_FAILED
;
if
((
system_state
==
SYSTEM_BOOTING
)
||
!
core_kernel_text
(
rec
->
ip
))
{
ftrace_free_rec
(
rec
);
}
}
else
ftrace_bug
(
failed
,
rec
->
ip
);
}
}
}
}
static
void
print_ip_ins
(
const
char
*
fmt
,
unsigned
char
*
p
)
{
int
i
;
printk
(
KERN_CONT
"%s"
,
fmt
);
for
(
i
=
0
;
i
<
MCOUNT_INSN_SIZE
;
i
++
)
printk
(
KERN_CONT
"%s%02x"
,
i
?
":"
:
""
,
p
[
i
]);
}
static
int
ftrace_code_disable
(
struct
dyn_ftrace
*
rec
)
ftrace_code_disable
(
struct
module
*
mod
,
struct
dyn_ftrace
*
rec
)
{
unsigned
long
ip
;
unsigned
char
*
nop
,
*
call
;
int
ret
;
ip
=
rec
->
ip
;
nop
=
ftrace_nop_replace
();
call
=
ftrace_call_replace
(
ip
,
mcount_addr
);
ret
=
ftrace_modify_code
(
ip
,
call
,
nop
);
ret
=
ftrace_make_nop
(
mod
,
rec
,
mcount_addr
);
if
(
ret
)
{
switch
(
ret
)
{
case
-
EFAULT
:
FTRACE_WARN_ON_ONCE
(
1
);
pr_info
(
"ftrace faulted on modifying "
);
print_ip_sym
(
ip
);
break
;
case
-
EINVAL
:
FTRACE_WARN_ON_ONCE
(
1
);
pr_info
(
"ftrace failed to modify "
);
print_ip_sym
(
ip
);
print_ip_ins
(
" expected: "
,
call
);
print_ip_ins
(
" actual: "
,
(
unsigned
char
*
)
ip
);
print_ip_ins
(
" replace: "
,
nop
);
printk
(
KERN_CONT
"
\n
"
);
break
;
case
-
EPERM
:
FTRACE_WARN_ON_ONCE
(
1
);
pr_info
(
"ftrace faulted on writing "
);
print_ip_sym
(
ip
);
break
;
default:
FTRACE_WARN_ON_ONCE
(
1
);
pr_info
(
"ftrace faulted on unknown error "
);
print_ip_sym
(
ip
);
}
ftrace_bug
(
ret
,
ip
);
rec
->
flags
|=
FTRACE_FL_FAILED
;
return
0
;
}
...
...
@@ -560,8 +544,7 @@ static void ftrace_startup(void)
mutex_lock
(
&
ftrace_start_lock
);
ftrace_start_up
++
;
if
(
ftrace_start_up
==
1
)
command
|=
FTRACE_ENABLE_CALLS
;
command
|=
FTRACE_ENABLE_CALLS
;
if
(
saved_ftrace_func
!=
ftrace_trace_function
)
{
saved_ftrace_func
=
ftrace_trace_function
;
...
...
@@ -639,7 +622,7 @@ static cycle_t ftrace_update_time;
static
unsigned
long
ftrace_update_cnt
;
unsigned
long
ftrace_update_tot_cnt
;
static
int
ftrace_update_code
(
voi
d
)
static
int
ftrace_update_code
(
struct
module
*
mo
d
)
{
struct
dyn_ftrace
*
p
,
*
t
;
cycle_t
start
,
stop
;
...
...
@@ -656,7 +639,7 @@ static int ftrace_update_code(void)
list_del_init
(
&
p
->
list
);
/* convert record (i.e, patch mcount-call with NOP) */
if
(
ftrace_code_disable
(
p
))
{
if
(
ftrace_code_disable
(
mod
,
p
))
{
p
->
flags
|=
FTRACE_FL_CONVERTED
;
ftrace_update_cnt
++
;
}
else
...
...
@@ -1211,7 +1194,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
mutex_lock
(
&
ftrace_sysctl_lock
);
mutex_lock
(
&
ftrace_start_lock
);
if
(
iter
->
filtered
&&
ftrace_start_up
&&
ftrace_enabled
)
if
(
ftrace_start_up
&&
ftrace_enabled
)
ftrace_run_update_code
(
FTRACE_ENABLE_CALLS
);
mutex_unlock
(
&
ftrace_start_lock
);
mutex_unlock
(
&
ftrace_sysctl_lock
);
...
...
@@ -1298,7 +1281,8 @@ static __init int ftrace_init_debugfs(void)
fs_initcall
(
ftrace_init_debugfs
);
static
int
ftrace_convert_nops
(
unsigned
long
*
start
,
static
int
ftrace_convert_nops
(
struct
module
*
mod
,
unsigned
long
*
start
,
unsigned
long
*
end
)
{
unsigned
long
*
p
;
...
...
@@ -1309,23 +1293,32 @@ static int ftrace_convert_nops(unsigned long *start,
p
=
start
;
while
(
p
<
end
)
{
addr
=
ftrace_call_adjust
(
*
p
++
);
/*
* Some architecture linkers will pad between
* the different mcount_loc sections of different
* object files to satisfy alignments.
* Skip any NULL pointers.
*/
if
(
!
addr
)
continue
;
ftrace_record_ip
(
addr
);
}
/* disable interrupts to prevent kstop machine */
local_irq_save
(
flags
);
ftrace_update_code
();
ftrace_update_code
(
mod
);
local_irq_restore
(
flags
);
mutex_unlock
(
&
ftrace_start_lock
);
return
0
;
}
void
ftrace_init_module
(
unsigned
long
*
start
,
unsigned
long
*
end
)
void
ftrace_init_module
(
struct
module
*
mod
,
unsigned
long
*
start
,
unsigned
long
*
end
)
{
if
(
ftrace_disabled
||
start
==
end
)
return
;
ftrace_convert_nops
(
start
,
end
);
ftrace_convert_nops
(
mod
,
start
,
end
);
}
extern
unsigned
long
__start_mcount_loc
[];
...
...
@@ -1355,7 +1348,8 @@ void __init ftrace_init(void)
last_ftrace_enabled
=
ftrace_enabled
=
1
;
ret
=
ftrace_convert_nops
(
__start_mcount_loc
,
ret
=
ftrace_convert_nops
(
NULL
,
__start_mcount_loc
,
__stop_mcount_loc
);
return
;
...
...
kernel/trace/trace.c
浏览文件 @
98580960
...
...
@@ -1051,7 +1051,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip)
* Need to use raw, since this must be called before the
* recursive protection is performed.
*/
raw_
local_irq_save
(
flags
);
local_irq_save
(
flags
);
cpu
=
raw_smp_processor_id
();
data
=
tr
->
data
[
cpu
];
disabled
=
atomic_inc_return
(
&
data
->
disabled
);
...
...
@@ -1062,7 +1062,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip)
}
atomic_dec
(
&
data
->
disabled
);
raw_
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
}
#ifdef CONFIG_FUNCTION_RET_TRACER
...
...
@@ -2638,8 +2638,11 @@ static int tracing_set_tracer(char *buf)
current_trace
->
reset
(
tr
);
current_trace
=
t
;
if
(
t
->
init
)
t
->
init
(
tr
);
if
(
t
->
init
)
{
ret
=
t
->
init
(
tr
);
if
(
ret
)
goto
out
;
}
trace_branch_enable
(
tr
);
out:
...
...
@@ -2655,6 +2658,9 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
char
buf
[
max_tracer_type_len
+
1
];
int
i
;
size_t
ret
;
int
err
;
ret
=
cnt
;
if
(
cnt
>
max_tracer_type_len
)
cnt
=
max_tracer_type_len
;
...
...
@@ -2668,12 +2674,11 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
for
(
i
=
cnt
-
1
;
i
>
0
&&
isspace
(
buf
[
i
]);
i
--
)
buf
[
i
]
=
0
;
ret
=
tracing_set_tracer
(
buf
);
if
(
!
ret
)
ret
=
cnt
;
err
=
tracing_set_tracer
(
buf
);
if
(
err
)
ret
urn
err
;
if
(
ret
>
0
)
filp
->
f_pos
+=
ret
;
filp
->
f_pos
+=
ret
;
return
ret
;
}
...
...
kernel/trace/trace.h
浏览文件 @
98580960
...
...
@@ -264,7 +264,8 @@ enum print_line_t {
*/
struct
tracer
{
const
char
*
name
;
void
(
*
init
)(
struct
trace_array
*
tr
);
/* Your tracer should raise a warning if init fails */
int
(
*
init
)(
struct
trace_array
*
tr
);
void
(
*
reset
)(
struct
trace_array
*
tr
);
void
(
*
start
)(
struct
trace_array
*
tr
);
void
(
*
stop
)(
struct
trace_array
*
tr
);
...
...
kernel/trace/trace_boot.c
浏览文件 @
98580960
...
...
@@ -47,7 +47,7 @@ static void reset_boot_trace(struct trace_array *tr)
tracing_reset
(
tr
,
cpu
);
}
static
void
boot_trace_init
(
struct
trace_array
*
tr
)
static
int
boot_trace_init
(
struct
trace_array
*
tr
)
{
int
cpu
;
boot_trace
=
tr
;
...
...
@@ -56,6 +56,7 @@ static void boot_trace_init(struct trace_array *tr)
tracing_reset
(
tr
,
cpu
);
tracing_sched_switch_assign_trace
(
tr
);
return
0
;
}
static
enum
print_line_t
...
...
kernel/trace/trace_branch.c
浏览文件 @
98580960
...
...
@@ -125,7 +125,7 @@ static void stop_branch_trace(struct trace_array *tr)
disable_branch_tracing
();
}
static
void
branch_trace_init
(
struct
trace_array
*
tr
)
static
int
branch_trace_init
(
struct
trace_array
*
tr
)
{
int
cpu
;
...
...
@@ -133,6 +133,7 @@ static void branch_trace_init(struct trace_array *tr)
tracing_reset
(
tr
,
cpu
);
start_branch_trace
(
tr
);
return
0
;
}
static
void
branch_trace_reset
(
struct
trace_array
*
tr
)
...
...
kernel/trace/trace_functions.c
浏览文件 @
98580960
...
...
@@ -42,9 +42,10 @@ static void stop_function_trace(struct trace_array *tr)
tracing_stop_cmdline_record
();
}
static
void
function_trace_init
(
struct
trace_array
*
tr
)
static
int
function_trace_init
(
struct
trace_array
*
tr
)
{
start_function_trace
(
tr
);
return
0
;
}
static
void
function_trace_reset
(
struct
trace_array
*
tr
)
...
...
kernel/trace/trace_functions_return.c
浏览文件 @
98580960
...
...
@@ -24,13 +24,14 @@ static void stop_return_trace(struct trace_array *tr)
unregister_ftrace_return
();
}
static
void
return_trace_init
(
struct
trace_array
*
tr
)
static
int
return_trace_init
(
struct
trace_array
*
tr
)
{
int
cpu
;
for_each_online_cpu
(
cpu
)
tracing_reset
(
tr
,
cpu
);
start_return_trace
(
tr
);
return
0
;
}
static
void
return_trace_reset
(
struct
trace_array
*
tr
)
...
...
kernel/trace/trace_irqsoff.c
浏览文件 @
98580960
...
...
@@ -416,11 +416,12 @@ static void irqsoff_tracer_close(struct trace_iterator *iter)
}
#ifdef CONFIG_IRQSOFF_TRACER
static
void
irqsoff_tracer_init
(
struct
trace_array
*
tr
)
static
int
irqsoff_tracer_init
(
struct
trace_array
*
tr
)
{
trace_type
=
TRACER_IRQS_OFF
;
__irqsoff_tracer_init
(
tr
);
return
0
;
}
static
struct
tracer
irqsoff_tracer
__read_mostly
=
{
...
...
@@ -442,11 +443,12 @@ static struct tracer irqsoff_tracer __read_mostly =
#endif
#ifdef CONFIG_PREEMPT_TRACER
static
void
preemptoff_tracer_init
(
struct
trace_array
*
tr
)
static
int
preemptoff_tracer_init
(
struct
trace_array
*
tr
)
{
trace_type
=
TRACER_PREEMPT_OFF
;
__irqsoff_tracer_init
(
tr
);
return
0
;
}
static
struct
tracer
preemptoff_tracer
__read_mostly
=
...
...
@@ -471,11 +473,12 @@ static struct tracer preemptoff_tracer __read_mostly =
#if defined(CONFIG_IRQSOFF_TRACER) && \
defined(CONFIG_PREEMPT_TRACER)
static
void
preemptirqsoff_tracer_init
(
struct
trace_array
*
tr
)
static
int
preemptirqsoff_tracer_init
(
struct
trace_array
*
tr
)
{
trace_type
=
TRACER_IRQS_OFF
|
TRACER_PREEMPT_OFF
;
__irqsoff_tracer_init
(
tr
);
return
0
;
}
static
struct
tracer
preemptirqsoff_tracer
__read_mostly
=
...
...
kernel/trace/trace_mmiotrace.c
浏览文件 @
98580960
...
...
@@ -30,13 +30,14 @@ static void mmio_reset_data(struct trace_array *tr)
tracing_reset
(
tr
,
cpu
);
}
static
void
mmio_trace_init
(
struct
trace_array
*
tr
)
static
int
mmio_trace_init
(
struct
trace_array
*
tr
)
{
pr_debug
(
"in %s
\n
"
,
__func__
);
mmio_trace_array
=
tr
;
mmio_reset_data
(
tr
);
enable_mmiotrace
();
return
0
;
}
static
void
mmio_trace_reset
(
struct
trace_array
*
tr
)
...
...
kernel/trace/trace_nop.c
浏览文件 @
98580960
...
...
@@ -24,7 +24,7 @@ static void stop_nop_trace(struct trace_array *tr)
/* Nothing to do! */
}
static
void
nop_trace_init
(
struct
trace_array
*
tr
)
static
int
nop_trace_init
(
struct
trace_array
*
tr
)
{
int
cpu
;
ctx_trace
=
tr
;
...
...
@@ -33,6 +33,7 @@ static void nop_trace_init(struct trace_array *tr)
tracing_reset
(
tr
,
cpu
);
start_nop_trace
(
tr
);
return
0
;
}
static
void
nop_trace_reset
(
struct
trace_array
*
tr
)
...
...
kernel/trace/trace_sched_switch.c
浏览文件 @
98580960
...
...
@@ -206,10 +206,11 @@ static void stop_sched_trace(struct trace_array *tr)
tracing_stop_sched_switch_record
();
}
static
void
sched_switch_trace_init
(
struct
trace_array
*
tr
)
static
int
sched_switch_trace_init
(
struct
trace_array
*
tr
)
{
ctx_trace
=
tr
;
start_sched_trace
(
tr
);
return
0
;
}
static
void
sched_switch_trace_reset
(
struct
trace_array
*
tr
)
...
...
kernel/trace/trace_sched_wakeup.c
浏览文件 @
98580960
...
...
@@ -331,10 +331,11 @@ static void stop_wakeup_tracer(struct trace_array *tr)
unregister_trace_sched_wakeup
(
probe_wakeup
);
}
static
void
wakeup_tracer_init
(
struct
trace_array
*
tr
)
static
int
wakeup_tracer_init
(
struct
trace_array
*
tr
)
{
wakeup_trace
=
tr
;
start_wakeup_tracer
(
tr
);
return
0
;
}
static
void
wakeup_tracer_reset
(
struct
trace_array
*
tr
)
...
...
kernel/trace/trace_selftest.c
浏览文件 @
98580960
...
...
@@ -52,7 +52,7 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count)
int
cpu
,
ret
=
0
;
/* Don't allow flipping of max traces now */
raw_
local_irq_save
(
flags
);
local_irq_save
(
flags
);
__raw_spin_lock
(
&
ftrace_max_lock
);
cnt
=
ring_buffer_entries
(
tr
->
buffer
);
...
...
@@ -63,7 +63,7 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count)
break
;
}
__raw_spin_unlock
(
&
ftrace_max_lock
);
raw_
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
if
(
count
)
*
count
=
cnt
;
...
...
@@ -71,6 +71,11 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count)
return
ret
;
}
static
inline
void
warn_failed_init_tracer
(
struct
tracer
*
trace
,
int
init_ret
)
{
printk
(
KERN_WARNING
"Failed to init %s tracer, init returned %d
\n
"
,
trace
->
name
,
init_ret
);
}
#ifdef CONFIG_FUNCTION_TRACER
#ifdef CONFIG_DYNAMIC_FTRACE
...
...
@@ -111,7 +116,11 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
ftrace_set_filter
(
func_name
,
strlen
(
func_name
),
1
);
/* enable tracing */
trace
->
init
(
tr
);
ret
=
trace
->
init
(
tr
);
if
(
ret
)
{
warn_failed_init_tracer
(
trace
,
ret
);
goto
out
;
}
/* Sleep for a 1/10 of a second */
msleep
(
100
);
...
...
@@ -181,7 +190,12 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
ftrace_enabled
=
1
;
tracer_enabled
=
1
;
trace
->
init
(
tr
);
ret
=
trace
->
init
(
tr
);
if
(
ret
)
{
warn_failed_init_tracer
(
trace
,
ret
);
goto
out
;
}
/* Sleep for a 1/10 of a second */
msleep
(
100
);
/* stop the tracing. */
...
...
@@ -223,7 +237,12 @@ trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)
int
ret
;
/* start the tracing */
trace
->
init
(
tr
);
ret
=
trace
->
init
(
tr
);
if
(
ret
)
{
warn_failed_init_tracer
(
trace
,
ret
);
return
ret
;
}
/* reset the max latency */
tracing_max_latency
=
0
;
/* disable interrupts for a bit */
...
...
@@ -272,7 +291,12 @@ trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr)
}
/* start the tracing */
trace
->
init
(
tr
);
ret
=
trace
->
init
(
tr
);
if
(
ret
)
{
warn_failed_init_tracer
(
trace
,
ret
);
return
ret
;
}
/* reset the max latency */
tracing_max_latency
=
0
;
/* disable preemption for a bit */
...
...
@@ -321,7 +345,11 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
}
/* start the tracing */
trace
->
init
(
tr
);
ret
=
trace
->
init
(
tr
);
if
(
ret
)
{
warn_failed_init_tracer
(
trace
,
ret
);
goto
out
;
}
/* reset the max latency */
tracing_max_latency
=
0
;
...
...
@@ -449,7 +477,12 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
wait_for_completion
(
&
isrt
);
/* start the tracing */
trace
->
init
(
tr
);
ret
=
trace
->
init
(
tr
);
if
(
ret
)
{
warn_failed_init_tracer
(
trace
,
ret
);
return
ret
;
}
/* reset the max latency */
tracing_max_latency
=
0
;
...
...
@@ -505,7 +538,12 @@ trace_selftest_startup_sched_switch(struct tracer *trace, struct trace_array *tr
int
ret
;
/* start the tracing */
trace
->
init
(
tr
);
ret
=
trace
->
init
(
tr
);
if
(
ret
)
{
warn_failed_init_tracer
(
trace
,
ret
);
return
ret
;
}
/* Sleep for a 1/10 of a second */
msleep
(
100
);
/* stop the tracing. */
...
...
@@ -532,7 +570,12 @@ trace_selftest_startup_sysprof(struct tracer *trace, struct trace_array *tr)
int
ret
;
/* start the tracing */
trace
->
init
(
tr
);
ret
=
trace
->
init
(
tr
);
if
(
ret
)
{
warn_failed_init_tracer
(
trace
,
ret
);
return
0
;
}
/* Sleep for a 1/10 of a second */
msleep
(
100
);
/* stop the tracing. */
...
...
@@ -554,7 +597,12 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
int
ret
;
/* start the tracing */
trace
->
init
(
tr
);
ret
=
trace
->
init
(
tr
);
if
(
ret
)
{
warn_failed_init_tracer
(
trace
,
ret
);
return
ret
;
}
/* Sleep for a 1/10 of a second */
msleep
(
100
);
/* stop the tracing. */
...
...
kernel/trace/trace_sysprof.c
浏览文件 @
98580960
...
...
@@ -261,11 +261,12 @@ static void stop_stack_trace(struct trace_array *tr)
mutex_unlock
(
&
sample_timer_lock
);
}
static
void
stack_trace_init
(
struct
trace_array
*
tr
)
static
int
stack_trace_init
(
struct
trace_array
*
tr
)
{
sysprof_trace
=
tr
;
start_stack_trace
(
tr
);
return
0
;
}
static
void
stack_trace_reset
(
struct
trace_array
*
tr
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录