Move dropping AppendVecs outside lock (#12408)

* Move drop outside lock

Co-authored-by: Carl Lin <carl@solana.com>
This commit is contained in:
carllin 2020-09-23 14:17:49 -07:00 committed by GitHub
parent ff890c173c
commit 55be8d4016
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 113 additions and 4 deletions

View File

@ -856,9 +856,10 @@ impl AccountsDB {
trace!("shrink_stale_slot: slot: {}", slot);
let mut stored_accounts = vec![];
let mut storage_read_elapsed = Measure::start("storage_read_elapsed");
{
let storage = self.storage.read().unwrap();
if let Some(stores) = storage.0.get(&slot) {
let slot_storages = self.storage.read().unwrap().0.get(&slot).cloned();
if let Some(stores) = slot_storages {
let mut alive_count = 0;
let mut stored_count = 0;
for store in stores.values() {
@ -897,7 +898,9 @@ impl AccountsDB {
}
}
}
storage_read_elapsed.stop();
let mut index_read_elapsed = Measure::start("index_read_elapsed");
let alive_accounts: Vec<_> = {
let accounts_index = self.accounts_index.read().unwrap();
stored_accounts
@ -921,6 +924,7 @@ impl AccountsDB {
)
.collect()
};
index_read_elapsed.stop();
let alive_total: u64 = alive_accounts
.iter()
@ -941,7 +945,16 @@ impl AccountsDB {
aligned_total
);
let mut rewrite_elapsed = Measure::start("rewrite_elapsed");
let mut dead_storages = vec![];
let mut find_alive_elapsed = 0;
let mut create_and_insert_store_elapsed = 0;
let mut store_accounts_elapsed = 0;
let mut update_index_elapsed = 0;
let mut handle_reclaims_elapsed = 0;
let mut write_storage_elapsed = 0;
if aligned_total > 0 {
let mut start = Measure::start("find_alive_elapsed");
let mut accounts = Vec::with_capacity(alive_accounts.len());
let mut hashes = Vec::with_capacity(alive_accounts.len());
let mut write_versions = Vec::with_capacity(alive_accounts.len());
@ -952,12 +965,18 @@ impl AccountsDB {
hashes.push(*account_hash);
write_versions.push(*write_version);
}
start.stop();
find_alive_elapsed = start.as_us();
let mut start = Measure::start("create_and_insert_store_elapsed");
let shrunken_store = self.create_and_insert_store(slot, aligned_total);
start.stop();
create_and_insert_store_elapsed = start.as_us();
// here, we're writing back alive_accounts. That should be an atomic operation
// without use of rather wide locks in this whole function, because we're
// mutating rooted slots; There should be no writers to them.
let mut start = Measure::start("store_accounts_elapsed");
let infos = self.store_accounts_to(
slot,
&accounts,
@ -965,16 +984,59 @@ impl AccountsDB {
|_| shrunken_store.clone(),
write_versions.into_iter(),
);
start.stop();
store_accounts_elapsed = start.as_us();
let mut start = Measure::start("update_index_elapsed");
let reclaims = self.update_index(slot, infos, &accounts);
start.stop();
update_index_elapsed = start.as_us();
let mut start = Measure::start("update_index_elapsed");
self.handle_reclaims_maybe_cleanup(&reclaims);
start.stop();
handle_reclaims_elapsed = start.as_us();
let mut start = Measure::start("write_storage_elapsed");
let mut storage = self.storage.write().unwrap();
if let Some(slot_storage) = storage.0.get_mut(&slot) {
slot_storage.retain(|_key, store| store.count() > 0);
slot_storage.retain(|_key, store| {
if store.count() == 0 {
dead_storages.push(store.clone());
}
store.count() > 0
});
}
start.stop();
write_storage_elapsed = start.as_us();
}
rewrite_elapsed.stop();
let mut drop_storage_entries_elapsed = Measure::start("drop_storage_entries_elapsed");
drop(dead_storages);
drop_storage_entries_elapsed.stop();
datapoint_info!(
"do_shrink_slot_time",
("storage_read_elapsed", storage_read_elapsed.as_us(), i64),
("index_read_elapsed", index_read_elapsed.as_us(), i64),
("find_alive_elapsed", find_alive_elapsed, i64),
(
"create_and_insert_store_elapsed",
create_and_insert_store_elapsed,
i64
),
("store_accounts_elapsed", store_accounts_elapsed, i64),
("update_index_elapsed", update_index_elapsed, i64),
("handle_reclaims_elapsed", handle_reclaims_elapsed, i64),
("write_storage_elapsed", write_storage_elapsed, i64),
("rewrite_elapsed", rewrite_elapsed.as_us(), i64),
(
"drop_storage_entries_elapsed",
drop_storage_entries_elapsed.as_us(),
i64
),
);
alive_accounts.len()
}
@ -1255,10 +1317,57 @@ impl AccountsDB {
.filter(|slot| !accounts_index.is_root(**slot))
.collect();
drop(accounts_index);
let mut storage_lock_elapsed = Measure::start("storage_lock_elapsed");
let mut storage = self.storage.write().unwrap();
storage_lock_elapsed.stop();
let mut all_removed_slot_storages = vec![];
let mut total_removed_storage_entries = 0;
let mut total_removed_bytes = 0;
let mut remove_storages_elapsed = Measure::start("remove_storages_elapsed");
for slot in non_roots {
storage.0.remove(&slot);
if let Some(slot_removed_storages) = storage.0.remove(&slot) {
total_removed_storage_entries += slot_removed_storages.len();
total_removed_bytes += slot_removed_storages
.values()
.map(|i| i.accounts.capacity())
.sum::<u64>();
all_removed_slot_storages.push(slot_removed_storages);
}
}
remove_storages_elapsed.stop();
drop(storage);
let num_slots_removed = all_removed_slot_storages.len();
let mut drop_storage_entries_elapsed = Measure::start("drop_storage_entries_elapsed");
// Backing mmaps for removed storages entries explicitly dropped here outside
// of any locks
drop(all_removed_slot_storages);
drop_storage_entries_elapsed.stop();
datapoint_info!(
"purge_slots_time",
("storage_lock_elapsed", storage_lock_elapsed.as_us(), i64),
(
"remove_storages_elapsed",
remove_storages_elapsed.as_us(),
i64
),
(
"drop_storage_entries_elapsed",
drop_storage_entries_elapsed.as_us(),
i64
),
("num_slots_removed", num_slots_removed, i64),
(
"total_removed_storage_entries",
total_removed_storage_entries,
i64
),
("total_removed_bytes", total_removed_bytes, i64),
);
}
pub fn remove_unrooted_slot(&self, remove_slot: Slot) {