Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 41ca59e

Browse files
Move dropping AppendVecs outside lock (#12408) (#12429)
* Move drop outside lock Co-authored-by: Carl Lin <carl@solana.com> (cherry picked from commit 55be8d4) Co-authored-by: carllin <wumu727@gmail.com>
1 parent a76e175 commit 41ca59e

File tree

1 file changed

+113
-4
lines changed

1 file changed

+113
-4
lines changed

runtime/src/accounts_db.rs

Lines changed: 113 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -856,9 +856,10 @@ impl AccountsDB {
856856
trace!("shrink_stale_slot: slot: {}", slot);
857857

858858
let mut stored_accounts = vec![];
859+
let mut storage_read_elapsed = Measure::start("storage_read_elapsed");
859860
{
860-
let storage = self.storage.read().unwrap();
861-
if let Some(stores) = storage.0.get(&slot) {
861+
let slot_storages = self.storage.read().unwrap().0.get(&slot).cloned();
862+
if let Some(stores) = slot_storages {
862863
let mut alive_count = 0;
863864
let mut stored_count = 0;
864865
for store in stores.values() {
@@ -897,7 +898,9 @@ impl AccountsDB {
897898
}
898899
}
899900
}
901+
storage_read_elapsed.stop();
900902

903+
let mut index_read_elapsed = Measure::start("index_read_elapsed");
901904
let alive_accounts: Vec<_> = {
902905
let accounts_index = self.accounts_index.read().unwrap();
903906
stored_accounts
@@ -921,6 +924,7 @@ impl AccountsDB {
921924
)
922925
.collect()
923926
};
927+
index_read_elapsed.stop();
924928

925929
let alive_total: u64 = alive_accounts
926930
.iter()
@@ -941,7 +945,16 @@ impl AccountsDB {
941945
aligned_total
942946
);
943947

948+
let mut rewrite_elapsed = Measure::start("rewrite_elapsed");
949+
let mut dead_storages = vec![];
950+
let mut find_alive_elapsed = 0;
951+
let mut create_and_insert_store_elapsed = 0;
952+
let mut store_accounts_elapsed = 0;
953+
let mut update_index_elapsed = 0;
954+
let mut handle_reclaims_elapsed = 0;
955+
let mut write_storage_elapsed = 0;
944956
if aligned_total > 0 {
957+
let mut start = Measure::start("find_alive_elapsed");
945958
let mut accounts = Vec::with_capacity(alive_accounts.len());
946959
let mut hashes = Vec::with_capacity(alive_accounts.len());
947960
let mut write_versions = Vec::with_capacity(alive_accounts.len());
@@ -952,29 +965,78 @@ impl AccountsDB {
952965
hashes.push(*account_hash);
953966
write_versions.push(*write_version);
954967
}
968+
start.stop();
969+
find_alive_elapsed = start.as_us();
955970

971+
let mut start = Measure::start("create_and_insert_store_elapsed");
956972
let shrunken_store = self.create_and_insert_store(slot, aligned_total);
973+
start.stop();
974+
create_and_insert_store_elapsed = start.as_us();
957975

958976
// here, we're writing back alive_accounts. That should be an atomic operation
959977
// without use of rather wide locks in this whole function, because we're
960978
// mutating rooted slots; There should be no writers to them.
979+
let mut start = Measure::start("store_accounts_elapsed");
961980
let infos = self.store_accounts_to(
962981
slot,
963982
&accounts,
964983
&hashes,
965984
|_| shrunken_store.clone(),
966985
write_versions.into_iter(),
967986
);
987+
start.stop();
988+
store_accounts_elapsed = start.as_us();
989+
990+
let mut start = Measure::start("update_index_elapsed");
968991
let reclaims = self.update_index(slot, infos, &accounts);
992+
start.stop();
993+
update_index_elapsed = start.as_us();
969994

995+
let mut start = Measure::start("update_index_elapsed");
970996
self.handle_reclaims_maybe_cleanup(&reclaims);
997+
start.stop();
998+
handle_reclaims_elapsed = start.as_us();
971999

1000+
let mut start = Measure::start("write_storage_elapsed");
9721001
let mut storage = self.storage.write().unwrap();
9731002
if let Some(slot_storage) = storage.0.get_mut(&slot) {
974-
slot_storage.retain(|_key, store| store.count() > 0);
1003+
slot_storage.retain(|_key, store| {
1004+
if store.count() == 0 {
1005+
dead_storages.push(store.clone());
1006+
}
1007+
store.count() > 0
1008+
});
9751009
}
1010+
start.stop();
1011+
write_storage_elapsed = start.as_us();
9761012
}
1013+
rewrite_elapsed.stop();
9771014

1015+
let mut drop_storage_entries_elapsed = Measure::start("drop_storage_entries_elapsed");
1016+
drop(dead_storages);
1017+
drop_storage_entries_elapsed.stop();
1018+
1019+
datapoint_info!(
1020+
"do_shrink_slot_time",
1021+
("storage_read_elapsed", storage_read_elapsed.as_us(), i64),
1022+
("index_read_elapsed", index_read_elapsed.as_us(), i64),
1023+
("find_alive_elapsed", find_alive_elapsed, i64),
1024+
(
1025+
"create_and_insert_store_elapsed",
1026+
create_and_insert_store_elapsed,
1027+
i64
1028+
),
1029+
("store_accounts_elapsed", store_accounts_elapsed, i64),
1030+
("update_index_elapsed", update_index_elapsed, i64),
1031+
("handle_reclaims_elapsed", handle_reclaims_elapsed, i64),
1032+
("write_storage_elapsed", write_storage_elapsed, i64),
1033+
("rewrite_elapsed", rewrite_elapsed.as_us(), i64),
1034+
(
1035+
"drop_storage_entries_elapsed",
1036+
drop_storage_entries_elapsed.as_us(),
1037+
i64
1038+
),
1039+
);
9781040
alive_accounts.len()
9791041
}
9801042

@@ -1255,10 +1317,57 @@ impl AccountsDB {
12551317
.filter(|slot| !accounts_index.is_root(**slot))
12561318
.collect();
12571319
drop(accounts_index);
1320+
let mut storage_lock_elapsed = Measure::start("storage_lock_elapsed");
12581321
let mut storage = self.storage.write().unwrap();
1322+
storage_lock_elapsed.stop();
1323+
1324+
let mut all_removed_slot_storages = vec![];
1325+
let mut total_removed_storage_entries = 0;
1326+
let mut total_removed_bytes = 0;
1327+
1328+
let mut remove_storages_elapsed = Measure::start("remove_storages_elapsed");
12591329
for slot in non_roots {
1260-
storage.0.remove(&slot);
1330+
if let Some(slot_removed_storages) = storage.0.remove(&slot) {
1331+
total_removed_storage_entries += slot_removed_storages.len();
1332+
total_removed_bytes += slot_removed_storages
1333+
.values()
1334+
.map(|i| i.accounts.capacity())
1335+
.sum::<u64>();
1336+
all_removed_slot_storages.push(slot_removed_storages);
1337+
}
12611338
}
1339+
remove_storages_elapsed.stop();
1340+
drop(storage);
1341+
1342+
let num_slots_removed = all_removed_slot_storages.len();
1343+
1344+
let mut drop_storage_entries_elapsed = Measure::start("drop_storage_entries_elapsed");
1345+
// Backing mmaps for removed storages entries explicitly dropped here outside
1346+
// of any locks
1347+
drop(all_removed_slot_storages);
1348+
drop_storage_entries_elapsed.stop();
1349+
1350+
datapoint_info!(
1351+
"purge_slots_time",
1352+
("storage_lock_elapsed", storage_lock_elapsed.as_us(), i64),
1353+
(
1354+
"remove_storages_elapsed",
1355+
remove_storages_elapsed.as_us(),
1356+
i64
1357+
),
1358+
(
1359+
"drop_storage_entries_elapsed",
1360+
drop_storage_entries_elapsed.as_us(),
1361+
i64
1362+
),
1363+
("num_slots_removed", num_slots_removed, i64),
1364+
(
1365+
"total_removed_storage_entries",
1366+
total_removed_storage_entries,
1367+
i64
1368+
),
1369+
("total_removed_bytes", total_removed_bytes, i64),
1370+
);
12621371
}
12631372

12641373
pub fn remove_unrooted_slot(&self, remove_slot: Slot) {

0 commit comments

Comments
 (0)