LWN: kmalloc( )确保对齐

640点击上方蓝色字关注我们~



Alignment guarantees for kmalloc()

By Jonathan Corbet
May 8, 2019


LSFMM


kmalloc()是kernel里最基础的内存分配API,用于针对较小的对象分配内存。通常,开发者不用操心返回的memory是否有对齐(alignment)问题,反正一直用的好好的。不过Vlastimil Babka在2019 Linux Storage, Filesystem, and Memory-Management Summit上的一个全员讲座里面指出,kmalloc()有时会有一些出人意料的行为。他建议今后应该让代码更严格,确保kmalloc能给出对齐的memory,从而避免意外。


Babka认为kmalloc()应该针对他所分配的对象而满足他们天生要求的对齐条件(natural alignment)。这里的natural alignment是指分配的内存起始地址需要是三个数字的整数倍:ARCH_KMALLOCMINALIGN(缺省是8个byte),cache-line size(对较大对象来说最好是cache line align的),还有object的size(如果是2的幂次的话)。通常用这三个值的最小公倍数即可。


多数时候,kmalloc()返回的memory会是满足natural align的要求的,都是2的幂次的分配大小。这是因为slab page分配器的实现决定的。不过如果打开了SLUB debug选项,或者使用了SLOB allocator的话,就会有例外。大家不太担心SLOB,毕竟用的人较少,但是SLUB debug比较常用,可能会让开发者碰到问题的时候想不到这个地方。例如平常分配到的都是满足natural align的内存对象,但是突然某一天他们打开SLUB debug选项,然后程序就运行不正常了。Babka已经看到一些Stack Overflow问题都是在问kmalloc()是否能保证满足对齐要求的,不过那些回答都不太对。XFS就肯定会在不满足block-size对齐的情况下会出异常。这里有一些workaround方案,不过就算这样,XFS还是很依赖具体底层实现,而没法强制确保alignment。这些workaround也会导致内存浪费的更多。


James Bottomley问道为什么XFS会有这种对齐需求。Christoph Hellwig回答指出XFS只是一个暴露出这个问题的报信者,而对I/O buffer有比较特别的对齐需求的那些外设来说,这里肯定会有问题。Matthew Wilcox开玩笑说如果block layer能做bounce buffering的话就没问题了。Hellwig很认真回答说开发者都在尽量消除bounce buffering机制,不应该再加回来了。此外,还有别的地方也用kmalloc()分配I/O buffer,它们也会碰到这种问题。


可能有个解决方案,就是对那些明知道自己需要有特定对齐要求的代码,去调用kmem_cache_alloc()来创建特定对齐size的一些cache。不过这样就需要对各种可能分配的size都需要先创建对应的cache。Dave Hansen觉得既然缺省行为是保证正确性,那么也许可以在按照指定alignment进行分配之后,再拼接成缺省的cache,这样就能降低overhead了。Babka觉得这个实现就太乱了。开发者们讨论了如何实现这个机制,不过最后没有达成一致意见。


还有一个可能的解决方案,就是创建一个kmalloc_aligned()函数,可以接受一个指定的alignment参数。这样当需要用到的alignment比起natural alignment值要大的场景会很有用。开发者也会很快知道这个API,然后会慢慢了解合适需要用到。不过,没法保证用这个API的地方都用对了。


Babka觉得,应该让kmalloc()实现里面来确保这点,在分配的size是2的幂次的时候,一定要返回满足natural align条件的memory object。在SLAB里面什么都不用改,SLUB如果不打开debug的话也什么都不用改。因此只有在SLUB debug打开的情况下,需要修改代码,这里会引入一些代价,例如浪费一些memory等。而如果在SLOB里面也实现这个机制来确保的话,会让他已经碎片化的heap变得更加雪上加霜。


Wilcox觉得SLUB的red-zone debugging机制(就是用来监测是否访问超出了分配的范围可能没有什么真的好处吧,毕竟现在KASAN实现了这个功能,干脆把它删掉?不过其他开发者还是有人觉得这个功能很有用处。KASAN的overhead比较大,并且一定要编译进kernel,而red-zone检测可以在运行后动态打开。Ted Ts'o觉得他也想打开red zone机制,打开KASAN通常要花很多功夫。Hellwig也说每次当有人提出增加一个新的数据结构的时候,他都会先打开red zone来看看。


Babka指出,虽然确保alignment能让kmalloc()的用户用起来更加简单一些,不过这也会引入一些代价。打开SLUB debug的kernel通常都会有一些性能损失,SLOB则更加低效了。此外如果实现严格模式的话,就会限制slab allocator今后可能的一些改进方向,例如Christoph Lameter就指出这回让今后在object里面增加metadata更加困难。


Bottomley建议做一点变化:只针对512 byte一下的object来做natural alignment,而对更大的object只保证512-byte align。分配的memory要是比一个page还大的话,那应该直接做page alignment。Babka认为这种特殊策略会让实现过于复杂。Ts'o觉得不值得花太多精力去解决所有的潜在问题,只要多花一点memory能解决那些更常出现的问题,那还是值得的。


Hugh Dickins替SLOB用户感到比较担心。通常SLOB用户都会在一些内存资源很少的设备上运行系统,他们可能会收到更多影响,例如分配memory的耗时更常,占用的内存空间也会多。可能不久之后内核开发者就会听到他们的反馈。Babka回复认为,情况可能不一定那么糟糕,毕竟SLOB的heap里面有更多的内存碎片空洞,不过最终都被分配的小对象给填满了。Wilcox指出SLOB会在分配出来的对象前面多保留4 byte来存储对象的size,这种会让需要满足对齐条件的情况很难处理。Bobka答应后续他会多看看SLOB里面的损耗,不过他也不太希望因为SLOB(毕竟用户非常少)而阻碍这个机制的合入。


全文完

LWN文章遵循CC BY-SA 4.0许可协议。

极度欢迎将文章分享到朋友圈 
热烈欢迎转载以及基于现有协议上的修改再创作~


长按下面二维码关注:Linux News搬运工,希望每周的深度文章以及开源社区的各种新近言论,能够让大家满意~


640?wx_fmt=jpeg

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值