Sign in
Sign up
Explore
Enterprise
Education
Search
Help
Terms of use
About Us
Explore
Enterprise
Education
Gitee Premium
Gitee AI
AI teammates
Sign in
Sign up
Fetch the repository succeeded.
description of repo status
Open Source
>
Other
>
Operation System
&&
Donate
Please sign in before you donate.
Cancel
Sign in
Scan WeChat QR to Pay
Cancel
Complete
Prompt
Switch to Alipay.
OK
Cancel
Watch
Unwatch
Watching
Releases Only
Ignoring
458
Star
1.7K
Fork
1.9K
GVP
openEuler
/
kernel
Closed
Code
Issues
1271
Pull Requests
991
Wiki
Insights
Pipelines
Service
Quality Analysis
Jenkins for Gitee
Tencent CloudBase
Tencent Cloud Serverless
悬镜安全
Aliyun SAE
Codeblitz
SBOM
DevLens
Don’t show this again
Update failed. Please try again later!
Remove this flag
Content Risk Flag
This task is identified by
as the content contains sensitive information such as code security bugs, privacy leaks, etc., so it is only accessible to contributors of this repository.
【openEuler-1.0-LTS】wake_up_page_bit函数存在缺陷,在特殊场景下会产生softlookup
Done
#I93S7P
Task
Zizhi Wo
Opened this issue
2024-02-26 15:10
【严重程度】 一般 【特性】 文件系统/xfs 【重现类型】 无规律重现 【定位分析】 考虑以下两种情况: 1.在多线程并发写相同页面并且执行fsync时,存在这样一种情况: 执行fsync时,会将page都标记为PAGECACHE_TAG_WRITEBACK,然后将等待page更新的线程都放入该page的链表中。 之后,bio回写时,会清除page中的PAGECACHE_TAG_WRITEBACK,同时从该page链表中唤醒等待该page的线程,这个过程是持锁的,但是由于设置了bookmark,一次只能释放最多64个线程,然后会短暂的放锁再持锁。 在这个放锁和持锁的间隔期内,前面被唤醒的线程如果被调度到,会继续写该页面,并执行fsync,这又会使得该page被设置为PAGECACHE_TAG_WRITEBACK,并且线程被放入到page的链表中。 之后,bio回写线程再次持锁,重复上述过程,他一次最多释放64个线程,只要在放锁持锁的窗口期内,重新加入的线程数一直大于64,这个循环就会一直持续,造成soft lockup。 2.在多线程并发写不同页面并且执行fsync时,存在这样一种情况: 执行fsync时,会将修改的page标记为PAGECACHE_TAG_WRITEBACK,然后将等待page更新的线程都放入该page的链表中。由于每个线程写的不同的页面,执行fsync是针对整个文件而言的。因此最终会使得每个page的链表上都关联了许多线程。 为了简化问题,在这里假设fsync执行时,各个页面都已经被置脏了。则每个page链表上都关联了所有的线程。 之后,bio回写时,会清除page中的PAGECACHE_TAG_WRITEBACK,同时从该page链表中唤醒等待该page的线程,这个过程是持锁的,但是由于设置了bookmark,一次只能释放最多64个线程,然后会短暂的放锁再持锁。 假设共有128个线程,写128个不同的page,则每个page链表上都链接了128个线程。fsync需要按序等待所有涉及到的page都更新完毕,才返回。当更新到最后一个page的链表时,先更新前64个线程,更新完毕后短暂释放锁。 在这个放锁期间,前面被唤醒的线程如果被调度到,会继续写不同页面,并执行fsync,这又会使得不同的page被设置为PAGECACHE_TAG_WRITEBACK,并且线程被放入到对应page的链表中。 如果这前64个线程中,有一个写的是第128个page,那么就会将这第128号page的flag再次设置为PAGECACHE_TAG_WRITEBACK。 之后,bio再次持锁并循环时,会唤醒后64个线程然后再放锁。 后64个线程在fsync流程中等待page更新,然后被唤醒后发现第128个页面的PAGECACHE_TAG_WRITEBACK这个flag依然存在,那么会再次被放入到这个page所在的链表中。 之后,bio回写线程继续持锁,再次遍历这第128号page的链表,还是这64个线程,唤醒并再放锁。然后64个线程的fsync流程中发现flag还在,会被继续加到链表中,这个循环就会一直持续,造成soft lockup。 那么这第128号page的PAGECACHE_TAG_WRITEBACK flag何时被清除?得等到前1->127号page都被更新完毕,另外的一些bio回写线程执行到第128号page,才能将此page的PAGECACHE_TAG_WRITEBACK这个flag清除掉。 但是,在这之后又会唤醒前64个线程,重新置脏page,重复上述流程,造成soft lockup。
【严重程度】 一般 【特性】 文件系统/xfs 【重现类型】 无规律重现 【定位分析】 考虑以下两种情况: 1.在多线程并发写相同页面并且执行fsync时,存在这样一种情况: 执行fsync时,会将page都标记为PAGECACHE_TAG_WRITEBACK,然后将等待page更新的线程都放入该page的链表中。 之后,bio回写时,会清除page中的PAGECACHE_TAG_WRITEBACK,同时从该page链表中唤醒等待该page的线程,这个过程是持锁的,但是由于设置了bookmark,一次只能释放最多64个线程,然后会短暂的放锁再持锁。 在这个放锁和持锁的间隔期内,前面被唤醒的线程如果被调度到,会继续写该页面,并执行fsync,这又会使得该page被设置为PAGECACHE_TAG_WRITEBACK,并且线程被放入到page的链表中。 之后,bio回写线程再次持锁,重复上述过程,他一次最多释放64个线程,只要在放锁持锁的窗口期内,重新加入的线程数一直大于64,这个循环就会一直持续,造成soft lockup。 2.在多线程并发写不同页面并且执行fsync时,存在这样一种情况: 执行fsync时,会将修改的page标记为PAGECACHE_TAG_WRITEBACK,然后将等待page更新的线程都放入该page的链表中。由于每个线程写的不同的页面,执行fsync是针对整个文件而言的。因此最终会使得每个page的链表上都关联了许多线程。 为了简化问题,在这里假设fsync执行时,各个页面都已经被置脏了。则每个page链表上都关联了所有的线程。 之后,bio回写时,会清除page中的PAGECACHE_TAG_WRITEBACK,同时从该page链表中唤醒等待该page的线程,这个过程是持锁的,但是由于设置了bookmark,一次只能释放最多64个线程,然后会短暂的放锁再持锁。 假设共有128个线程,写128个不同的page,则每个page链表上都链接了128个线程。fsync需要按序等待所有涉及到的page都更新完毕,才返回。当更新到最后一个page的链表时,先更新前64个线程,更新完毕后短暂释放锁。 在这个放锁期间,前面被唤醒的线程如果被调度到,会继续写不同页面,并执行fsync,这又会使得不同的page被设置为PAGECACHE_TAG_WRITEBACK,并且线程被放入到对应page的链表中。 如果这前64个线程中,有一个写的是第128个page,那么就会将这第128号page的flag再次设置为PAGECACHE_TAG_WRITEBACK。 之后,bio再次持锁并循环时,会唤醒后64个线程然后再放锁。 后64个线程在fsync流程中等待page更新,然后被唤醒后发现第128个页面的PAGECACHE_TAG_WRITEBACK这个flag依然存在,那么会再次被放入到这个page所在的链表中。 之后,bio回写线程继续持锁,再次遍历这第128号page的链表,还是这64个线程,唤醒并再放锁。然后64个线程的fsync流程中发现flag还在,会被继续加到链表中,这个循环就会一直持续,造成soft lockup。 那么这第128号page的PAGECACHE_TAG_WRITEBACK flag何时被清除?得等到前1->127号page都被更新完毕,另外的一些bio回写线程执行到第128号page,才能将此page的PAGECACHE_TAG_WRITEBACK这个flag清除掉。 但是,在这之后又会唤醒前64个线程,重新置脏page,重复上述流程,造成soft lockup。
Comments (
1
)
Sign in
to comment
Status
Done
Backlog
Doing
Done
Declined
Assignees
Not set
Labels
sig/Kernel
Not set
Projects
Unprojected
Unprojected
Pull Requests
None yet
None yet
Successfully merging a pull request will close this issue.
Branches
No related branch
Branches (
-
)
Tags (
-
)
Planed to start   -   Planed to end
-
Top level
Not Top
Top Level: High
Top Level: Medium
Top Level: Low
Priority
Not specified
Serious
Main
Secondary
Unimportant
Duration
(hours)
参与者(2)
C
1
https://gitee.com/openeuler/kernel.git
git@gitee.com:openeuler/kernel.git
openeuler
kernel
kernel
Going to Help Center
Search
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
Comment
Repository Report
Back to the top
Login prompt
This operation requires login to the code cloud account. Please log in before operating.
Go to login
No account. Register