前段时间写的一个转发模块在现网应用后
几台设备出现了不同程度的内存泄露
大约4-15天设备内存耗尽
泄露速度因业务压力和网络丢包情况而不同
经历了N次的代码review和一个不眠之夜后
终于找到了原因
在一处释放skb的地方
本应该使用kfree_skb()的,鬼使神差的被我敲成了kfree()
教训很深刻
遂仔细查看了相关函数
以SLUB分配方式为例
alloc_skb()位于include/linux/skbuff.h中
是对__alloc_skb()的内联封装函数,快速克隆标志为0
在__alloc_skb()中根据fclone标志从缓存skbuff_fclone_cache或skbuff_head_cache中分配struct sk_buff控制结构
随后根据size分配按缓存线对齐的线性区长度空间
skbuff_fclone_cache和skbuff_head_cache由skb_init()调用kmem_cache_create()初始化
kfree_skb()位于net/core/skbuff.c中
进行必要的判断后根据情况调用__kfree_skb()
在__kfree_skb()中会调用skb_rele