Skip to content

Commit b862bb1

Browse files
author
Adam Ford
committed
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 3d1c444 commit b862bb1

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,15 @@ 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+
if completed_fence.fence_id > *entry {
213+
*entry = completed_fence.fence_id;
214+
}
210215
})
211216
}
212217

0 commit comments

Comments
 (0)