vmtime time-source task spins forever on a timeout half the ring past the start time
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 85/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- rust
- Área
- operating-systems
Línea de trabajo
The bug is in vm/vmcore/src/vmtime.rs in TimerState::poll and timestamp(). Add the attached test to vm/vmcore/tests/ and run cargo test -p vmcore --test vmtime_half_ring_spin to reproduce the spin. Read VmTime::is_before doc and the suggested fix: measure future times from now, clamp to one day, and parameterize timestamp() with now_os. Done when the spin test passes and cargo test -p vmcore --lib is green.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
TimerState::poll busy-loops forever, at 100% CPU and without ever yielding, when a VmTimeAccess timeout is circularly after the current VM time but circularly before the keeper's last start time. From then on no VM-time timeout fires, and stop() and save() on the keeper hang.
Repro
Add the attached vmtime_half_ring_spin.rs (.txt) to vm/vmcore/tests/ and run:
cargo test -p vmcore --test vmtime_half_ring_spin
- Create a keeper at VM time 0, build a source, and call
start(). - Let at least 100ns of VM time pass.
- Call
set_timeout_if_before(VmTime::from_100ns(1 << 63))and poll once. - Call
keeper.stop().await.
The control test runs the same sequence with T = 1e9 and passes.
Expected
T is ~29,000 years ahead, so the timer sleeps and stop() completes.
Actual
thread 'timeout_half_ring_after_start_does_not_spin' panicked at vm/vmcore/tests/vmtime_half_ring_spin.rs:53:10:
vmtime source task did not yield within 10s (TimerState::poll spins): Timeout
The spinning thread used 9.99s of CPU in 10s of wall time:
pal_async::sys::epoll::...::set_deadline support/pal/pal_async/src/unix/epoll.rs:517
vmcore::vmtime::TimerState::set_next vm/vmcore/src/vmtime.rs:239
vmcore::vmtime::TimerState::wake vm/vmcore/src/vmtime.rs:260
vmcore::vmtime::TimerState::poll vm/vmcore/src/vmtime.rs:330
vmcore::vmtime::...::run::{async_fn} vm/vmcore/src/vmtime.rs:724
Root cause
VmTime comparisons are circular and therefore not transitive, as the doc comment on is_before notes. The two halves of the timer logic use different reference points. With start = 0, now = d > 0 and T = 2^63:
wake()compares T with now.T - now = 2^63 - d > 0, so T is still pending andset_next(T)is called.timestamp()measures T from start.T.checked_sub(start)returnsNone(2^63isi64::MIN), so the deadline becomes the host time of the last start, which is in the past.- The host timer is ready immediately,
wake()re-arms the same past deadline, andpollloops forever.
Any T in start + [2^63, 2^63 + d) triggers this, so the window grows with uptime.
Impact
- The keeper task hangs, so no VM-time timeout in the VM fires again.
- Possible guest path (a lead, not verified end to end): OpenHCL's
VmTimeGuestTimer::timeout(openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs:3354) derives the timeout from the guest's synthetic-timer deadline. A guest that programs a deadline ~29,000 years ahead may reach this; I haven't checked how that value is validated. VmTimeAccess::host_time()also goes throughtimestamp(). The OpenHCL VP loop (openhcl/virt_mshv_vtl/src/processor/mod.rs:813) uses its result as a deadline andcontinues when that deadline is ready, so from reading the code it may busy-loop as well.- Restoring a saved state that has an armed timeout reaches the same code.
Suggested fix
Measure future times from now, the reference wake() uses. Clamp the distance to one day, like poll's default deadline, because a circular distance can exceed what the host clock can represent. Times that are not after now keep today's behavior. timestamp() takes now_os as a parameter so that the unit test can use synthetic host times.
Verification
- The spin test hangs on 76edd46e2 and passes with the patch. The control test passes on both.
cargo test -p vmcore --lib(30 tests, including the newtest_timestamp) passes, and so does the regression test for the "duration too large" panic.- rustfmt and
clippy -D warningsare clean. - Replay of all 53
vmtime_v2_*timeout inputs:
| build | pass | timeout | other |
|---|---|---|---|
| 76edd46e2 | 0 | 48 | 5 ("duration too large" panic) |
76edd46e2 + since.min(86400s) |
1 | 52 | 0 |
| 76edd46e2 + this patch | 53 | 0 | 0 |
Alternative
Bound how far ahead set_timeout* may be set, for example by treating more than 2^62 units ahead as "never". That narrows the API rather than fixing the conversion.
- Lenguaje dominante
- Rust
- Estrellas
- 758
- Forks
- 48
- Merge medio
- 17 h 40 min
- PR fusionados (30 d)
- 444
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de microsoft/nvx
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
microsoft/nvx#1172 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
microsoft/nvx#1151 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
microsoft/nvx#1147 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de microsoft/nvx
Issues similares
-
A-linter
Dificultad 2/5 1-3 horas Aptitud para principiantes 73/100
oxc-project/oxc#28783 ·
Los mantenedores suelen responder en 1 día
-
Substrait consumer doesn't recognise `shift_left` / `shift_right` from functions_arithmetic.yamlAbiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
apache/datafusion#27059 ·
Los mantenedores suelen responder en 1 día
-
Bump calamine to 0.38: RUSTSEC-2026-0436 (CFB/OLE2 panic and unbounded allocation) fails cargo auditAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
docling-project/docling.rs#979 ·
Los mantenedores suelen responder en 1 día
-
llm translation
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
Los mantenedores suelen responder en 1 día