Skip to content

Commit 8f23d8c

Browse files
committed
fix: force a sync on drop subtree for safety
1 parent 5919a72 commit 8f23d8c

File tree

2 files changed

+11
-14
lines changed

2 files changed

+11
-14
lines changed

crates/vm/src/system/cuda/memory.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,12 @@ impl MemoryInventoryGPU {
203203
}
204204
mem.tracing_info("merkle update");
205205
persistent.merkle_tree.finalize();
206-
Some(persistent.merkle_tree.update_with_touched_blocks(
206+
let merkle_tree_ctx = persistent.merkle_tree.update_with_touched_blocks(
207207
unpadded_merkle_height,
208208
&d_touched_memory,
209209
empty,
210-
))
210+
);
211+
Some(merkle_tree_ctx)
211212
}
212213
TouchedMemory::Volatile(partition) => {
213214
assert!(self.persistent.is_none(), "TouchedMemory enum mismatch");

crates/vm/src/system/cuda/merkle_tree/mod.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -311,24 +311,20 @@ impl MemoryMerkleTree {
311311

312312
/// Drops all massive buffers to free memory. Used at the end of an execution segment.
313313
///
314-
/// Caution: this method destroys all subtree streams and events. If events have not been
315-
/// manually removed after completion, they are enqueued to the default stream and then a forced
316-
/// synchronization is performed on the default stream. The forced synchronization is avoided if
317-
/// all events are manually removed when they are known to be completed (e.g., after some other
318-
/// synchronization like D2H transfer).
314+
/// Caution: this method destroys all subtree streams and events. For safety, we force
315+
/// synchronize all subtree streams and the default stream (cudaStreamPerThread) with host
316+
/// before deallocating buffers.
319317
pub fn drop_subtrees(&mut self) {
320-
let mut needs_sync = false;
321318
// Make sure all streams are synchronized before destroying events
322319
for subtree in self.subtrees.iter() {
323320
subtree.stream.synchronize().unwrap();
324-
if let Some(event) = subtree.build_completion_event.as_ref() {
325-
needs_sync = true;
326-
default_stream_wait(event).unwrap();
321+
if let Some(_event) = subtree.build_completion_event.as_ref() {
322+
tracing::warn!(
323+
"Dropping merkle subtree before build_async event has been destroyed"
324+
);
327325
}
328326
}
329-
if needs_sync {
330-
current_stream_sync().unwrap();
331-
}
327+
current_stream_sync().unwrap();
332328
// Clearing will drop streams (which calls synchronize again) and drops events (which
333329
// destroys them)
334330
self.subtrees.clear();

0 commit comments

Comments
 (0)