宋宝华:关于Ftrace的一个完整案例
- 2019 年 11 月 7 日
- 筆記
本文系转载,著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者: 宋宝华
来源: 微信公众号linux阅码场(id: linuxdev)
Ftrace简介
Ftrace是Linux进行代码级实践分析最有效的工具之一,比如我们进行一个系统调用,出来的时间过长,我们想知道时间花哪里去了,利用Ftrace就可以追踪到一级级的时间分布。
Ftrace案例
写一个proc模块,包含一个proc的读和写的入口。test_proc_show()故意调用了一个kill_time()的函数,而kill_time()的函数,又调用了mdelay(2)和kill_moretime()的函数,该函数体内调用mdelay(2)。
kill_time()的函数和kill_moretime()函数前面都加了noinline以避免被编译器inline优化掉。
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/version.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/delay.h> #include <linux/uaccess.h>
static unsigned int variable; static struct proc_dir_entry *test_dir, *test_entry;
static noinline void kill_moretime(void) { mdelay(2); }
static noinline void kill_time(void) { mdelay(2); kill_moretime(); }
static int test_proc_show(struct seq_file *seq, void *v) { unsigned int *ptr_var = seq->private; kill_time(); seq_printf(seq, "%un", *ptr_var); return 0; }
static ssize_t test_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct seq_file *seq = file->private_data; unsigned int *ptr_var = seq->private; int err; char *kbuffer;
if (!buffer || count > PAGE_SIZE - 1) return -EINVAL;
kbuffer = (char *)__get_free_page(GFP_KERNEL); if (!kbuffer) return -ENOMEM;
err = -EFAULT; if (copy_from_user(kbuffer, buffer, count)) goto out; kbuffer[count] = '