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_traces > > root@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; > > }