-
Notifications
You must be signed in to change notification settings - Fork 38.7k
validation: don't re-acquire cs_main during IBD in CChainState::IsInitialBlockDownload() #24220
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
validation: don't re-acquire cs_main during IBD in CChainState::IsInitialBlockDownload() #24220
Conversation
|
Noticed while reviewing #24178. |
|
I recall that the reason IsIBD was written like this: is so that in the common case -- which is that we've already latched to false -- that we can respond without ever acquiring cs_main inside this function. See #8007 Maybe there's a better refactor that could be done so that we can reduce locking contention on cs_main further, but this patch would have all the call sites grab the lock in order to even call IsIBD(), which would add more cs_main lock acquisitions in general -- and that seems counter to where we want to end up? Is the motivation for this patch to reduce the uses of cs_main as a recursive mutex, and thereby get to a better design? If so that sounds like a good direction, but I think it'd be better if we avoided adding extra lock acquisitions (and holding cs_main longer) in order to get there. For instance it seems like with this patch some of the validation callbacks will now be invoked while holding cs_main the whole time? That seems undesirable. |
|
Yes, the trade-off this pull makes EDIT: is no longer made, thanks to review feedback. Thanks for the link to #8007. It looks like the proportion of callers that hold the lock has since increased. |
9adeef8 to
5159d2c
Compare
Agree with @sdaftuar; IsIBD() is called in a few performance-critical places and at the very least this change should be benchmarked before merge. I'm Concept NACK if this change is essentially just for refactoring's sake; if there's some overarching benefit it would be nice to hear that. |
|
@jamesob I agree; potentially improving performance by not needlessly retaking the cs_main lock is the only point here. |
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
AFAIU lock acquisition is essentially free if it's already held, so I would be surprised if there's a performance gain from avoiding re-acquisition. |
|
Looking ahead at the assumeutxo work in the pipeline, IsIBD() will see further callers already holding cs_main. If the assumption holds that a thread safety annotation is preferable to retaking a lock, we might have our cake and eat it too: the majority can call the core IsIBD() with an annotation, and the seven callers sans lock can go through a wrapper with optimization and lock. |
|
This may also have a silent merge conflict with #22053? |
5159d2c to
b1b3350
Compare
|
Pushed a different approach along the lines of #24220 (comment). It does not increase the scope of
With the latest push, if |
b1b3350 to
a22c867
Compare
I think this is a goal that is almost impossible to achieve with a mutex visible in the global scope/namespace. And if someone did it, it would be brittle and easily lead to UB. See also how for a far simpler and private mutex ( Personally, I think a better way would be to no longer hold cs_main for non-validation uses and then make cs_main private to chainman. |
|
Yes. This change makes explicit which callers hold |
…ng IBD as most of its callers already hold the cs_main lock; have these callers invoke non-locking IsIBD() instead. Retains the post-IBD optimization latch for the callers that do not hold the lock. Makes explicit which callers hold cs_main and which do not.
Ensures that callers now and going forward invoke the correct function.
a22c867 to
601f90e
Compare
|
Updated with @luke-jr and @PastaPastaPasta feedback (thanks!) |
|
🐙 This pull request conflicts with the target branch and needs rebase. Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft". |
There hasn't been much activity lately and the patch still needs rebase. What is the status here?
|
|
Closing for now due to inactivity. Let us know if this should be reopened. |
No longer re-acquire lock
cs_mainduring IBD inCChainState::IsInitialBlockDownload(), as most of its callers already hold the lock. Have these callers invoke non-locking functionCChainState::IsIBD()instead. Apply thread safety analysis to the IBD functions. Retains the post-IBD optimization latch for the callers that do not hold the lock. Makes explicit which callers holdcs_main, and which do not.