-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CP io fibers deadlock #634
Comments
HO's pr triggers back-to-back cp instead of force cp. We have adjusted the number of On the HS side, there is no occurrence of concurrent checkpoints. However, even with sequential CP flushes, there remains a risk of deadlock. @JacksonYao287 , could you please provide more details on this? |
let me clarify the root cause of the dead lock issue found in cp_flush. Background
from the code above , we create a reactor with 2 fibers for now, which is 8 before the workaround PR. then we select all the sync_io fibers as our worker fibers. sync_io fibers are all the fibers in the reactor excluding the main_fiber(first fiber). thus, if the num of fibers here is larger than 2 when creating the reactor , we will have multiple worker fibers.
from the two code pieces above, we can see when we submit a io job to cp reactor, we will random select a sync_io fiber. thus , if there are multiple sync_io fibers, different sync_io fiber will take different io job.
Root Cause
from the code above, when one cp flush is done , it will submit an io job to the cp reactor and from the perspective of cp_manager, it considers this cp flush is done and can start a new cp flush. note that, it does not wait for this io job to be done, and we have no idea when this io job will be handled since it is scheduled by the fiber scheduler. also, in this code we can see it will try to update metablk(m_sb.write()), where a metablk lock will be acquired. moreover, m_sb.write() is a sync io, as described above as background#2, it will acquire the lock and then yield to another fiber without freeing the lock there is a scenario that before this cp_flush_done io job is completed, another cp_flush is triggered where it will try to update metablk and try to acquire the metablk , then the deadlock will happen since the lock is occupied by the previous fiber which is has yielded , and the current fiber will block and try to acquire the lock. one example is the wb_cache#cp_flush
here, m_vdev->cp_flush(cp_ctx) will try to update metablk, which will try to acquire the meta lock. if it is trying to update metablk but ATM the job created by on_cp_flush_done is still trying to update the metablk, we mightly hit the deadlock issue. also the blocking stack can be seen at here. Conclusion now, we use a workaround pr to set the num of sync_io fiber to only one so that all the io jobs will be executed sequentially since there is only one fiber which can do sync_io job also , we can change run_on_forget to run_on_wait in CPManager::on_cp_flush_done to make sure before the next cp starts , all the sync_io of previous cp is done |
we met the deadlock issue during NuObject2.0 SM long running test. here's the issue link:
https://docs.google.com/document/d/16DMqv9J-JuNs5c25IBuX01QXe5WbxPm4B4hAfz4JNZM/edit?tab=t.0#heading=h.94n4m5lw7ms3
The problem is if fiber hold a thread-level lock and do sync io , its will be yield, other fibers can come in. So there is a deadlock risk if other fiber acquire the same thread-level lock.
The text was updated successfully, but these errors were encountered: