VirtualBox

Changeset 53464 in vbox for trunk/src


Ignore:
Timestamp:
Dec 5, 2014 2:52:21 PM (10 years ago)
Author:
vboxsync
Message:

HostDrivers/Support: Move certain globals into the device extension, addressing todo in r97183.

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

Legend:

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

    r53459 r53464  
    138138
    139139/** Whether the application of TSC-deltas is required. */
    140 #define GIP_ARE_TSC_DELTAS_APPLICABLE(a_pGip)  ((a_pGip)->u32Mode == SUPGIPMODE_INVARIANT_TSC && !g_fOsTscDeltasInSync)
     140#define GIP_ARE_TSC_DELTAS_APPLICABLE(a_pDevExt)  ((a_pDevExt)->pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC && !((a_pDevExt)->fOsTscDeltasInSync))
    141141
    142142
     
    176176static void                 supdrvGipUpdatePerCpu(PSUPDRVDEVEXT pDevExt, uint64_t u64NanoTS, uint64_t u64TSC,
    177177                                                  RTCPUID idCpu, uint8_t idApic, uint64_t iTick);
    178 static void                 supdrvGipInitCpu(PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pCpu, uint64_t u64NanoTS);
     178static void                 supdrvGipInitCpu(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pCpu, uint64_t u64NanoTS);
    179179static int                  supdrvMeasureTscDeltas(PSUPDRVDEVEXT pDevExt, uint32_t *pidxMaster);
    180180static int                  supdrvMeasureTscDeltaOne(PSUPDRVDEVEXT pDevExt, uint32_t idxWorker);
     
    187187DECLEXPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage = NULL;
    188188
    189 /** @name r=bird: Stuff that should be SUPDRVDEVEXT members.
    190  * @todo Move this ASAP.  */
    191 /**
    192  * The TSC delta synchronization struct. rounded to cache line size.
    193  */
    194 typedef union SUPTSCDELTASYNC
    195 {
    196     /** The synchronization variable, holds values GIP_TSC_DELTA_SYNC_*. */
    197     volatile uint32_t   u;
    198     /** Padding to cache line size. */
    199     uint8_t             u8Padding[64];
    200 } SUPTSCDELTASYNC;
    201 AssertCompileSize(SUPTSCDELTASYNC, 64);
    202 typedef SUPTSCDELTASYNC *PSUPTSCDELTASYNC;
    203 
    204 /** Pointer to the TSC delta sync. struct. */
    205 static void                *g_pvTscDeltaSync;
    206 /** Aligned pointer to the TSC delta sync. struct. */
    207 static PSUPTSCDELTASYNC     g_pTscDeltaSync;
    208 /** The TSC delta measurement initiator Cpu Id. */
    209 static volatile RTCPUID     g_idTscDeltaInitiator = NIL_RTCPUID;
    210 /** Number of online/offline events, incremented each time a CPU goes online
    211  *  or offline. */
    212 static volatile uint32_t    g_cMpOnOffEvents;
    213 /** TSC reading during start of TSC frequency refinement phase. */
    214 static uint64_t             g_u64TscAnchor;
    215 /** Timestamp (in nanosec) during start of TSC frequency refinement phase. */
    216 static uint64_t             g_u64NanoTSAnchor;
    217 /** Pointer to the timer used to refine the TSC frequency. */
    218 static PRTTIMER             g_pTscRefineTimer;
    219 /** Whether the host OS has already normalized the hardware TSC deltas across
    220  *  CPUs. */
    221 static bool                 g_fOsTscDeltasInSync;
    222 /** @}  */
    223189
    224190/**
     
    543509    pDevExt->hGipSpinlock = NIL_RTSPINLOCK;
    544510    pDevExt->hSessionHashTabSpinlock = NIL_RTSPINLOCK;
     511    pDevExt->idTscDeltaInitiator = NIL_RTCPUID;
    545512    rc = RTSpinlockCreate(&pDevExt->Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "SUPDrvDevExt");
    546513    if (RT_SUCCESS(rc))
     
    59245891static int supdrvTscDeltaThreadInit(PSUPDRVDEVEXT pDevExt)
    59255892{
    5926     Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt->pGip));
     5893    Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt));
    59275894
    59285895    int rc = RTSpinlockCreate(&pDevExt->hTscDeltaSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "VBoxTscSpnLck");
     
    61066073        ASMSetFlags(uFlags);
    61076074
    6108         if (GIP_ARE_TSC_DELTAS_APPLICABLE(pGip))
     6075        if (GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt))
    61096076        {
    61106077            int rc;
     
    61556122 *
    61566123 * @param   pTimer      The timer.
    6157  * @param   pvUser      Opaque pointer to the GIP.
     6124 * @param   pvUser      Opaque pointer to the device instance data.
    61586125 * @param   iTick       The timer tick.
    61596126 */
    61606127static DECLCALLBACK(void) supdrvRefineTscTimer(PRTTIMER pTimer, void *pvUser, uint64_t iTick)
    61616128{
     6129    PSUPDRVDEVEXT      pDevExt = (PSUPDRVDEVEXT)pvUser;
     6130    PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
     6131    bool               fDeltaApplied = false;
    61626132    uint8_t            idApic;
    61636133    uint64_t           u64DeltaNanoTS;
     
    61666136    uint64_t           u64Tsc;
    61676137    RTCCUINTREG        uFlags;
    6168     bool               fDeltaApplied = false;
    6169     PSUPGLOBALINFOPAGE pGip = (PSUPGLOBALINFOPAGE)pvUser;
    61706138
    61716139    /* Paranoia. */
     
    61846152    ASMSetFlags(uFlags);
    61856153    SUPTscDeltaApply(pGip, &u64Tsc, idApic, &fDeltaApplied);
    6186     u64DeltaNanoTS = u64NanoTS - g_u64NanoTSAnchor;
    6187     u64DeltaTsc = u64Tsc - g_u64TscAnchor;
     6154    u64DeltaNanoTS = u64NanoTS - pDevExt->u64NanoTSAnchor;
     6155    u64DeltaTsc = u64Tsc - pDevExt->u64TscAnchor;
    61886156
    61896157    if (   pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC
     
    62436211    while (RTTimeSystemNanoTS() == u64NanoTS)
    62446212        ASMNopPause();
    6245     uFlags            = ASMIntDisableFlags();
    6246     idApic            = ASMGetApicId();
    6247     g_u64TscAnchor    = ASMReadTSC();
    6248     g_u64NanoTSAnchor = RTTimeSystemNanoTS();
     6213    uFlags                   = ASMIntDisableFlags();
     6214    idApic                   = ASMGetApicId();
     6215    pDevExt->u64TscAnchor    = ASMReadTSC();
     6216    pDevExt->u64NanoTSAnchor = RTTimeSystemNanoTS();
    62496217    ASMSetFlags(uFlags);
    6250     SUPTscDeltaApply(pGip, &g_u64TscAnchor, idApic, &fDeltaApplied);
     6218    SUPTscDeltaApply(pGip, &pDevExt->u64TscAnchor, idApic, &fDeltaApplied);
    62516219
    62526220#ifdef SUPDRV_USE_TSC_DELTA_THREAD
     
    62636231#endif
    62646232
    6265     rc = RTTimerCreateEx(&g_pTscRefineTimer, 0 /* one-shot */, RTTIMER_FLAGS_CPU_ANY, supdrvRefineTscTimer, pGip);
     6233    rc = RTTimerCreateEx(&pDevExt->pTscRefineTimer, 0 /* one-shot */, RTTIMER_FLAGS_CPU_ANY, supdrvRefineTscTimer, pDevExt);
    62666234    if (RT_SUCCESS(rc))
    62676235    {
     
    62746242         * same TSC frequency whenever possible so we need to keep the interval short.
    62756243         */
    6276         rc = RTTimerStart(g_pTscRefineTimer, GIP_TSC_REFINE_INTERVAL * RT_NS_1SEC_64);
     6244        rc = RTTimerStart(pDevExt->pTscRefineTimer, GIP_TSC_REFINE_INTERVAL * RT_NS_1SEC_64);
    62776245        AssertRC(rc);
    62786246    }
     
    63286296    pGip = (PSUPGLOBALINFOPAGE)RTR0MemObjAddress(pDevExt->GipMemObj); AssertPtr(pGip);
    63296297    HCPhysGip = RTR0MemObjGetPagePhysAddr(pDevExt->GipMemObj, 0); Assert(HCPhysGip != NIL_RTHCPHYS);
     6298
     6299    /*
     6300     * Allocate the TSC-delta sync struct on a separate cache line.
     6301     */
     6302    pDevExt->pvTscDeltaSync = RTMemAllocZ(sizeof(SUPTSCDELTASYNC) + 63);
     6303    pDevExt->pTscDeltaSync  = RT_ALIGN_PT(pDevExt->pvTscDeltaSync, 64, PSUPTSCDELTASYNC);
     6304    Assert(RT_ALIGN_PT(pDevExt->pTscDeltaSync, 64, PSUPTSCDELTASYNC) == pDevExt->pTscDeltaSync);
    63306305
    63316306    /*
     
    63446319    supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), RT_NS_1SEC / u32Interval /*=Hz*/, u32Interval, cCpus);
    63456320
    6346     if (RT_UNLIKELY(   g_fOsTscDeltasInSync
     6321    if (RT_UNLIKELY(   pDevExt->fOsTscDeltasInSync
    63476322                    && pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
    63486323                    && !supdrvOSGetForcedAsyncTscMode(pDevExt)))
    63496324    {
    6350         /* Basically invariant Windows boxes, should never be detected as async. */
     6325        /* Basically, invariant Windows boxes, should never be detected as async (i.e. TSC-deltas should be 0). */
    63516326        OSDBGPRINT(("supdrvGipCreate: The TSC-deltas should be normalized by the host OS, but verifying shows it's not!\n"));
    63526327        return VERR_INTERNAL_ERROR_2;
     
    63546329
    63556330#ifdef SUPDRV_USE_TSC_DELTA_THREAD
    6356     if (GIP_ARE_TSC_DELTAS_APPLICABLE(pGip))
     6331    if (GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt))
    63576332    {
    63586333        /* Initialize TSC-delta measurement thread before executing any Mp event callbacks. */
     
    63706345                uint16_t iCpu;
    63716346#ifndef SUPDRV_USE_TSC_DELTA_THREAD
    6372                 if (GIP_ARE_TSC_DELTAS_APPLICABLE(pGip))
     6347                if (GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt))
    63736348                {
    63746349                    /*
     
    64806455     * Destroy the TSC-refinement one-shot timer.
    64816456     */
    6482     if (g_pTscRefineTimer)
    6483     {
    6484         RTTimerDestroy(g_pTscRefineTimer);
    6485         g_pTscRefineTimer = NULL;
     6457    if (pDevExt->pTscRefineTimer)
     6458    {
     6459        RTTimerDestroy(pDevExt->pTscRefineTimer);
     6460        pDevExt->pTscRefineTimer = NULL;
     6461    }
     6462
     6463    if (pDevExt->pvTscDeltaSync)
     6464    {
     6465        RTMemFree(pDevExt->pvTscDeltaSync);
     6466        pDevExt->pTscDeltaSync  = NULL;
     6467        pDevExt->pvTscDeltaSync = NULL;
    64866468    }
    64876469
     
    65376519    u64NanoTS = RTTimeSystemNanoTS();
    65386520
    6539     if (GIP_ARE_TSC_DELTAS_APPLICABLE(pGip))
     6521    if (GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt))
    65406522    {
    65416523        /*
     
    66606642    u64NanoTS = RTTimeSystemNanoTS() - pGip->u32UpdateIntervalNS;
    66616643    i = supdrvGipCpuIndexFromCpuId(pGip, idCpu);
    6662     supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS);
     6644    supdrvGipInitCpu(pDevExt, pGip, &pGip->aCPUs[i], u64NanoTS);
    66636645    idApic = ASMGetApicId();
    66646646    ASMAtomicWriteU16(&pGip->aCPUs[i].idApic,  idApic);
     
    66736655
    66746656    /* Update the Mp online/offline counter. */
    6675     ASMAtomicIncU32(&g_cMpOnOffEvents);
     6657    ASMAtomicIncU32(&pDevExt->cMpOnOffEvents);
    66766658
    66776659#ifdef SUPDRV_USE_TSC_DELTA_THREAD
     
    66826664     * update the state and it'll get serviced when the thread's listening interval times out.
    66836665     */
    6684     if (GIP_ARE_TSC_DELTAS_APPLICABLE(pGip))
     6666    if (GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt))
    66856667    {
    66866668        RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock);
     
    67316713
    67326714    /* Update the Mp online/offline counter. */
    6733     ASMAtomicIncU32(&g_cMpOnOffEvents);
     6715    ASMAtomicIncU32(&pDevExt->cMpOnOffEvents);
    67346716
    67356717    /* If we are the initiator going offline while measuring the TSC delta, unspin other waiting CPUs! */
    6736     if (ASMAtomicReadU32(&g_idTscDeltaInitiator) == idCpu)
    6737     {
    6738         ASMAtomicWriteU32(&g_pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_START);
     6718    if (ASMAtomicReadU32(&pDevExt->idTscDeltaInitiator) == idCpu)
     6719    {
     6720        ASMAtomicWriteU32(&pDevExt->pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_START);
    67396721        ASMAtomicWriteU64(&pGip->aCPUs[i].u64TSCSample, ~GIP_TSC_DELTA_RSVD);
    67406722    }
    67416723
    67426724    /* Reset the TSC delta, we will recalculate it lazily. */
    6743     if (GIP_ARE_TSC_DELTAS_APPLICABLE(pGip))
     6725    if (GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt))
    67446726        ASMAtomicWriteS64(&pGip->aCPUs[i].i64TSCDelta, INT64_MAX);
    67456727
     
    68576839 *
    68586840 * @param   idCpu       The CPU we are current scheduled on.
    6859  * @param   pvUser1     Opaque pointer to the GIP.
     6841 * @param   pvUser1     Opaque pointer to the device instance data.
    68606842 * @param   pvUser2     Opaque pointer to the worker Cpu Id.
    68616843 *
     
    68876869static DECLCALLBACK(void) supdrvMeasureTscDeltaCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2)
    68886870{
    6889     PSUPGLOBALINFOPAGE pGip      = (PSUPGLOBALINFOPAGE)pvUser1;
     6871    PSUPDRVDEVEXT      pDevExt   = (PSUPDRVDEVEXT)pvUser1;
     6872    PSUPGLOBALINFOPAGE pGip      = pDevExt->pGip;
    68906873    uint32_t          *pidWorker = (uint32_t *)pvUser2;
    6891     RTCPUID            idMaster  = ASMAtomicUoReadU32(&g_idTscDeltaInitiator);
     6874    RTCPUID            idMaster  = ASMAtomicUoReadU32(&pDevExt->idTscDeltaInitiator);
    68926875    unsigned           idxMaster = supdrvGipCpuIndexFromCpuId(pGip, idMaster);
    68936876    unsigned           idxWorker = supdrvGipCpuIndexFromCpuId(pGip, *pidWorker);
     
    69156898        if (idCpu == idMaster)
    69166899        {
    6917             ASMAtomicWriteU32(&g_pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_PRESTART_MASTER);
    6918             while (ASMAtomicReadU32(&g_pTscDeltaSync->u) != GIP_TSC_DELTA_SYNC_PRESTART_WORKER)
     6900            ASMAtomicWriteU32(&pDevExt->pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_PRESTART_MASTER);
     6901            while (ASMAtomicReadU32(&pDevExt->pTscDeltaSync->u) != GIP_TSC_DELTA_SYNC_PRESTART_WORKER)
    69196902            {
    69206903                ASMSerializeInstruction();
     
    69326915        else
    69336916        {
    6934             while (ASMAtomicReadU32(&g_pTscDeltaSync->u) != GIP_TSC_DELTA_SYNC_PRESTART_MASTER)
     6917            while (ASMAtomicReadU32(&pDevExt->pTscDeltaSync->u) != GIP_TSC_DELTA_SYNC_PRESTART_MASTER)
    69356918            {
    69366919                ASMSerializeInstruction();
     
    69446927                ASMNopPause();
    69456928            }
    6946             ASMAtomicWriteU32(&g_pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_PRESTART_WORKER);
     6929            ASMAtomicWriteU32(&pDevExt->pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_PRESTART_WORKER);
    69476930        }
    69486931    }
     
    69626945                RTCCUINTREG uFlags;
    69636946                Assert(pGipCpuMaster->u64TSCSample == GIP_TSC_DELTA_RSVD);
    6964                 ASMAtomicWriteU32(&g_pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_START);
     6947                ASMAtomicWriteU32(&pDevExt->pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_START);
    69656948
    69666949                /* Disable interrupts only in the master for as short a period
     
    69686951                uFlags = ASMIntDisableFlags();
    69696952
    6970                 while (ASMAtomicReadU32(&g_pTscDeltaSync->u) == GIP_TSC_DELTA_SYNC_START)
     6953                while (ASMAtomicReadU32(&pDevExt->pTscDeltaSync->u) == GIP_TSC_DELTA_SYNC_START)
    69716954                    ;
    69726955
     
    69796962                ASMSetFlags(uFlags);
    69806963
    6981                 while (ASMAtomicReadU32(&g_pTscDeltaSync->u) != GIP_TSC_DELTA_SYNC_WORKER_DONE)
     6964                while (ASMAtomicReadU32(&pDevExt->pTscDeltaSync->u) != GIP_TSC_DELTA_SYNC_WORKER_DONE)
    69826965                    ;
    69836966
     
    69936976
    69946977                ASMAtomicWriteU64(&pGipCpuMaster->u64TSCSample, GIP_TSC_DELTA_RSVD);
    6995                 ASMAtomicWriteU32(&g_pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_STOP);
     6978                ASMAtomicWriteU32(&pDevExt->pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_STOP);
    69966979            }
    69976980            else
     
    70056988
    70066989                ASMAtomicReadU64(&pGipCpuMaster->u64TSCSample);     /* Warm the cache line. */
    7007                 while (ASMAtomicReadU32(&g_pTscDeltaSync->u) != GIP_TSC_DELTA_SYNC_START)
     6990                while (ASMAtomicReadU32(&pDevExt->pTscDeltaSync->u) != GIP_TSC_DELTA_SYNC_START)
    70086991                    ;
    70096992                Assert(pGipCpuMaster->u64TSCSample == GIP_TSC_DELTA_RSVD);
    7010                 ASMAtomicWriteU32(&g_pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_WORKER_READY);
     6993                ASMAtomicWriteU32(&pDevExt->pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_WORKER_READY);
    70116994
    70126995                /*
     
    70437026                }
    70447027
    7045                 ASMAtomicWriteU32(&g_pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_WORKER_DONE);
    7046                 while (ASMAtomicReadU32(&g_pTscDeltaSync->u) == GIP_TSC_DELTA_SYNC_WORKER_DONE)
     7028                ASMAtomicWriteU32(&pDevExt->pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_WORKER_DONE);
     7029                while (ASMAtomicReadU32(&pDevExt->pTscDeltaSync->u) == GIP_TSC_DELTA_SYNC_WORKER_DONE)
    70477030                    ASMNopPause();
    70487031            }
     
    70607043 * GIP struct. as well.
    70617044 *
    7062  * @param   pGip            Pointer to the GIP.
     7045 * @param   pDevExt         Pointer to the device instance data.
    70637046 * @param   fClearDeltas    Whether the deltas are also to be cleared.
    70647047 */
    7065 DECLINLINE(void) supdrvClearTscSamples(PSUPGLOBALINFOPAGE pGip, bool fClearDeltas)
     7048DECLINLINE(void) supdrvClearTscSamples(PSUPDRVDEVEXT pDevExt, bool fClearDeltas)
    70667049{
    70677050    unsigned iCpu;
     7051    PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
    70687052    for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
    70697053    {
     
    70737057            ASMAtomicWriteS64(&pGipCpu->i64TSCDelta, INT64_MAX);
    70747058    }
    7075     ASMAtomicWriteU32(&g_pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_STOP);
     7059    ASMAtomicWriteU32(&pDevExt->pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_STOP);
    70767060}
    70777061
     
    71027086    pGipCpuWorker = &pGip->aCPUs[idxWorker];
    71037087
    7104     Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pGip));
     7088    Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt));
    71057089
    71067090    if (pGipCpuWorker->idCpu == idMaster)
     
    71117095
    71127096    /* Set the master TSC as the initiator. */
    7113     while (ASMAtomicCmpXchgU32(&g_idTscDeltaInitiator, idMaster, NIL_RTCPUID) == false)
     7097    while (ASMAtomicCmpXchgU32(&pDevExt->idTscDeltaInitiator, idMaster, NIL_RTCPUID) == false)
    71147098    {
    71157099        /*
     
    71247108        /* Fire TSC-read workers on all CPUs but only synchronize between master and one worker to ease memory contention. */
    71257109        ASMAtomicWriteS64(&pGipCpuWorker->i64TSCDelta, INT64_MAX);
    7126         ASMAtomicWriteU32(&g_pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_STOP);
    7127         rc = RTMpOnAll(supdrvMeasureTscDeltaCallback, pGip, &pGipCpuWorker->idCpu);
     7110        ASMAtomicWriteU32(&pDevExt->pTscDeltaSync->u, GIP_TSC_DELTA_SYNC_STOP);
     7111        rc = RTMpOnAll(supdrvMeasureTscDeltaCallback, pDevExt, &pGipCpuWorker->idCpu);
    71287112        if (RT_SUCCESS(rc))
    71297113        {
     
    71357119        rc = VERR_CPU_OFFLINE;
    71367120
    7137     ASMAtomicWriteU32(&g_idTscDeltaInitiator, NIL_RTCPUID);
     7121    ASMAtomicWriteU32(&pDevExt->idTscDeltaInitiator, NIL_RTCPUID);
    71387122    return rc;
    71397123}
     
    71607144    uint32_t   idxMaster      = UINT32_MAX;
    71617145    int        rc             = VINF_SUCCESS;
    7162     uint32_t   cMpOnOffEvents = ASMAtomicReadU32(&g_cMpOnOffEvents);
     7146    uint32_t   cMpOnOffEvents = ASMAtomicReadU32(&pDevExt->cMpOnOffEvents);
    71637147    uint32_t   cOnlineCpus    = pGip->cOnlineCpus;
    71647148
    7165     Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pGip));
     7149    Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt));
    71667150
    71677151    /*
     
    71737157     * master as this point since the sync/async timer isn't created yet.
    71747158     */
    7175     supdrvClearTscSamples(pGip, true /* fClearDeltas */);
     7159    supdrvClearTscSamples(pDevExt, true /* fClearDeltas */);
    71767160    for (iCpu = 0; iCpu < RT_ELEMENTS(pGip->aiCpuFromApicId); iCpu++)
    71777161    {
     
    72147198            }
    72157199
    7216             if (ASMAtomicReadU32(&g_cMpOnOffEvents) != cMpOnOffEvents)
     7200            if (ASMAtomicReadU32(&pDevExt->cMpOnOffEvents) != cMpOnOffEvents)
    72177201            {
    72187202                SUPR0Printf("One or more CPUs transitioned between online & offline states. I'm confused, retrying...\n");
     
    73917375 * Initializes per-CPU GIP information.
    73927376 *
    7393  * @param   pGip        Pointer to the read-write kernel mapping of the GIP.
     7377 * @param   pDevExt     Pointer to the device instance data.
     7378 * @param   pGip        Pointer to the GIP.
    73947379 * @param   pCpu        Pointer to which GIP CPU to initalize.
    73957380 * @param   u64NanoTS   The current nanosecond timestamp.
    73967381 */
    7397 static void supdrvGipInitCpu(PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pCpu, uint64_t u64NanoTS)
    7398 {
     7382static void supdrvGipInitCpu(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pCpu, uint64_t u64NanoTS)
     7383{
     7384    /* !!! Warning !!! The GIP may not be linked to the device instance data at this point!
     7385       which is why we have 2 separate parameters. Don't dereference pDevExt->pGip here. */
    73997386    pCpu->u32TransactionId   = 2;
    74007387    pCpu->u64NanoTS          = u64NanoTS;
    74017388    pCpu->u64TSC             = ASMReadTSC();
    74027389    pCpu->u64TSCSample       = GIP_TSC_DELTA_RSVD;
    7403     pCpu->i64TSCDelta        = g_fOsTscDeltasInSync ? 0 : INT64_MAX;
     7390    pCpu->i64TSCDelta        = pDevExt->fOsTscDeltasInSync ? 0 : INT64_MAX;
    74047391
    74057392    ASMAtomicWriteSize(&pCpu->enmState, SUPGIPCPUSTATE_INVALID);
     
    74537440     * We only bother with TSC-deltas only on invariant CPUs for now.
    74547441     */
    7455     g_fOsTscDeltasInSync = supdrvIsInvariantTsc() && supdrvOSAreTscDeltasInSync();
     7442    pDevExt->fOsTscDeltasInSync = supdrvIsInvariantTsc() && supdrvOSAreTscDeltasInSync();
    74567443
    74577444    /*
     
    74797466
    74807467    for (i = 0; i < cCpus; i++)
    7481         supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS);
     7468        supdrvGipInitCpu(pDevExt, pGip, &pGip->aCPUs[i], u64NanoTS);
    74827469
    74837470    /*
     
    74877474    pDevExt->HCPhysGip = HCPhys;
    74887475    pDevExt->cGipUsers = 0;
    7489 
    7490     /*
    7491      * Allocate the TSC delta sync. struct. on a separate cache line.
    7492      */
    7493     g_pvTscDeltaSync = RTMemAllocZ(sizeof(SUPTSCDELTASYNC) + 63);
    7494     g_pTscDeltaSync  = RT_ALIGN_PT(g_pvTscDeltaSync, 64, PSUPTSCDELTASYNC);
    7495     Assert(RT_ALIGN_PT(g_pTscDeltaSync, 64, PSUPTSCDELTASYNC) == g_pTscDeltaSync);
    74967476}
    74977477
     
    75287508        pGip->aCPUs[i].u64TSCSample = 0;
    75297509        pGip->aCPUs[i].i64TSCDelta = INT64_MAX;
    7530     }
    7531 
    7532     if (g_pvTscDeltaSync)
    7533     {
    7534         RTMemFree(g_pvTscDeltaSync);
    7535         g_pTscDeltaSync  = NULL;
    7536         g_pvTscDeltaSync = NULL;
    75377510    }
    75387511}
     
    78847857    pGip = pDevExt->pGip;
    78857858
    7886     if (!GIP_ARE_TSC_DELTAS_APPLICABLE(pGip))
     7859    if (!GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt))
    78877860        return VINF_SUCCESS;
    78887861
     
    79787951            AssertMsgReturn(iCpu < pGip->cCpus, ("iCpu=%u cCpus=%u\n", iCpu, pGip->cCpus), VERR_INVALID_CPU_INDEX);
    79797952
    7980             Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pGip));
     7953            Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pDevExt));
    79817954            rc2 = supdrvMeasureTscDeltaOne(pDevExt, iCpu);
    79827955            if (RT_SUCCESS(rc2))
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r53430 r53464  
    556556
    557557/**
     558 * The TSC delta synchronization struct. rounded to cache line size.
     559 */
     560typedef union SUPTSCDELTASYNC
     561{
     562    /** The synchronization variable, holds values GIP_TSC_DELTA_SYNC_*. */
     563    volatile uint32_t   u;
     564    /** Padding to cache line size. */
     565    uint8_t             u8Padding[64];
     566} SUPTSCDELTASYNC;
     567AssertCompileSize(SUPTSCDELTASYNC, 64);
     568typedef SUPTSCDELTASYNC *PSUPTSCDELTASYNC;
     569
     570
     571/**
    558572 * Device extension.
    559573 */
     
    679693    /** @} */
    680694
     695    /** @name TSC-delta measurement.
     696     *  @{ */
     697    /** TSC reading during start of TSC frequency refinement phase. */
     698    uint64_t                        u64TscAnchor;
     699    /** Timestamp (in nanosec) during start of TSC frequency refinement phase. */
     700    uint64_t                        u64NanoTSAnchor;
     701    /** Pointer to the timer used to refine the TSC frequency. */
     702    PRTTIMER                        pTscRefineTimer;
     703    /** Pointer to the TSC delta sync. struct. */
     704    void                           *pvTscDeltaSync;
     705    /** The TSC delta measurement initiator Cpu Id. */
     706    RTCPUID volatile                idTscDeltaInitiator;
     707    /** Number of online/offline events, incremented each time a CPU goes online
     708     *  or offline. */
     709    uint32_t volatile               cMpOnOffEvents;
     710    /** Aligned pointer to the TSC delta sync. struct. */
     711    PSUPTSCDELTASYNC                pTscDeltaSync;
     712    /** Whether the host OS has already normalized the hardware TSC deltas across
     713     *  CPUs. */
     714    bool                            fOsTscDeltasInSync;
     715    /** @}  */
     716
    681717#ifdef SUPDRV_USE_TSC_DELTA_THREAD
    682     /** @name TSC-delta measurement.
     718    /** @name TSC-delta measurement thread.
    683719     *  @{ */
    684720    /** Spinlock protecting enmTscDeltaState. */
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