LWN: kmalloc( )确保对齐

news/2024/6/29 8:26:15
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


http://www.niftyadmin.cn/n/734177.html

相关文章

swiper轮播图

<!-- 轮播图 --><div class"swiper-container swiper1"><div class"swiper-wrapper"><div class"swiper-slide"><img src"./images/0.jpg" alt""></div><div class"swiper-sli…

LWN: 配置lockdown security module

点击上方蓝色字关注我们~Lockdown as a security moduleBy Jonathan CorbetJune 24, 2019像UEFI secure boot&#xff08;安全引导&#xff09;这一类的技术&#xff0c;目的都是为了保证运行的系统软件是发布者指定的版本&#xff08;这里定义一下发布者&#xff0c;是指firmw…

es6 -- 默认参数Default,不定参数Rest,扩展运算符Spread详解

欢迎访问我的个人博客&#xff1a;http://www.xiaolongwu.cn 前言 记录一下在实际开发中&#xff0c;很有用的三个es6的新方法 用法详解 默认参数 function f(x, y13) {// 如果没有传入y或传入了undefined&#xff0c;y的默认值为13return x y; } f(5) // 18 不定参数Rest 不定…

tab选项卡联动swiper轮播图

function tabs(obj, swiperObj, className, index) {var tabSwiper new Swiper(swiperObj, {initialSlide: index, // 设定初始化时slide的索引speed: 500, //滑动速度&#xff0c;单位ms// autoHeight: true, //高度随内容变化onSlideChangeStart: function() {if (tabSwiper…

H5页面调用原生方法返回

var userAgent navigator.userAgent.toLowerCase(); // 调用原生方法返回 function back() {if (equipment(iphone)) {naviBack({ isRefresh: 0, callBack: isRefresh() });} else if (equipment(ipad)) {naviBack({ isRefresh: 0, callBack: isRefresh() });} else if(equipm…

LWN: FreeBSD已经26周年啦!

点击上方蓝色字关注我们~FreeBSD turns 26June 21, 2019This article was contributed by Sean KernerFreeBSD在创建之后&#xff0c;已经活跃开发了26年了。目前活跃开发的领域包括RISC-V处理器支持&#xff0c;FUSE文件系统的更新&#xff0c;C运行时库的改动&#xff0c;以及…

吴恩达:按照这5步,传统公司也可转型人工智能\n

12月13日&#xff0c;吴恩达在自己的创业公司网站Landing.ai上发布了一本《人工智能转型手册》&#xff0c;旨在为传统公司转型AI提供指导和帮助&#xff0c;我们翻译了部分内容&#xff0c;并在文末附上了手册的下载链接&#xff0c;供读者阅读。 以下内容为InfoQ整理翻译&…

判断设备类型android和iphone

$(function () {// 判断设备类型var u navigator.userAgent;var isAndroid u.indexOf(Android) > -1 || u.indexOf(Adr) > -1; //android终端 var isiOS !!u.match(/\(i[^;];( U;)? CPU.Mac OS X/); //ios终端if (isiOS true) {addHeight();}$(.line2:last).css(di…