diff --git a/articles/20220910-ftrace-impl-4-replace-trace-function.md b/articles/20220910-ftrace-impl-4-replace-trace-function.md
index ae25bd1a4164b6d77804cfebd2e6d8a763d26b56..c028402a3d0b55ede50daac0b3c672f569617e0d 100644
--- a/articles/20220910-ftrace-impl-4-replace-trace-function.md
+++ b/articles/20220910-ftrace-impl-4-replace-trace-function.md
@@ -1,10 +1,10 @@
-> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc3 - [spaces epw]
-> Author: sugarfillet
-> Date: 2022/09/10
-> Revisor: Falcon falcon@tinylab.org
-> Project: [RISC-V Linux 内核剖析](https://gitee.com/tinylab/riscv-linux)
-> Proposal: [RISC-V ftrace 相关技术调研与分析](https://gitee.com/tinylab/riscv-linux/issues/I58N1O)
-> Sponsor: PLCT Lab, ISCAS
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1 - [header]
+> Author: sugarfillet
+> Date: 2022/09/10
+> Revisor: Falcon falcon@tinylab.org
+> Project: [RISC-V Linux 内核剖析](https://gitee.com/tinylab/riscv-linux)
+> Proposal: [RISC-V ftrace 相关技术调研与分析](https://gitee.com/tinylab/riscv-linux/issues/I58N1O)
+> Sponsor: PLCT Lab, ISCAS
# RISC-V Ftrace 实现原理(4)- 替换跟踪函数
@@ -45,7 +45,7 @@ early_trace_init()
global_trace.current_trace = &nop_trace; // 设置默认 tracer 为 nop tracer
ftrace_init_global_array_ops(&global_trace); // 挂接 global_ops
init_function_trace(); // 注册 function tracer
- register_tracer(&function_trace); // 注册 function_trace 到全局 tracer 链表 - trace_type ,如果命令行指定 `ftrace=function` 则执行此 tracer 的初始化
+ register_tracer(&function_trace); // 注册 function_trace 到全局 tracer 链表 - trace_type,如果命令行指定 `ftrace=function` 则执行此 tracer 的初始化
list_add(&global_trace.list, &ftrace_trace_arrays); // 添加 `global_trace_list` 到 ftrace_trace_arrays 链表
```
@@ -355,13 +355,13 @@ End of assembler dump.
## 总结
-本文分析 `ftrace_call` 替换为对 `function` tracer 的跟踪函数 `function_trace_call()` 的实现过程。
+本文分析 `ftrace_call` 标签替换为对 `function` tracer 的跟踪函数 `function_trace_call()` 的实现过程。
首先,介绍 `current_tracer` 文件的相关操作函数,其中重点介绍了 `global_trace` 的定义与初始化过程;然后,分析 `tracing_set_trace_write()` 函数的实现以及 `function` tracer 的初始化函数 `function_trace_init()` 的实现;再然后,分析注册跟踪函数的标准接口 `register_ftrace_function()`,其中重点介绍了更新全局跟踪函数的 `update_ftrace_function()` 与列表跟踪函数 `ftrace_ops_list_func()`;最后,我们再次对执行指令替换的标准接口 `ftrace_run_update_code()` 进行分析,简单介绍了其如何在修改指令时做并发保护,分析了 `ftrace_modify_all_code()` 如何解决并发问题以及 `ftrace_update_ftrace_func()` 如何实现对 `ftrace_call` 的指令替换。
-整个替换跟踪函数的过程中,`function` tracer 的跟踪函数大致经历 `function_trace => select_trace_function() => tr->ops->func => ftrace_trace_function()` 这些过程或结构来查找或记录,并最终通过替换 `ftrace_call` 指令来实现对 `function_trace_call()` 函数的调用。
+整个替换跟踪函数的过程中,`function` tracer 的跟踪函数大致经历 `function_trace => select_trace_function() => tr->ops->func => ftrace_trace_function()` 这些过程或结构来查找或记录,并最终通过替换 `ftrace_call` 标签来实现对 `function_trace_call()` 函数的调用。
-自此,我们通过两篇文章分别介绍了函数入口以及跟踪函数的替换过程,相信大家对采用 tracefs 接口进行函数跟踪有了更进一步的理解。下文我们来介绍下同在 tracefs 目录下的 `available_tracers` 文件里的那些 tracer 们。
+自此,我们通过两篇文章分别介绍了函数入口以及跟踪函数的替换过程,相信大家对采用 tracefs 接口进行动态函数跟踪有了更进一步的理解。下文我们来介绍下 Ftrace 中另一个重要的跟踪机制 -- 动态函数图跟踪。
## 参考资料