Prevent process_blockstore_from_root() from holding Bank for too long (#31179)

blockstore_processor::process_blockstore_from_root() starts with a
BankForks that contains exactly one Bank. The function grabs an Arc of
this initial Bank, and does some logging and initial setup before
processing more slots in load_frozen_forks().

process_blockstore_from_root() holds that Arc until it returns. This
increases the ref count and prevents the initial Bank from getting
cleaned up in a timely manner if load_frozen_forks() prunes that initial
Bank from BankForks.

This change extracts the needed information from the Arc<Bank>, and
drops the Arc so that the Bank can be dropped in a timely manner.
This commit is contained in:
steviez 2023-04-12 23:10:26 -05:00 committed by GitHub
parent a5bd85cf75
commit c834d2fc95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 9 deletions

View File

@ -743,12 +743,14 @@ pub fn process_blockstore_from_root(
cache_block_meta_sender: Option<&CacheBlockMetaSender>,
accounts_background_request_sender: &AbsRequestSender,
) -> result::Result<(), BlockstoreProcessorError> {
// Starting slot must be a root, and thus has no parents
assert_eq!(bank_forks.read().unwrap().banks().len(), 1);
let bank = bank_forks.read().unwrap().root_bank();
assert!(bank.parent().is_none());
let (start_slot, start_slot_hash) = {
// Starting slot must be a root, and thus has no parents
assert_eq!(bank_forks.read().unwrap().banks().len(), 1);
let bank = bank_forks.read().unwrap().root_bank();
assert!(bank.parent().is_none());
(bank.slot(), bank.hash())
};
let start_slot = bank.slot();
info!("Processing ledger from slot {}...", start_slot);
let now = Instant::now();
@ -757,16 +759,16 @@ pub fn process_blockstore_from_root(
if blockstore.is_primary_access() {
blockstore
.mark_slots_as_if_rooted_normally_at_startup(
vec![(bank.slot(), Some(bank.hash()))],
vec![(start_slot, Some(start_slot_hash))],
true,
)
.expect("Couldn't mark start_slot as root on startup");
.expect("Couldn't mark start_slot as root in startup");
blockstore
.set_and_chain_connected_on_root_and_next_slots(bank.slot())
.set_and_chain_connected_on_root_and_next_slots(start_slot)
.expect("Couldn't mark start_slot as connected during startup")
} else {
info!(
"Starting slot {} isn't root and won't be updated due to being secondary blockstore access",
"Start slot {} isn't a root, and won't be updated due to secondary blockstore access",
start_slot
);
}