Linux内核态CRC32算法优化
CRC32算法常用于信息的完整性校验,如网络通信中,在收到网络包之后,先对数据段做CRC32运算,然后将结果与接收到的CRC校验值对比,从而判断收到网络包的完整性。在Linux内核中,包含了一套由C语言实现的CRC32校验代码,但是执行效率不高。在内核态出现大量网络吞吐时,CRC32校验有可能成为性能瓶颈。
同时,在高版本的内核中(Kernel 5.x),已经实现了通过CRC指令的CRC32校验方式,该方式效率更高,能大大减少CRC32算法耗时。接下来介绍如何将该实现合入到kernel 4.x中。
- 从https://github.com/torvalds/linux/blob/master/arch/arm64/lib/crc32.S附件中拷贝crc32.S文件到linux-4.14.105/arch/arm64/lib/目录。
以4.14.105版本内核为例,将CRC32的汇编实现拷贝到linux-4.14.105/arch/arm64/lib/目录:
cp crc32.S linux-4.14.105/arch/arm64/lib/
- 修改Makefile文件。
在linux-4.14.105/arch/arm64/lib/Makefile的末尾加一行,保证添加的crc32.S文件能编译到内核。
obj-$(CONFIG_CRC32) += crc32.o
- 修改lib/crc32.c源码。
对C代码的CRC32校验接口添加__weak标识,通过该标识指明调用crc32_le接口时,该C接口不作为第一优先级调用。此时,若接口存在汇编实现,会优先调用汇编实现。同时,对汇编中实现的接口进行指向。
图1 修改前图2 修改后 - 重新编译内核。
参考:操作系统内核源码编译