除tracing函数调用外,ftrace还可tracing系统的进程切换,唤醒,块设备访问,内核数据结构分配等活动. 注意,tracing和profile是不同的,tracing记录的是一段时间内的全部活动,而不是统计信息,用户可以通过/sys/kernel/debug/tracing下的buffer_size_kb设置缓冲区的大小, 以记录更长时间的数据.
关于ftrace的具体使用可参考内核源码Documenation/trace下的内容
D) oprofile 和 perf
oprofile和perf都是对系统进行profile(抽样,统计)的工具,它们主要用来解决系统和应用的性能问题. perf功能更强大,更全面,同时perf的用户空间工具和内核源码一起维护和发布,让用户能及时的享受perf内核新增加的特征. Perf 是在RHEL6中才有,RHEL5中没有Perf. Oprofile和perf 都使用现代CPU中具有的硬件计数器进行统计工作,但perf还可以使用内核中定义的 “software counter”及 “trace points”, 所以能做更多的工作. Oprofile的抽样工作利用 CPU的NMI中断来进行,而perf既可以利用NMI中断也可利用硬件计数器提供的周期性中断. 用户能很容易用perf来oprofile一个进程或系统的执行时间分布,如
#> perf top -f 1000 -p
还可以利用系统定义的 “software counter”和各子系统的 “trace points” 对子系统进行分析, 如
#>perf stat -a -e kmem:mm_page_alloc -e kmem:mm_page_free_direct -e kmem:mm_pagevec_free sleep 6 能统计6秒内kmem子系统的活动 (这一点实际是利用ftrace提供的tracepoints来实现)
我认为有了perf, 用户就没必要使用oprofile了
4. 用kdump工具定位内核故障实例
A) 部署Kdump
部署 kdump 收集故障信息的步骤如下:
1) 设置好相关的内核启动参数
在 /boot/grub/menu.lst 中加入如下内容
crashkernel=128M@16M nmi_watchdog=1
其中crashkernel参数是用来为kdump的内核预留内存的; nmi_watchdog=1 是用来
激活NMI中断的, 我们在未确定故障是否关闭了中断的情况下, 需要部署NMI watchdog才能确保触发panic. 重启系统确保设置生效
2) 设置好相关的sysctl内核参数
在/etc/sysctl.conf 中最后加入一行
kernel.softlookup_panic = 1
该设置确保softlock发生时会调用panic, 从而触发kdump行为
执行 #>sysctl -p 确保设置生效
3) 配置 /etc/kdump.conf
在 /etc/kdump.conf 中加入如下几行内容
ext3 /dev/sdb1
core-collector makedumpfile -c –message-level 7 -d 31 -i /mnt/vmcoreinfo
path /var/crash
default reboot
其中 /dev/sdb1 是用于放置dumpfile 的文件系统, dumpfile 文件放置在/var/crash下, 要事先在/dev/sdb1分区下创建/var/crash 目录. “-d 31”指定对dump内容的过滤级别,这参数对于dump分区放不下全部内存内容或用户不想让dumping中断业务太长时间时很重要. vmcoreinfo 文件放置在 /dev/sdb1 分区的 / 目录下, 需要使用如下命令产生:
#>makedumpfile -g //vmcoreinfo -x /usr/lib/debug/lib/modules/2.6.18-128.el5.x86_64/vmlinux
“vmlinux” 文件是由kernel-debuginfo 包提供的,在运行makedumpfile 之前需要安装相应内核的 kernel-debuginfo 和 kernel-debuginfo-common 两个包,该两个包需从 下载. “default reboot” 用来告诉kdump, 收集完dump信息后重启系统
4) 激活kdump
运行 #>service kdump start 命令,你会看到,在成功完成的情况下会在/boot/目录下生成一个initrd-2.6.18-128.el5.x86_64kdump.img 文件,该文件就是kdump加载的内核的 initrd文件,收集dump信息的工作就是在该initrd的启动环境下进行的. 查看/etc/init.d/kdump脚本的代码,你可看到其中会调用mkdumprd命令创建用于dump的initrd文件
B) 测试Kdump部署的有效性
为了测试kdump部署的有效性,本人写了如下一个内核模块,通过insmod 加载该内核模块, 就能产生一个内核线程,在10秒左右后,占据100%的CPU,在20秒左右后触发kdump. 系统重启后,检查/Oracle分区/var/crash 目录下的内容,就能确认vmcore文件是否生成.
Zqfthread.c
#include
#include
#include
#include
#include
#include
MODULE_AUTHOR("frzhang@redhat.com");
MODULE_DESCRIPTION("A module to test ....");
MODULE_LICENSE("GPL");
static struct task_struct *zqf_thread;
static int zqfd_thread(void *data);
static int zqfd_thread(void *data)
{
int i=0;
while (!kthread_should_stop()) {
i++;
if ( i < 10 ) {
msleep_interruptible(1000);
printk("%d seconds\n", i);
}
if ( i == 1000 ) // Running in the kernel
i = 11 ;
}
return 0;
}
static int __init zqfinit(void)
{
struct task_struct *p;
p = kthread_create(zqfd_thread, NULL,"%s","zqfd");
if ( p ) {
zqf_thread = p;
wake_up_process(zqf_thread); // actually start it up
return(0);
}
return(-1);
}
static void __exit zqffini(void)
{
kthread_stop(zqf_thread);
}
module_init(zqfinit);
module_exit(zqffini)
Makefile
obj-m += zqfthread.o
Making
#> make -C /usr/src/kernels/2.6.32-71.el6.x86_64/ M=`pwd` modules
C) 用crash 工具分析vmcore 文件