Introduction to WF-based Ftrace, case, result reading, and analysis of Ftrace folding with vim

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:

Introduction to WF-based Ftrace, case, result reading, and analysis of Ftrace folding with vim

Introduction to WF-based Ftrace, case, result reading, and analysis of Ftrace folding with vim

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:

Introduction to WF-based Ftrace, case, result reading, and analysis of Ftrace folding with vim

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:

Introduction to WF-based Ftrace, case, result reading, and analysis of Ftrace folding with vim

We can move the cursor to the 5th line, and the keyboard will hit za, then expand to:

Introduction to WF-based Ftrace, case, result reading, and analysis of Ftrace folding with vim

Continue to kill_time() on line 6, press za:

Introduction to WF-based Ftrace, case, result reading, and analysis of Ftrace folding with vim

We can use the z, a two buttons to search or expand the results of Ftrace.

Introduction to WF-based Ftrace, case, result reading, and analysis of Ftrace folding with vim

Rectifier Diode KBU

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.

Diode

Rectifier Diode,diode Bridge Rectifier,KBU Bridge Rectifiers,rectifier diode,Fast rectifier diode

Changzhou Changyuan Electronic Co., Ltd. , https://www.cydiode.com