[vbox-dev] fUpdateStuff flag never set in trunk/src/VBox/VMM/TM.cpp ?

Mark Cranness mark.cranness at gmail.com
Thu Dec 10 02:56:49 GMT 2009

2009/12/8 Knut St. Osmundsen <bird at sun.com>:
> And there are known issues with the catch-up not working correctly on
> certain setups.  We're looking into the latter and there should
> eventually be fixed once we have it figured out...

I've done some more testing and code examination, which I hope may be useful.

For the testing I've done, I note the following (all with GA disabled
in the VM - no timesync):
('catchup works' below means: No given up messages, and clock tracks
in line with host @~100%.)

- If I have two VMs running at the same time (the original Windows
2000 and a clone of the same), then catchup works: The clock is

- If the (single) VM is busy, catchup works (it will even
double/triple time the timers and run the VM faster than normal to
catchup the current 60 second lag, and correct the clock - except for
the given-up lag of course).

- If I set the Windows 2000 VM to use the ACPI Multiprocessor PC HAL,
catchup works (but I get very high host CPU usage).
(The catchup only fails when using either of the two uniprocessor HALs.)

- If I have a single (or multiple) Windows XP BartPE (UBCD4WIN) VM
running, catchup works.
(IO APIC doesn't matter; I'm not sure what HAL this uses.)

- If I have the Windows 2000 VM running and also a separate XP VM,
catchup works in both VMs.

- In summary, the VM only goes slow (2/3 speed) and has 'Catchup given
up' messages when a single Windows 2000 VM is running with a
uniprocessor HAL when it is idle.

For the code examination I've done, I note the following:
(Please excuse me if I misunderstand any of the code: that is
certainly possible.)
(These comments based on the 3.0.10 stable codeline.)

- There are only two functions that calculate and catchup amount, AND
store that catchup back into the timers to actually fix the catchup.
(The calculation is done in a few more places, but only for internal
use and is not actually "caught up" by updating a new value for

These are:
1) TM.cpp>tmR3TimerQueueRunVirtualSync (line 1908)
2) TMAllVirtual.cpp > tmVirtualSyncGetHandleCatchUpLocked (line 403)

Because of the fUpdateStuff bug, TM.cpp>tmR3TimerQueueRunVirtualSync
did not actually fix and store the catchup.

Combining the tests and the code examination, seems to indicate this:

- In many situations, TMAllVirtual.cpp >
tmVirtualSyncGetHandleCatchUpLocked is periodically run, which
performs timer catchup and clocks keep in sync.

- When the host is running only a single VM that has only a single CPU
and the guest is idle, TMAllVirtual.cpp >
tmVirtualSyncGetHandleCatchUpLocked IS NOT periodically called, and no
timer catchup occurs.

Is it intended that TMAllVirtual.cpp >
tmVirtualSyncGetHandleCatchUpLocked should NOT run when there is only
1 CPU and that CPU is idle (halted)?
If it should be running, then that is the (a) problem.

If it not supposed to periodically run with a single idle (halted)
CPU, and instead TM.cpp>tmR3TimerQueueRunVirtualSync runs instead (or
TM.cpp>tmR3TimerQueueRunVirtualSync is supposed to run all the time
anyway), then the fUpdateStuff bug is the (a) problem.

- Questions about the 2/3 rate:

+ Is the design actually that the timer in a guest should run at 2/3
(66.7%) the speed of the host, and that the catchup speeds it back up
to 100%?
+ I suppose that design would / might handle host CPUs that had a
varying TSC rate?
+ What is the explanation for the 2/3 rate?


More information about the vbox-dev mailing list