This article directory
Ftrace Introduction Ftrace case Ftrace results how to read? Vm for Ftrace folding
Introduction to Ftrace
Ftrace is one of the most effective tools for Linux to perform code-level practice analysis. For example, if we make a system call, it takes too long. We want to know where the time is spent. We can use Ftrace to trace the time distribution of the first level.
Ftrace case
Write a proc module that contains a proc read and write entry. Test_proc_show() deliberately calls a function of kill_time(), and the function of kill_time() calls the functions of mdelay(2) and kill_moretime(), which calls mdelay(2).
The kill_time() function and the kill_moretime() function are both preceded by a noinline to avoid being optimized by the compiler inline.
#include
#include
#include
#include
#include
#include
#include
#include
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, "%u", *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] = '\0';
*ptr_var = simple_strtoul(kbuffer, NULL, 10);
Return count;
Out:
Free_page((unsigned long)buffer);
Return err;
}
Static int test_proc_open(struct inode *inode, struct file *file)
{
Return single_open(file, test_proc_show, PDE_DATA(inode));
}
Static const struct file_operations test_proc_fops =
{
.owner = THIS_MODULE,
.open = test_proc_open,
.read = seq_read,
.write = test_proc_write,
.llseek = seq_lseek,
.release = single_release,
};
Static __init int test_proc_init(void)
{
Test_dir = proc_mkdir("test_dir", NULL);
If (test_dir) {
Test_entry = proc_create_data("test_rw",0666, test_dir, &test_proc_fops, &variable);
If (test_entry)
Return 0;
}
Return -ENOMEM;
}
Module_init(test_proc_init);
Static __exit void test_proc_cleanup(void)
{
Remove_proc_entry("test_rw", test_dir);
Remove_proc_entry("test_dir", NULL);
}
Module_exit(test_proc_cleanup);
MODULE_AUTHOR("Barry Song <>");
MODULE_DESCRIPTION("proc exmaple");
MODULE_LICENSE("GPL v2");
The corresponding Makefile for the module is as follows:
KVERS = $(shell uname -r)
# Kernel modules
Obj-m += proc.o
# Specify flags for the module compilation.
#EXTRA_CFLAGS=-g -O0
Build: kernel_modules
Kernel_modules:
Make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
Clean:
Make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
Compile and load:
$ make
Baohua@baohua-perf:~/develop/training/debug/ftrace/proc$
$ sudo insmod proc.ko
[sudo] password for baohua:
After the /proc directory, the /proc/test_dir/test_rw file can be read and written.
Below we use Ftrace to track the test_proc_show() function.
We write all the commands to start ftrace to a script function.sh:
#!/bin/bash
Debugfs=/sys/kernel/debug
Echo nop > $debugfs/tracing/current_tracer
Echo 0 > $debugfs/tracing/tracing_on
Echo $$ > $debugfs/tracing/set_ftrace_pid
Echo function_graph > $debugfs/tracing/current_tracer
#replace test_proc_show by your function name
Echo test_proc_show > $debugfs/tracing/set_graph_function
Echo 1 > $debugfs/tracing/tracing_on
Exec "$@"
Then use this script to start cat /proc/test_dir/test_rw, so the test_proc_show() function under ftrace is traced.
# ./function.sh cat /proc/test_dir/test_rw
0
Read the results of the trace:
# cat /sys/kernel/debug/tracing/trace > 1
Then open this file 1 with vim and find that this file has more than 600 lines:
How to read Ftrace results?
How to read Ftrace results? The answer is very simple: if it is a leaf function, it will display the time it takes directly in front of this function. If it is non-leaf, wait until it is, then display the time, as shown below:
The delay is relatively large, there will be special labels such as +, #:
'$' - greater than 1 second '@' - greater than 100 milisecond '*' - greater than 10 milisecond '#' - greater than 1000 microsecond '!' - greater than 100 microsecond '+' - greater than 10 microsecond ' ' - less than or equal to 10 microsecond.
Vim folding Ftrace
The Ftrace file above is too big to be seen. We can use vim to fold it, but need a special configuration of vim, I stored it in my ~ directory, named .fungraph-vim:
" Enable folding for ftrace function_graph traces.
"
" To use, :source this file while viewing a function_graph trace, or use vim's
" -S option to load from the command-line together with a trace. You can then
" use the usual vim fold commands, such as "za", to open and close nested
" functions. While closed, a fold will show the total time taken for a call,
" as would normally appear on the line with the closing brace. Folded
" functions will not include finish_task_switch(), so folding should remain
" Relative sane even through a context switch.
"
" Note that this will almost certainly only work well with a
" single-CPU trace (eg trace-cmd report --cpu 1).
Function! FunctionGraphFoldExpr(lnum)
Let line = getline(a:lnum)
If line[-1:] == '{'
If line =~ 'finish_task_switch() {$'
Return '>1'
Endif
Return 'a1'
Elseif line[-1:] == '}'
Return 's1'
Else
Return '='
Endif
Endfunction
Function! FunctionGraphFoldText()
Let s = split(getline(v:foldstart), '|', 1)
If getline(v:foldend+1) =~ 'finish_task_switch() {$'
Let s[2] = ' task switch '
Else
Let e ​​= split(getline(v:foldend), '|', 1)
Let s[2] = e[2]
Endif
Return join(s, '|')
Endfunction
Setlocal foldexpr=FunctionGraphFoldExpr(v:lnum)
Setlocal foldtext=FunctionGraphFoldText()
Setlocal foldcolumn=12
Setlocal foldmethod=expr
Then we configure vim as this template to open the previous file of more than 600 lines:
Vim -S ~/.fungraph-vim 1
So what we see is:
We can move the cursor to the 5th line, and the keyboard will hit za, then expand to:
Continue to kill_time() on line 6, press za:
We can use the z, a two buttons to search or expand the results of Ftrace.
High Quality Rectifier Diode with Competitive Price, Fast Shipping, Order Now.Years of experience.
The company has domestic advanced diode production equipment, complete testing methods and quality assurance system.
Advanced Technology.Electronic component diodes are widely used in household appliances, green lighting, network communications, power chargers, automotive electronics and other fields.
Rectifier Diode,diode Bridge Rectifier,KBU Bridge Rectifiers,rectifier diode,Fast rectifier diode
Changzhou Changyuan Electronic Co., Ltd. , https://www.cydiode.com