VirtualBox

Changeset 53396 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 25, 2014 3:01:59 PM (10 years ago)
Author:
vboxsync
Message:

HostDrivers/Support: Don't try measuring TSC deltas on OSes that normalizes TSC-deltas themselves, currently only Windows.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
8 edited

Legend:

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

    r53369 r53396  
    206206static volatile uint32_t    g_cMpOnOffEvents;
    207207/** TSC reading during start of TSC frequency refinement phase. */
    208 uint64_t                    g_u64TSCAnchor;
     208static uint64_t             g_u64TSCAnchor;
    209209/** Timestamp (in nanosec) during start of TSC frequency refinement phase. */
    210 uint64_t                    g_u64NanoTSAnchor;
     210static uint64_t             g_u64NanoTSAnchor;
     211/** Whether the host OS has already normalized the hardware TSC deltas across
     212 *  CPUs. */
     213static bool                 g_fOsTscDeltasInSync;
    211214
    212215/**
     
    58555858static int supdrvTscDeltaInit(PSUPDRVDEVEXT pDevExt)
    58565859{
     5860    Assert(!g_fOsTscDeltasInSync);
    58575861    int rc = RTSpinlockCreate(&pDevExt->hTscDeltaSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "VBoxTscSpnLck");
    58585862    if (RT_SUCCESS(rc))
     
    60676071    cCpus = RTMpGetArraySize();
    60686072    if (   cCpus > RTCPUSET_MAX_CPUS
    6069         || cCpus > 256 /*ApicId is used for the mappings*/)
     6073        || cCpus > 256 /* ApicId is used for the mappings */)
    60706074    {
    60716075        SUPR0Printf("VBoxDrv: Too many CPUs (%u) for the GIP (max %u)\n", cCpus, RT_MIN(RTCPUSET_MAX_CPUS, 256));
     
    60996103    supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), RT_NS_1SEC / u32Interval /*=Hz*/, u32Interval, cCpus);
    61006104
     6105    if (RT_UNLIKELY(   g_fOsTscDeltasInSync
     6106                    && pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
     6107                    && !supdrvOSGetForcedAsyncTscMode(pDevExt)))
     6108    {
     6109        OSDBGPRINT(("supdrvGipCreate: The TSC-deltas should be normalized by the host OS, but verifying shows it's not!\n"));
     6110        return VERR_INTERNAL_ERROR_2;
     6111    }
     6112
    61016113#ifdef SUPDRV_USE_TSC_DELTA_THREAD
    6102     /* Initialize TSC-delta measurement thread before executing any Mp event callbacks. */
    6103     rc = supdrvTscDeltaInit(pDevExt);
     6114    if (!g_fOsTscDeltasInSync)
     6115    {
     6116        /* Initialize TSC-delta measurement thread before executing any Mp event callbacks. */
     6117        rc = supdrvTscDeltaInit(pDevExt);
     6118    }
    61046119#endif
    61056120    if (RT_SUCCESS(rc))
     
    61126127            {
    61136128#ifndef SUPDRV_USE_TSC_DELTA_THREAD
    6114                 /*
    6115                  * Measure the TSC deltas now that we have MP notifications.
    6116                  */
    6117                 int      cTries = 5;
    61186129                uint16_t iCpu;
    6119                 do
     6130                if (!g_fOsTscDeltasInSync)
    61206131                {
    6121                     rc = supdrvMeasureTscDeltas(pDevExt, NULL /* pidxMaster */);
    6122                     if (rc != VERR_TRY_AGAIN)
    6123                         break;
    6124                 } while (--cTries > 0);
    6125                 for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
    6126                     Log(("supdrvTscDeltaInit: cpu[%u] delta %lld\n", iCpu, pGip->aCPUs[iCpu].i64TSCDelta));
     6132                    /*
     6133                     * Measure the TSC deltas now that we have MP notifications.
     6134                     */
     6135                    int cTries = 5;
     6136                    do
     6137                    {
     6138                        rc = supdrvMeasureTscDeltas(pDevExt, NULL /* pidxMaster */);
     6139                        if (rc != VERR_TRY_AGAIN)
     6140                            break;
     6141                    } while (--cTries > 0);
     6142                    for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
     6143                        Log(("supdrvTscDeltaInit: cpu[%u] delta %lld\n", iCpu, pGip->aCPUs[iCpu].i64TSCDelta));
     6144                }
     6145                else
     6146                {
     6147                    for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
     6148                        Assert(!pGip->aCPUs[iCpu].i64TSCDelta);
     6149                }
    61276150#endif
    6128 
    6129                 rc = supdrvGipMeasureTscFreq(pGip);
    61306151                if (RT_SUCCESS(rc))
    61316152                {
    6132                     if (supdrvIsInvariantTsc())
     6153                    rc = supdrvGipMeasureTscFreq(pGip);
     6154                    if (RT_SUCCESS(rc))
    61336155                    {
    6134                         for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
    6135                             pGip->aCPUs[iCpu].u64CpuHz = pGip->u64CpuHz;
    6136                     }
    6137 
    6138                     /*
    6139                      * Create the timer.
    6140                      * If CPU_ALL isn't supported we'll have to fall back to synchronous mode.
    6141                      */
    6142                     if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)
    6143                     {
    6144                         rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, RTTIMER_FLAGS_CPU_ALL, supdrvGipAsyncTimer, pDevExt);
    6145                         if (rc == VERR_NOT_SUPPORTED)
     6156                        if (supdrvIsInvariantTsc())
     6157                            pGip->aCPUs[0].u64CpuHz = pGip->u64CpuHz;
     6158
     6159                        /*
     6160                         * Create the timer.
     6161                         * If CPU_ALL isn't supported we'll have to fall back to synchronous mode.
     6162                         */
     6163                        if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)
    61466164                        {
    6147                             OSDBGPRINT(("supdrvGipCreate: omni timer not supported, falling back to synchronous mode\n"));
    6148                             pGip->u32Mode = SUPGIPMODE_SYNC_TSC;
     6165                            rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, RTTIMER_FLAGS_CPU_ALL, supdrvGipAsyncTimer,
     6166                                                 pDevExt);
     6167                            if (rc == VERR_NOT_SUPPORTED)
     6168                            {
     6169                                OSDBGPRINT(("supdrvGipCreate: omni timer not supported, falling back to synchronous mode\n"));
     6170                                pGip->u32Mode = SUPGIPMODE_SYNC_TSC;
     6171                            }
     6172                        }
     6173                        if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)
     6174                            rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, 0 /* fFlags */, supdrvGipSyncTimer, pDevExt);
     6175                        if (RT_SUCCESS(rc))
     6176                        {
     6177                            /*
     6178                             * We're good.
     6179                             */
     6180                            Log(("supdrvGipCreate: %u ns interval.\n", u32Interval));
     6181                            g_pSUPGlobalInfoPage = pGip;
     6182                            return VINF_SUCCESS;
     6183                        }
     6184                        else
     6185                        {
     6186                            OSDBGPRINT(("supdrvGipCreate: RTTimerCreateEx failed (%u ns interval). rc=%Rrc\n", u32Interval, rc));
     6187                            Assert(!pDevExt->pGipTimer);
    61496188                        }
    61506189                    }
    6151                     if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)
    6152                         rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, 0 /* fFlags */, supdrvGipSyncTimer, pDevExt);
    6153                     if (RT_SUCCESS(rc))
    6154                     {
    6155                         /*
    6156                          * We're good.
    6157                          */
    6158                         Log(("supdrvGipCreate: %u ns interval.\n", u32Interval));
    6159                         g_pSUPGlobalInfoPage = pGip;
    6160                         return VINF_SUCCESS;
    6161                     }
    61626190                    else
    6163                     {
    6164                         OSDBGPRINT(("supdrvGipCreate: failed create GIP timer at %u ns interval. rc=%Rrc\n", u32Interval, rc));
    6165                         Assert(!pDevExt->pGipTimer);
    6166                     }
     6191                        OSDBGPRINT(("supdrvGipCreate: supdrvGipMeasureTscFreq failed. rc=%Rrc\n", rc));
    61676192                }
     6193                else
     6194                    OSDBGPRINT(("supdrvGipCreate: supdrvMeasureTscDeltas failed. rc=%Rrc\n", rc));
    61686195            }
    61696196            else
     
    63336360                    pGip->u64CpuHz = (u64TSC - g_u64TSCAnchor) / (u64DeltaNanoTS / RT_NS_1SEC);
    63346361
    6335                 for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
    6336                     pGip->aCPUs[iCpu].u64CpuHz = pGip->u64CpuHz;
     6362                pGip->aCPUs[0].u64CpuHz = pGip->u64CpuHz;
    63376363                g_u64TSCAnchor = 0;
    63386364            }
     
    64656491     * update the state and it'll get serviced when the thread's listening interval times out.
    64666492     */
    6467     if (supdrvIsInvariantTsc())
     6493    if (   !g_fOsTscDeltasInSync
     6494        && supdrvIsInvariantTsc())
    64686495    {
    64696496        RTCpuSetAdd(&pDevExt->TscDeltaCpuSet, idCpu);
     
    65236550    }
    65246551
    6525     /* Reset the TSC delta, we will recalculate it lazily. */
    6526     ASMAtomicWriteS64(&pGip->aCPUs[i].i64TSCDelta, INT64_MAX);
     6552    /* Reset the TSC delta (if required), we will recalculate it lazily. */
     6553    if (!g_fOsTscDeltasInSync)
     6554        ASMAtomicWriteS64(&pGip->aCPUs[i].i64TSCDelta, INT64_MAX);
    65276555
    65286556    /* commit it */
     
    67066734    if (!RTMpOnAllIsConcurrentSafe())
    67076735    {
     6736        /** @todo This was introduced for Windows, but since Windows doesn't use this
     6737         *        code path any longer (as DPC timeouts BSOD regardless of interrupts,
     6738         *        see @bugref{6710} comment 81), eventually phase it out. */
    67086739        uint64_t       uTscNow;
    67096740        uint64_t       uTscStart;
     
    68966927    AssertReturn(pDevExt, VERR_INVALID_PARAMETER);
    68976928    AssertReturn(pDevExt->pGip, VERR_INVALID_PARAMETER);
     6929    Assert(!g_fOsTscDeltasInSync);
    68986930
    68996931    pGip          = pDevExt->pGip;
     
    69606992    uint32_t   cOnlineCpus    = pGip->cOnlineCpus;
    69616993
     6994    Assert(!g_fOsTscDeltasInSync);
     6995
    69626996    /*
    69636997     * If we determined the TSC is async., don't bother with measuring deltas.
     
    70567090 * case we have to choose the asynchronous timer mode.
    70577091 *
    7058  * @param   poffMin     Pointer to the determined difference between different cores.
     7092 * @param   poffMin     Pointer to the determined difference between different
     7093 *                      cores (optional, can be NULL).
    70597094 * @return  false if the time stamp counters appear to be synchronized, true otherwise.
    70607095 */
     
    71167151    }
    71177152
    7118     *poffMin = offMin; /* Almost RTMpOnSpecific profiling. */
     7153    if (poffMin)
     7154        *poffMin = offMin; /* Almost RTMpOnSpecific profiling. */
    71197155    Log(("supdrvDetermineAsyncTsc: returns %d; iEndCpu=%d rc=%d offMin=%llx offMax=%llx\n",
    71207156         fAsync, iEndCpu, rc, offMin, offMax));
     
    72007236    pCpu->u64TSC             = ASMReadTSC();
    72017237    pCpu->u64TSCSample       = GIP_TSC_DELTA_RSVD;
    7202     pCpu->i64TSCDelta        = INT64_MAX;
     7238    pCpu->i64TSCDelta        = g_fOsTscDeltasInSync ? 0 : INT64_MAX;
    72037239
    72047240    ASMAtomicWriteSize(&pCpu->enmState, SUPGIPCPUSTATE_INVALID);
     
    72477283    LogFlow(("supdrvGipInit: pGip=%p HCPhys=%lx u64NanoTS=%llu uUpdateHz=%d cCpus=%u\n", pGip, (long)HCPhys, u64NanoTS, uUpdateHz, cCpus));
    72487284#endif
     7285
     7286    /*
     7287     * Record whether the host OS has already normalized inter-CPU deltas for the hardware TSC.
     7288     * We only bother with TSC-deltas only on invariant CPUs for now.
     7289     */
     7290    g_fOsTscDeltasInSync = supdrvIsInvariantTsc() && supdrvOSAreTscDeltasInSync();
    72497291
    72507292    /*
     
    76427684        return VERR_INVALID_CPU_ID;
    76437685
     7686    if (g_fOsTscDeltasInSync)
     7687        return VINF_SUCCESS;
     7688
    76447689    cTries       = RT_MAX(pReq->u.In.cRetries + 1, 10);
    76457690    cMsWaitRetry = RT_MAX(pReq->u.In.cMsWaitRetry, 5);
     
    77377782            AssertMsgReturn(iCpu < pGip->cCpus, ("iCpu=%u cCpus=%u\n", iCpu, pGip->cCpus), VERR_INVALID_CPU_INDEX);
    77387783
     7784            Assert(!g_fOsTscDeltasInSync);
    77397785            rc2 = supdrvMeasureTscDeltaOne(pDevExt, iCpu);
    77407786            if (RT_SUCCESS(rc2))
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r53054 r53396  
    751751bool VBOXCALL   supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc);
    752752bool VBOXCALL   supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt);
     753bool VBOXCALL   supdrvOSAreTscDeltasInSync(void);
    753754int  VBOXCALL   supdrvOSEnableVTx(bool fEnabled);
    754755bool VBOXCALL   supdrvOSSuspendVTxOnCpu(void);
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp

    r52618 r53396  
    954954
    955955
     956bool VBOXCALL supdrvOSAreTscDeltasInSync(void)
     957{
     958    return false;
     959}
     960
    956961void VBOXCALL   supdrvOSLdrNotifyOpened(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
    957962{
  • trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c

    r52576 r53396  
    540540
    541541
     542bool VBOXCALL  supdrvOSAreTscDeltasInSync(void)
     543{
     544    return false;
     545}
     546
     547
    542548int  VBOXCALL   supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
    543549{
  • trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c

    r53339 r53396  
    867867
    868868
     869bool VBOXCALL supdrvOSAreTscDeltasInSync(void)
     870{
     871    return false;
     872}
     873
     874
    869875int  VBOXCALL   supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
    870876{
  • trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp

    r52618 r53396  
    407407
    408408
     409bool VBOXCALL  supdrvOSAreTscDeltasInSync(void)
     410{
     411    NOREF(pDevExt);
     412    return false;
     413}
     414
     415
    409416int  VBOXCALL   supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
    410417{
  • trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c

    r53269 r53396  
    964964}
    965965
     966
     967bool VBOXCALL  supdrvOSAreTscDeltasInSync(void)
     968{
     969    return false;
     970}
     971
     972
    966973#if  defined(VBOX_WITH_NATIVE_SOLARIS_LOADING) \
    967974 && !defined(VBOX_WITHOUT_NATIVE_R0_LOADER)
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r53329 r53396  
    16551655
    16561656
     1657/**
     1658 * Whether the hardware TSC has been synchronized by the OS.
     1659 */
     1660bool VBOXCALL  supdrvOSAreTscDeltasInSync(void)
     1661{
     1662    /* Windows writes back the hardware TSC registers to adjust for inter-CPU deltas. */
     1663    return true;
     1664}
     1665
     1666
    16571667#define MY_SystemLoadGdiDriverInSystemSpaceInformation  54
    16581668#define MY_SystemUnloadGdiDriverInformation             27
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