遇到一个问题,内核某驱动在alloc一个order=5的page时失败了,查看/proc/meminfo发现memfree是够的,但是/proc/buddyinfo里的大块内存没有了,这是一个典型的内存碎片化的问题。即总内存是够的,但是连续的大块内存却没有了。
那么针对这种内存碎片的问题有没有什么解决方法呢,目前好像没有什么好办法(欢迎讨论),在alloc page的时候,如果alloc失败,会触发内存回收以及内存规整,如果还失败了,那就没什么办法了,所以我们在写内核代码的时候,应尽量避免这种情况发生:
1.如在需要大块内存时,如不要求内存的物理地址连续,应尽量使用vmalloc来代替;
2.在使用kmalloc时尽量只申请order=0的page;
3.如果非要连续的大块内存,尽量先预留好;
上面的问题,最后也是调整内核驱动的分配内存逻辑解决的。
另外,也可以尝试提高watermark_boost_factor的值,这个参数会通过动态调节整体提升zone的min、low、high的水位,但应该注意的是kswapd触发内存回收的逻辑是空闲内存低于low水位开始,直到空闲内存高于high水位停止,如果水位设置过高,在小内存设备稍微使用一些内存,空闲内存就会低于low水位,则会触发kswapd回收。如果设置得过高,则会导致min水位过高,min水位之下的内存难以被使用到。
最后还可以尝试调整/proc/sys/vm/compaction_proactiveness参数来调节内存规整。