Linus Torvalds 再改页面锁逻辑,把 if 替换为 while

御坂弟弟
 御坂弟弟
发布于 2021年01月12日
收藏 5

几个月前,Linus Torvalds 在 Linux 5.9 版本中重写了 wait_on_page_bit_common() 相关逻辑,原因是为了解决页面锁竞争的公平性问题。

在这之前,页面锁持有者在执行 ”unlock_page()" 时仅会唤醒等待队列里的一个独占进程(FIFO,且该进程正在执行 “lock_page” ),但是该进程不一定正在运行,特别是在负载情况下,只有其获得 CPU 时间才能真正运行,与此同时,其它正在运行的没有进入等待队列的进程可以直接获得页面锁,这个过程虽然依然有效利用了页面,但会导致非常不公平的情况,被唤醒的等待进程运行后发现页面锁没有释放,于是重新进入等待队列,而且是最后一个,极端情况下,这个进程可能会重复该过程以至于等待数十秒。

因此 Linus Torvalds 修改为在唤醒等待进程时同时会把锁交给它,无论它是否正在运行。

然而,这并没有完全解决问题。自这之后,偶尔会发生 BUG_ON() ,因为上述 “wait-to-set” 的过程并非原子性的,所以被唤醒的进程仍有可能被“第三者插足”。如果要把 “wait-to-set” 这一过程修改为原子性操作,需要修改大约 50 个函数。因此,在上周,Linus Torvalds 把 wait_on_page_writeback () 函数中的 if 修改为 while 来解决这一问题。而这基本上又回到了最开始的情况,不过发生频率要低得多,因此仍然可控。

不过,据外国媒体报道,其在该版上的基准测试中, PostgreSQL 性能下降了 5%-10%,对此,Linus Torvalds 认为这种下降并非由该补丁引起,可能和其测试模型或机器性能有关。

Linux 5.11-rc3 现已发布,感兴趣的同学可以进行相关测试。

更多详细内容查看以下 commit:

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。
转载请注明:文章转载自 开源中国社区 [http://www.oschina.net]
本文标题:Linus Torvalds 再改页面锁逻辑,把 if 替换为 while
加载中

精彩评论

久永
久永
这要是别人这样改,那还不给P死?我觉得下降就是由这个“S循环”造成的,赌一行代码!
luwenhua
luwenhua
看似一个技术问题,实际是一个程序权利的问题 :)
大张皓
大张皓
我查了一下phoronix.com上关于这个问题的评论。
有人提出,从代码逻辑上讲,if会使得trace_wait_on_page_writeback和wait_on_page_bit运行0次或者1次,而while会使得trace_wait_on_page_writeback和wait_on_page_bit运行0次或者N次,确实会增加这段代码运行的时间。
有人提出改成while会增加汇编代码中的JMP指令,可能有指令对齐的问题,但有人说这不会造成指令对齐问题。我更倾向于后者。
在绝大多数情况下,trace_wait_on_page_writeback和wait_on_page_bit只会运行一次。可能是PostgreSQL基准测试,恰好触发了那种运行N次的场景。
这个patch对PostgreSQL性能的影响,只出现在:有100~250个PostgreSQL客户端,同时PostgreSQL服务器是低端硬件,比如桌面级的Core i7/i9或者Ryzen这种机器,这样一种场景下。
对于更大型的服务器,比如有十几个CPU核的数据库服务器来说,这种性能问题并不会出现。
ddatsh
ddatsh
虽然看不懂,不过看来还未彻底解决,之后还会有更好的FIX?
这块东西在3和4的内核同样会有吗
万事通
万事通
为了追求性能及稳定性,大神又出来贡献代码了。

最新评论(17

水溶C100
水溶C100
while括号里面的代码编译后不也是一个if的形式(滑稽)
红薯片
红薯片
嗯,实际上是一个歧视的问题,必须改
eechen
eechen
不建议没有参与过Linux内核开发的人来评论Linus做法的对错,懂的人应该只会说出这种做法的优劣。
欧阳春晖
欧阳春晖
还要保证不破坏功能。。。linux开发的要求很严的,别以为是你平时做的那点,打不了你改别人跟着你改。。。。出了问题继续改。。。。国际协作没这样做的,必须考虑到整个项目的情况,达成共识。。
大张皓
大张皓
这位同学,请你提交一个patch,改变现在的"wait for lock bit to clear and then set it"的代码,把"wait-to-set"做成一个原子操作,并且改掉与之相关的50多个函数。如果patch做对了,Linus大神会给你+1的。
大张皓
大张皓
这个patch对PostgreSQL性能的影响,只出现在:有100~250个PostgreSQL客户端,同时PostgreSQL服务器是低端硬件,比如桌面级的Core i7/i9或者Ryzen这种机器,这样一种场景下。
对于更大型的服务器,比如有十几个CPU核的数据库服务器来说,这种性能问题并不会出现。
Linus当然知道,这会在极其少见的情况下造成性能损失,但这个patch是在页面锁竞争的公平性、代码修改工作量、和性能之间进行权衡之后的选择。
目前来看影响不大,在绝大多数情况下,trace_wait_on_page_writeback和wait_on_page_bit只会运行0次或者1次,而不是循环N次。
大张皓
大张皓
我查了一下phoronix.com上关于这个问题的评论。
有人提出,从代码逻辑上讲,if会使得trace_wait_on_page_writeback和wait_on_page_bit运行0次或者1次,而while会使得trace_wait_on_page_writeback和wait_on_page_bit运行0次或者N次,确实会增加这段代码运行的时间。
有人提出改成while会增加汇编代码中的JMP指令,可能有指令对齐的问题,但有人说这不会造成指令对齐问题。我更倾向于后者。
在绝大多数情况下,trace_wait_on_page_writeback和wait_on_page_bit只会运行一次。可能是PostgreSQL基准测试,恰好触发了那种运行N次的场景。
这个patch对PostgreSQL性能的影响,只出现在:有100~250个PostgreSQL客户端,同时PostgreSQL服务器是低端硬件,比如桌面级的Core i7/i9或者Ryzen这种机器,这样一种场景下。
对于更大型的服务器,比如有十几个CPU核的数据库服务器来说,这种性能问题并不会出现。
bbccaaac
bbccaaac
是不是它导致的性能下降应该用tracepoint或kprobe就能测试出来吧
d
dwcz
个人认为是架构问题--串模拟并,必然的问题。并本身就存在一个“函数内”和“函数间”的问题。
欧阳春晖
欧阳春晖
你不懂就少说几句
返回顶部
顶部