1,配置menuconfig
Kernel hacking > Memory Debugging
配置 config=y
[*] SLUB debugging on by default
[*] Enable SLUB performance statistics
配置之前
lark@ubuntu:~/Public/rk356x-linux/rk356x-linux/kernel$ cat .config | grep "CONFIG_SLUB"
CONFIG_SLUB_SYSFS=y
CONFIG_SLUB_DEBUG=y
# CONFIG_SLUB_MEMCG_SYSFS_ON is not set
CONFIG_SLUB=y
CONFIG_SLUB_CPU_PARTIAL=y
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
.
配置之后看.config
lark@ubuntu:~/Public/rk356x-linux/rk356x-linux/kernel$ cat .config | grep "CONFIG_SLUB"
CONFIG_SLUB_SYSFS=y
CONFIG_SLUB_DEBUG=y
# CONFIG_SLUB_MEMCG_SYSFS_ON is not set
CONFIG_SLUB=y
CONFIG_SLUB_CPU_PARTIAL=y
CONFIG_SLUB_DEBUG_ON=y
CONFIG_SLUB_STATS=y
或者配置defconfig,配置完之后需要clean后再编译
Public\rk356x-linux\rk356x-linux\kernel\arch\arm64\configs\rockchip_linux_defconfig
改后的代码路径rk356x-linux\kernel\mm\Makefile
obj-$(CONFIG_KSM) += ksm.o
obj-$(CONFIG_PAGE_POISONING) += page_poison.o
obj-$(CONFIG_SLAB) += slab.o
obj-$(CONFIG_SLUB) += slub.o
obj-$(CONFIG_KASAN) += kasan/
obj-$(CONFIG_KFENCE) += kfence/
obj-$(CONFIG_FAILSLAB) += failslab.o
SLAB或者SLUB有一个用就可以,改menuconfig没有clean会覆盖之前的更改,现在看一下编译的过程。编译的流程
make -C /home/lark/Public/rk356x-linux/rk356x-linux/kernel/ -j5 CROSS_COMPILE=/home/lark/Public/rk356x-linux/rk356x-linux/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- ARCH=arm64 rockchip_linux_defconfig
更改slab除了menuconfig之外可以在 rockchip_linux_defconfig中更改,配置完重新编译之后:
lark@ubuntu:~/Public/rk356x-linux/rk356x-linux/kernel$ cat .config | grep "SLUB"
CONFIG_SLUB_SYSFS=y
CONFIG_SLUB_DEBUG=y
# CONFIG_SLUB_MEMCG_SYSFS_ON is not set
CONFIG_SLUB=y
CONFIG_SLUB_CPU_PARTIAL=y
CONFIG_SLUB_DEBUG_ON=y
CONFIG_SLUB_STATS=y
当slab_unreclamiable一直增加时我们怀疑是内核态内存泄漏,这个时候我们可以看是哪个kmalloc申请的内存多。
首先看slabinfo按的size排序查看 slub object,可以查看 space 总占用大小,及objects个数判断泄漏点 为kmalloc-128。
当没看到/sys/kernel/debug或者没有权限或者打开失败后:
umount /sys/fs/bpf /sys/kernel/debug/
mount -t debugfs none /sys/kernel/debug
那个泄露多看/sys/kernel/debug的slab/kmalloc*-的alloc-traces和free-traces。
root@ubuntu2004:/sys/kernel/debug/slab/kmalloc-128# ls
alloc_traces free_tracesroot@ubuntu2004:#cat alloc_traces
root@ubuntu2004:#cat free_traces
主动去触发slub debug检查
echo 1 > /sys/kernel/slab/kmalloc-128/validate
1,查看slab 使用状态
cat /proc/slabinfo
2,查看slab debug信息,统计状态等
/sys/kernel/slab/*
root@ubuntu2004:/sys/kernel/slab/kmalloc-128# echo 1 > validate
root@ubuntu2004:/sys/kernel/slab/kmalloc-128# echo 1 > trace
3,调试内存泄漏,踩踏等信息
/sys/kernel/debug/slab/*
root@ubuntu2004:/sys/kernel/debug/slab/kmalloc-128#cat alloc_traces
对比alloc和free次数,找到比较多的。
跟踪代码
rk356x-linux\kernel\net\rfkill\rfkill-wlan.c
static int rfkill_wlan_remove(struct platform_device *pdev)
{
struct rfkill_wlan_data *rfkill = platform_get_drvdata(pdev);LOG("Enter %s\n", __func__);
wake_lock_destroy(&rfkill->wlan_irq_wl);
fb_unregister_client(&rfkill_wlan_fb_notifier);
if (gpio_is_valid(rfkill->pdata->power_n.io))
gpio_free(rfkill->pdata->power_n.io);if (gpio_is_valid(rfkill->pdata->reset_n.io))
gpio_free(rfkill->pdata->reset_n.io);//此处没有kfree
// kfree(rfkill);
// g_rfkill = NULL;return 0;
}