Skip to content
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

Remove cs_main lock annotation from ChainstateManager.m_blockman #24024

Merged
merged 1 commit into from
Jan 12, 2022

Conversation

ryanofsky
Copy link
Contributor

@ryanofsky ryanofsky commented Jan 10, 2022

BlockManager is a large data structure, and cs_main is not required to take its address or access every part of it. Individual BlockManager fields and methods which do require cs_main like m_block_index and LookupBlockIndex are already annotated separately, and these other annotations describe locking requirements more accurately and do a better job enforcing thread safety.

Since cs_main is not needed to access the address of the m_block object, this commit drops cs_main LOCK calls which were added pointlessly to satisfy this annotation in the past.

Code changes were made by dongcarl, I just wrote the commit description

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 11, 2022

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

No conflicts as of last run.

@maflcko
Copy link
Member

maflcko commented Jan 11, 2022

cr ACK 5a1c413

cs_main is a validation lock. It has nothing to do with writing or reading blocks from disk (other than being historically used for that). Ideally nothing in blockman depends on cs_main.

BlockManager is a large data structure, and cs_main is not required to
take its address or access every part of it. Individual BlockManager
fields and methods which do require cs_main like m_block_index and
LookupBlockIndex are already annotated separately, and these other
annotations describe locking requirements more accurately and do a
better job enforcing thread safety.

Since cs_main is not needed to access the address of the m_block object,
this commit drops cs_main LOCK calls which were added pointlessly to
satisfy this annotation in the past.

Co-authored-by: Carl Dong <[email protected]>
Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Light ACK. Attempted removing a few additional related cs_main locks and saw the expected warnings.

src/validation.h Outdated
@@ -826,7 +826,7 @@ class ChainstateManager
std::thread m_load_block;
//! A single BlockManager instance is shared across each constructed
//! chainstate to avoid duplicating block metadata.
BlockManager m_blockman GUARDED_BY(::cs_main);
BlockManager m_blockman{};
Copy link
Member

@jonatack jonatack Jan 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add the braces? m_blockman is initialized in the ctor (unless I'm missing something). Question for my benefit :) constructor implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #24024 (comment)

Why add the braces? m_blockman is initialized in the ctor (unless I'm missing something). Question for my benefit :)

Not sure since Carl sent me this commit, but it seems good to clean this up. I dropped the braces just to avoid unnecessary punctuation. The braces would never do anything since BlockManager isn't a primitive type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the ctor

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked them, because they clarified that there is no ctor and the initialization happens inline

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked them, because they clarified that there is no ctor and the initialization happens inline

I wouldn't object to adding them back if people have strong opinions, but they don't guarantee this. Someone could add a ChainStateMananger constructor in the future which does pass arguments to the m_blockman constructor, and this code would still compile as long as m_blockman also has a default constructor. The nice thing about plain BlockManager m_blockman; is it says "ChainStateMananger has a m_blockman member. If you care about how it will be constructed, go look at the constructor implementation, like you need to do anyway."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh indeed, thanks for the responses!

Copy link
Contributor Author

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased 5a1c413 -> ce95fb3 (pr/block.1 -> pr/block.2, compare) due to conflict with #23497

src/validation.h Outdated
@@ -826,7 +826,7 @@ class ChainstateManager
std::thread m_load_block;
//! A single BlockManager instance is shared across each constructed
//! chainstate to avoid duplicating block metadata.
BlockManager m_blockman GUARDED_BY(::cs_main);
BlockManager m_blockman{};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #24024 (comment)

Why add the braces? m_blockman is initialized in the ctor (unless I'm missing something). Question for my benefit :)

Not sure since Carl sent me this commit, but it seems good to clean this up. I dropped the braces just to avoid unnecessary punctuation. The braces would never do anything since BlockManager isn't a primitive type.

@ryanofsky
Copy link
Contributor Author

re: #24024 (comment)

cs_main is a validation lock. It has nothing to do with writing or reading blocks from disk (other than being historically used for that). Ideally nothing in blockman depends on cs_main.

That's a good point. It is important to have some lock guarding things like m_block_index but it it doesn't need to be cs_main and maybe ideally it would be a more narrow lock. It looks like there is more discussion about this at #22932 (comment)

@maflcko
Copy link
Member

maflcko commented Jan 11, 2022

cr ACK ce95fb3

@dongcarl
Copy link
Contributor

crACK ce95fb3

Thanks for PRing this!

@jonatack
Copy link
Member

ACK ce95fb3 per git range-diff db1f04f 5a1c413 ce95fb3 change since last push is rebase and dropping braces on the member initialization

@maflcko maflcko merged commit 1f7acfd into bitcoin:master Jan 12, 2022
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Jan 12, 2022
…nager.m_blockman

ce95fb3 Remove cs_main lock annotation from ChainstateManager.m_blockman (Ryan Ofsky)

Pull request description:

  `BlockManager` is a large data structure, and `cs_main` is not required to take its address or access every part of it. Individual `BlockManager` fields and methods which do require `cs_main` like `m_block_index` and `LookupBlockIndex` are already annotated separately, and these other annotations describe locking requirements more accurately and do a better job enforcing thread safety.

  Since `cs_main` is not needed to access the address of the m_block object, this commit drops `cs_main` LOCK calls which were added pointlessly to satisfy this annotation in the past.

  Code changes were made by dongcarl, I just wrote the commit description

ACKs for top commit:
  MarcoFalke:
    cr ACK ce95fb3
  dongcarl:
    crACK ce95fb3
  jonatack:
    ACK ce95fb3 per `git range-diff db1f04f 5a1c413 ce95fb3` change since last push is rebase and dropping braces on the member initialization

Tree-SHA512: b18a6ebcc70bea750485f04d4feb7bb28450fea2176e513be9cc242e9f63b24254c5659e74eb6d6045c706a3aaeb94688937b25b7ca7653f8aa3cf8c18845d5a
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Dec 19, 2022
Summary:
BlockManager is a large data structure, and cs_main is not required to
take its address or access every part of it. Individual BlockManager
fields and methods which do require cs_main like m_block_index and
LookupBlockIndex are already annotated separately, and these other
annotations describe locking requirements more accurately and do a
better job enforcing thread safety.

Since cs_main is not needed to access the address of the m_block object,
this commit drops cs_main LOCK calls which were added pointlessly to
satisfy this annotation in the past.

Co-authored-by: Carl Dong <[email protected]>

This is a backport of [[bitcoin/bitcoin#24024 | core#24024]]

Test Plan:
With clang and Debug
`ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D12909
@bitcoin bitcoin locked and limited conversation to collaborators Jan 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants