LWN: 确保kmalloc()分配是对齐的

Implementing alignment guarantees for kmalloc()

October 18, 2019

This article was contributed by Marta Rybczyńska

kmalloc()是kernel中经常用到的针对小块目标进行内存分配的函数。在2019 Linux Storage, Filesystem, and Memory Management Summit上,Vlastimil Babka的演讲介绍了开发者在使用这个API时意外碰到的alignment(对齐)问题。几个月后,他提出了第二版的patch set,对kmalloc()实现了natural alignment(自然对齐,具体来说假如这个对象的字节数是2的指数的话,buffer应该是按同样size做过对齐的)。起初,大家强烈反对这个方案,看起来没可能合入kernel,不过最终Linus Torvalds还是合入了。我们一起来看看发生了什么。

Babka打算修复的问题是kmalloc()有时候返回的对象不是natually aligned的。通常,kmalloc()返回的buffer还是满足自然对齐要求的,因此不少驱动和内核子系统也依赖这个条件。但是如果打开了SLUB debugging功能,或者使用了SLOB分配器的话就可能得到不满足自然对齐的buffer。kmalloc()其实是对SLAB, SLUB或者SLOB分配器的一个封装接口,具体用得是那个,取决于kernel config的配置。感兴趣的读者可以回顾一下2007年的文章介绍为什么要引入SLUB分配器(https://lwn.net/Articles/229984/ ),还有看一下2014年LinuxCon会议上对三个分配器的介绍(https://events.static.linuxfound.org/sites/events/files/slides/slaballocators.pdf  )。如果返回的buffer没有满足对齐条件的话,可能就会出现数据损坏等错误。为了应对这个问题,Babka建议要确保分配的buffer(如果size是2的指数次方的话)能满足自然对齐的要求,这样就能满足所有的对齐需求了。

For and against kmalloc() alignment

在讨论patch set的时候,Christopher Lameter(SLUB分配器的作者)不赞同增加自然对齐的观点,他认为kmalloc()自己原有的对齐限制(KMALLOC_MINALIGN)是合理的,因为它能优化内存分配减少浪费的空间。SLOB分配器就是个例子,它主要的设计目标是小型的嵌入式系统,希望尽量减少内存浪费。Babka的patch会改变SLOB的行为,导致达不到预期目标。并且,今后新实现的分配器都不得不考虑这个强加的限制,这样就没法针对它们的目标场景进行深度优化了。

Matthew Wilcox比较支持Babka的方案,因为其实已经有很多内核子系统代码都依赖这个对齐特性了。他举了persistent-memory(pmem)和RAM-disk驱动的例子。XFS文件系统,本身没法保证对齐,所以针对512字节到PAGE_SIZE之间的对象,都需要slab cache(缓存),甚至可能会需要更多的slab cache,取决于kmalloc()本身能保证到什么程度的对齐。

Dave Chinner赞成对小buffer来确保对齐,而对大buffer(超过一个page size的)则直接按照page边界对齐。这是他在用KASAN处理pmem的时候看到的需求。不过他建议用一个GFP flag来通知分配器是否要返回一个自然对齐的buffer,如果分配器不能满足这个要求的话直接返回失败信息即可。这样就不需要让内核其他部分的代码来创建更多的cache了。Babka等更多开发者则建议用一个单独的flag来处理这个情况。

接着大家热烈讨论了一下这个问题的重要性。Lameter觉得这种不对齐的情况应该是很罕见的,甚至可能根本不会出现,因为在各个发行版的测试系统测试时,都是打开slab debug功能的,没看到哪个驱动出问题。Christoph Hellwig则指出,出错情况通常需要一些特殊条件,例如buffer刚好跨越了page边界。

From a private NAK to the mainline

在这些讨论之后,Babka问大家是否赞成合入这个patch set:“如果有人觉得这个主意不错,请说出来(最好用正式Acked-by等方式),否则的话,这个patch就到此结束了(因为收到了private NACK——私下表示反对)”。

David Sterba回复说,他此前就曾经针对这种未对齐的情况使用了一些workaround方法,如果能fix kmalloc(),那他很愿意把workaround删掉了。

Darrick J. Wong也表示赞同,并且强烈要求讨论应该公开进行:“噢,我还不知道,咱们中间有些人有权力能通过private NACK来组织一个patch的合入,都不需要经过繁琐的公开讨论啊!”

Andrew Morton把话题引回了技术讨论上,要求开发者们能验证确保这个patch本身的正确性。Lameter从技术角度确认是可行的,不过仍然坚持反对这个出发点。接下来又收到很多赞同意见(Acked-by:),这些内核开发者表示支持Babka的方案。

这些赞同意见之后,公开讨论没有再进行了,Babka也没有再提交第三版。看起来这里卡住了,因为有不少开发者支持这组patch set,但是受这组patch影响最大的SLUB allocator maintainer本人并不支持。不过,最终这个patch还是合入了Morton的代码库,然后在10月7日合入了mainline。

Summary

这组讨论很好的展示了内核社区如何处理这种会导致旧有行为被改变的patch。不出意料,并不是所有开发者都支持这个方案的,不过,在本例中,反对者是这个子系统的maintainer本人。最终接过来看,这类改动还是可以被接受到mainline的,毕竟有很多kmalloc()用户以及其他内存你管理代码开发者都支持这么改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值