Skip to content

Commit 3fc7d1c

Browse files
Adam Fordslp
authored andcommitted
Fix fence completion race in virtio-gpu worker
When fences complete out of order (e.g., an immediate-retire for fence N+1 arrives before the timeline signal for fence N), the unconditional insert() would overwrite the higher fence_id with the lower one. This causes fence N+1 to appear incomplete forever, hanging the guest. Use entry().or_insert() with a max check so only strictly higher fence_ids update the completed_fences map. Signed-off-by: Adam Ford <adam.ford@anodize.com>
1 parent c58f00a commit 3fc7d1c

1 file changed

Lines changed: 7 additions & 4 deletions

File tree

src/devices/src/virtio/gpu/virtio_gpu.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,13 @@ impl VirtioGpu {
203203
i += 1;
204204
}
205205
}
206-
// Update the last completed fence for this context
207-
fence_state
208-
.completed_fences
209-
.insert(ring, completed_fence.fence_id);
206+
// Update the last completed fence for this context.
207+
// Use max() to avoid a race where an out-of-order completion
208+
// (e.g., immediate-retire for fence N+1 followed by timeline
209+
// signal for fence N) would overwrite a higher fence_id with
210+
// a lower one, causing fence N+1 to be stuck forever.
211+
let entry = fence_state.completed_fences.entry(ring).or_insert(0);
212+
*entry = (*entry).max(completed_fence.fence_id);
210213
})
211214
}
212215

0 commit comments

Comments
 (0)