VirtualBox

Changeset 53458 in vbox for trunk


Ignore:
Timestamp:
Dec 5, 2014 12:56:32 PM (10 years ago)
Author:
vboxsync
Message:

SUPDrv: Must increase the host timer frequence before we determin the interval just like we do when starting it, otherwise we might end up with an uneven interval (in ticks) because the clock tick length changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r53444 r53458  
    39653965
    39663966/**
     3967 * Increase the timer freqency on hosts where this is possible (NT).
     3968 *
     3969 * The idea is that more interrupts is better for us... Also, it's better than
     3970 * we increase the timer frequence, because we might end up getting inaccuract
     3971 * callbacks if someone else does it.
     3972 *
     3973 * @param   pDevExt   Sets u32SystemTimerGranularityGrant if increased.
     3974 */
     3975static void supdrvGipRequestHigherTimerFrequencyFromSystem(PSUPDRVDEVEXT pDevExt)
     3976{
     3977    if (pDevExt->u32SystemTimerGranularityGrant == 0)
     3978    {
     3979        uint32_t u32SystemResolution;
     3980        if (   RT_SUCCESS_NP(RTTimerRequestSystemGranularity(  976563 /* 1024 HZ */, &u32SystemResolution))
     3981            || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 1000000 /* 1000 HZ */, &u32SystemResolution))
     3982            || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 1953125 /*  512 HZ */, &u32SystemResolution))
     3983            || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 2000000 /*  500 HZ */, &u32SystemResolution))
     3984           )
     3985        {
     3986            Assert(RTTimerGetSystemGranularity() <= u32SystemResolution);
     3987            pDevExt->u32SystemTimerGranularityGrant = u32SystemResolution;
     3988        }
     3989    }
     3990}
     3991
     3992
     3993/**
     3994 * Undoes supdrvGipRequestHigherTimerFrequencyFromSystem.
     3995 *
     3996 * @param   pDevExt     Clears u32SystemTimerGranularityGrant.
     3997 */
     3998static void supdrvGipReleaseHigherTimerFrequencyFromSystem(PSUPDRVDEVEXT pDevExt)
     3999{
     4000    if (pDevExt->u32SystemTimerGranularityGrant)
     4001    {
     4002        int rc2 = RTTimerReleaseSystemGranularity(pDevExt->u32SystemTimerGranularityGrant);
     4003        AssertRC(rc2);
     4004        pDevExt->u32SystemTimerGranularityGrant = 0;
     4005    }
     4006}
     4007
     4008
     4009/**
    39674010 * Maps the GIP into userspace and/or get the physical address of the GIP.
    39684011 *
     
    40284071                PSUPGLOBALINFOPAGE pGipR0 = pDevExt->pGip;
    40294072                uint64_t u64NanoTS;
    4030                 uint32_t u32SystemResolution;
    4031                 unsigned i;
    40324073
    40334074                LogFlow(("SUPR0GipMap: Resumes GIP updating\n"));
    40344075
    4035                 /*
    4036                  * Try bump up the system timer resolution.
    4037                  * The more interrupts the better...
    4038                  */
    4039                 /** @todo On Windows, RTTimerRequestSystemGranularity() always succeeds, so
    4040                  *        whats the point of the remaining calls? */
    4041                 if (   RT_SUCCESS_NP(RTTimerRequestSystemGranularity(  976563 /* 1024 HZ */, &u32SystemResolution))
    4042                     || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 1000000 /* 1000 HZ */, &u32SystemResolution))
    4043                     || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 1953125 /*  512 HZ */, &u32SystemResolution))
    4044                     || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 2000000 /*  500 HZ */, &u32SystemResolution))
    4045                    )
    4046                 {
    4047                     Assert(RTTimerGetSystemGranularity() <= u32SystemResolution);
    4048                     pDevExt->u32SystemTimerGranularityGrant = u32SystemResolution;
    4049                 }
     4076                supdrvGipRequestHigherTimerFrequencyFromSystem(pDevExt);
    40504077
    40514078                if (pGipR0->aCPUs[0].u32TransactionId != 2 /* not the first time */)
    40524079                {
     4080                    unsigned i;
    40534081                    for (i = 0; i < pGipR0->cCpus; i++)
    40544082                        ASMAtomicUoWriteU32(&pGipR0->aCPUs[i].u32TransactionId,
     
    41524180            rc = RTTimerStop(pDevExt->pGipTimer); AssertRC(rc); rc = VINF_SUCCESS;
    41534181#endif
    4154 
    4155             if (pDevExt->u32SystemTimerGranularityGrant)
    4156             {
    4157                 int rc2 = RTTimerReleaseSystemGranularity(pDevExt->u32SystemTimerGranularityGrant);
    4158                 AssertRC(rc2);
    4159                 pDevExt->u32SystemTimerGranularityGrant = 0;
    4160             }
     4182            supdrvGipReleaseHigherTimerFrequencyFromSystem(pDevExt);
    41614183        }
    41624184    }
     
    63056327     * Find a reasonable update interval and initialize the structure.
    63066328     */
     6329    supdrvGipRequestHigherTimerFrequencyFromSystem(pDevExt);
    63076330    /** @todo figure out why using a 100Ms interval upsets timekeeping in VMs.
    63086331     *        See @bugref{6710}. */
     
    63906413                             */
    63916414                            Log(("supdrvGipCreate: %u ns interval.\n", u32Interval));
     6415                            supdrvGipReleaseHigherTimerFrequencyFromSystem(pDevExt);
     6416
    63926417                            g_pSUPGlobalInfoPage = pGip;
    63936418                            if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC)
     
    64166441        OSDBGPRINT(("supdrvGipCreate: supdrvTscDeltaInit failed. rc=%Rrc\n", rc));
    64176442
    6418     supdrvGipDestroy(pDevExt);
     6443    supdrvGipDestroy(pDevExt); /* Releases timer frequency increase too. */
    64196444    return rc;
    64206445}
     
    64856510     * if one actually succeeded and is still pending.
    64866511     */
    6487     if (pDevExt->u32SystemTimerGranularityGrant)
    6488     {
    6489         rc = RTTimerReleaseSystemGranularity(pDevExt->u32SystemTimerGranularityGrant); AssertRC(rc);
    6490         pDevExt->u32SystemTimerGranularityGrant = 0;
    6491     }
     6512    supdrvGipReleaseHigherTimerFrequencyFromSystem(pDevExt);
    64926513}
    64936514
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette