virtualbox6: adapt watchdog timer interval dynamically

Issue #4381
This commit is contained in:
Christian Prochaska 2022-01-17 09:23:25 +01:00 committed by Christian Helmuth
parent 95d9c15607
commit d3adadf4cf
4 changed files with 82 additions and 1 deletions

View File

@ -1 +1 @@
4520096005074d88433410752e88df1e748a80dd
7991a9853bb0a96cad9a54ebaf3290dfda9ae2d2

View File

@ -14,9 +14,11 @@
/* VirtualBox includes */
#include <VBox/vmm/cpum.h> /* must be included before CPUMInternal.h */
#include <VBox/vmm/tm.h> /* must be included before TMInternal.h */
#define VMCPU_INCL_CPUM_GST_CTX /* needed for cpum.GstCtx */
#include <CPUMInternal.h> /* enable access to cpum.s.* */
#include <HMInternal.h> /* enable access to hm.s.* */
#include <TMInternal.h> /* enable access to tm.s.* */
#define RT_OS_WINDOWS /* needed for definition all nem.s members */
#include <NEMInternal.h> /* enable access to nem.s.* */
#undef RT_OS_WINDOWS
@ -253,6 +255,30 @@ VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu)
{
using namespace Sup;
/*
* Program the watchdog timer near the next expiring virtual sync timeout.
* Without this code the watchdog timer would be programmed to a fixed
* interval (10ms by default), which could be too high or cause too much
* CPU load if set lower. Other hosts use the VMX preemption timer, which
* is currently not available on Genode.
*/
{
static ::uint64_t current_interval_ns { 0 };
static Mutex interval_mutex { };
Mutex::Guard guard(interval_mutex);
::uint64_t new_interval_ns = TMVirtualSyncGetNsToDeadline(pVM);
new_interval_ns = (new_interval_ns / RT_NS_1MS) * RT_NS_1MS;
new_interval_ns = max(new_interval_ns, 1 * RT_NS_1MS);
new_interval_ns = min(new_interval_ns, 10 * RT_NS_1MS);
if (new_interval_ns != current_interval_ns) {
RTTimerChangeInterval(pVM->tm.s.pTimer, new_interval_ns);
current_interval_ns = new_interval_ns;
}
}
Vm &vm = *static_cast<Vm *>(pVM);
/* commit on VM entry */

View File

@ -0,0 +1,54 @@
Implement RTTimerChangeInterval()
diff --git a/src/virtualbox6/src/VBox/Runtime/generic/timer-generic.cpp b/src/virtualbox6/src/VBox/Runtime/generic/timer-generic.cpp
index 6857bfb..7a32560 100644
--- a/src/virtualbox6/src/VBox/Runtime/generic/timer-generic.cpp
+++ b/src/virtualbox6/src/VBox/Runtime/generic/timer-generic.cpp
@@ -223,10 +223,45 @@ RT_EXPORT_SYMBOL(RTTimerStop);
RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval)
{
+ /* implementation ported from timerlr-generic.cpp for Genode */
+
if (!rtTimerIsValid(pTimer))
return VERR_INVALID_HANDLE;
- NOREF(u64NanoInterval);
- return VERR_NOT_SUPPORTED;
+
+ PRTTIMER pThis = pTimer;
+
+ /*
+ * Do the job accoring to state and caller.
+ */
+ int rc;
+ if (pThis->fSuspended)
+ {
+ /* Stopped: Just update the interval. */
+ ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval);
+ rc = VINF_SUCCESS;
+ }
+ else if (RTThreadSelf() == pThis->Thread)
+ {
+ /* Running: Updating interval from the callback. */
+ uint64_t u64Now = RTTimeNanoTS();
+ pThis->iTick = 0;
+ pThis->u64StartTS = u64Now;
+ pThis->u64NextTS = u64Now;
+ ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval);
+ rc = VINF_SUCCESS;
+ }
+ else
+ {
+ /* Running: Stopping */
+ rc = RTTimerStop(pThis);
+ if (RT_SUCCESS(rc))
+ {
+ ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval);
+ rc = RTTimerStart(pThis, 0);
+ }
+ }
+
+ return rc;
}
RT_EXPORT_SYMBOL(RTTimerChangeInterval);

View File

@ -7,3 +7,4 @@ devahci.patch
smp_sipi.patch
tm_poke.patch
exec_state.patch
rttimer.patch