VirtualBox

Changeset 54462 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Feb 24, 2015 5:54:23 PM (10 years ago)
Author:
vboxsync
Message:

SUPDrvGip.cpp: Sync fixes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp

    r54458 r54462  
    26102610    /** The time the master spent in the MP worker.  */
    26112611    uint64_t                    cElapsedMasterTscTicks;
     2612    /** The iTry value when stopped at. */
     2613    uint32_t                    iTry;
     2614    /** Set if the run timed out.   */
     2615    bool volatile               fTimedOut;
    26122616    /** Pointer to the master's synchronization struct (on stack). */
    26132617    PSUPTSCDELTASYNC2 volatile  pSyncMaster;
     
    26602664# define TSCDELTA_DBG_CHECK_LOOP()      ((void)0)
    26612665#endif
     2666#if 0
     2667# define TSCDELTA_DBG_SYNC_MSG(a_Args)  SUPR0Printf a_Args
     2668#else
     2669# define TSCDELTA_DBG_SYNC_MSG(a_Args)  ((void)0)
     2670#endif
     2671#if 0
     2672# define TSCDELTA_DBG_SYNC_MSG2(a_Args) SUPR0Printf a_Args
     2673#else
     2674# define TSCDELTA_DBG_SYNC_MSG2(a_Args) ((void)0)
     2675#endif
     2676#if 0
     2677# define TSCDELTA_DBG_SYNC_MSG9(a_Args) SUPR0Printf a_Args
     2678#else
     2679# define TSCDELTA_DBG_SYNC_MSG9(a_Args) ((void)0)
     2680#endif
    26622681
    26632682
    26642683static bool supdrvTscDeltaSync2_Before(PSUPTSCDELTASYNC2 pMySync, PSUPTSCDELTASYNC2 pOtherSync,
    2665                                        bool fIsMaster, PRTCCUINTREG pfEFlags)
     2684                                       bool fIsMaster, PRTCCUINTREG pfEFlags, PSUPDRVGIPTSCDELTARGS pArgs)
    26662685{
    26672686    uint32_t        iMySeq  = fIsMaster ? 0 : 256;
     
    26822701        { /* likely*/ }
    26832702        else
     2703        {
     2704            TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #1 uSyncVar=%#x\n", fIsMaster ? "master" : "worker", pOtherSync->uSyncVar));
    26842705            return false;
     2706        }
    26852707    }
    26862708
     
    26952717        if (u32Tmp == GIP_TSC_DELTA_SYNC2_STEADY)
    26962718            break;
    2697 
    26982719        ASMSetFlags(fEFlags);
    26992720        ASMNopPause();
     
    27012722        /* Abort? */
    27022723        if (u32Tmp != GIP_TSC_DELTA_SYNC2_READY)
    2703             break;
     2724        {
     2725            TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #2 u32Tmp=%#x\n", fIsMaster ? "master" : "worker", u32Tmp));
     2726            return false;
     2727        }
    27042728
    27052729        /* Check for timeouts every so often (not every loop in case RDTSC is
     
    27192743            if (ASMAtomicCmpXchgU32(&pMySync->uSyncVar, GIP_TSC_DELTA_SYNC2_TIMEOUT, GIP_TSC_DELTA_SYNC2_READY))
    27202744            {
     2745                TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: timeout\n", fIsMaster ? "master" : "worker"));
    27212746                ASMAtomicCmpXchgU32(&pOtherSync->uSyncVar, GIP_TSC_DELTA_SYNC2_TIMEOUT, GIP_TSC_DELTA_SYNC2_STEADY);
     2747                ASMAtomicWriteBool(&pArgs->fTimedOut, true);
    27222748                return false;
    27232749            }
     
    27432769        {
    27442770            ASMSetFlags(fEFlags);
     2771            TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #3 uSyncVar=%#x\n", fIsMaster ? "master" : "worker", pOtherSync->uSyncVar));
    27452772            return false;
    27462773        }
     
    27572784        {
    27582785            ASMSetFlags(fEFlags);
     2786            TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #4 uSyncVar=%#x\n", fIsMaster ? "master" : "worker", pOtherSync->uSyncVar));
    27592787            return false;
    27602788        }
     
    27752803        {
    27762804            ASMSetFlags(fEFlags);
     2805            TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #5 u32Tmp=%#x\n", fIsMaster ? "master" : "worker", u32Tmp));
    27772806            return false;
    27782807        }
     
    27922821        {
    27932822            ASMSetFlags(fEFlags);
     2823            TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #6 uSyncVar=%#x\n", fIsMaster ? "master" : "worker", pOtherSync->uSyncVar));
    27942824            return false;
    27952825        }
     
    28282858}
    28292859
    2830 #define TSCDELTA_MASTER_SYNC_BEFORE(a_pMySync, a_pOtherSync, a_pfEFlags) \
    2831     if (RT_LIKELY(supdrvTscDeltaSync2_Before(a_pMySync, a_pOtherSync, true /*fMaster*/, a_pfEFlags))) \
     2860#define TSCDELTA_MASTER_SYNC_BEFORE(a_pMySync, a_pOtherSync, a_pfEFlags, a_pArgs) \
     2861    if (RT_LIKELY(supdrvTscDeltaSync2_Before(a_pMySync, a_pOtherSync, true /*fIsMaster*/, a_pfEFlags, a_pArgs))) \
    28322862    { /*likely*/ } \
    2833     else break
    2834 #define TSCDELTA_OTHER_SYNC_BEFORE(a_pMySync, a_pOtherSync, a_pfEFlags) \
    2835     if (RT_LIKELY(supdrvTscDeltaSync2_Before(a_pMySync, a_pOtherSync, false /*fMaster*/, a_pfEFlags))) \
     2863    else if (true) \
     2864    { \
     2865        TSCDELTA_DBG_SYNC_MSG9(("sync/before/master: #89\n")); \
     2866        break; \
     2867    } else do {} while (0)
     2868#define TSCDELTA_OTHER_SYNC_BEFORE(a_pMySync, a_pOtherSync, a_pfEFlags, a_pArgs) \
     2869    if (RT_LIKELY(supdrvTscDeltaSync2_Before(a_pMySync, a_pOtherSync, false /*fIsMaster*/, a_pfEFlags, a_pArgs))) \
    28362870    { /*likely*/ } \
    2837     else break
    2838 
    2839 
    2840 static bool supdrvTscDeltaSync2_After(PSUPTSCDELTASYNC2 pMySync, PSUPTSCDELTASYNC2 pOtherSync, RTCCUINTREG fEFlags)
     2871    else if (true) \
     2872    { \
     2873        TSCDELTA_DBG_SYNC_MSG9(("sync/before/other: #89\n")); \
     2874        break; \
     2875    } else do {} while (0)
     2876
     2877
     2878static bool supdrvTscDeltaSync2_After(PSUPTSCDELTASYNC2 pMySync, PSUPTSCDELTASYNC2 pOtherSync,
     2879                                      bool fIsMaster, RTCCUINTREG fEFlags)
    28412880{
    28422881    TSCDELTA_DBG_VARS();
     
    28532892    {
    28542893        uint32_t u32Tmp = ASMAtomicReadU32(&pMySync->uSyncVar);
    2855         if (u32Tmp == GIP_TSC_DELTA_SYNC2_READY)
     2894        if (   u32Tmp == GIP_TSC_DELTA_SYNC2_READY
     2895            || (u32Tmp == GIP_TSC_DELTA_SYNC2_STEADY && !fIsMaster) /* kicked twice => race */ )
    28562896            return true;
    28572897        ASMNopPause();
    2858         if (u32Tmp != GIP_TSC_DELTA_SYNC2_GO)
     2898        if (RT_LIKELY(u32Tmp == GIP_TSC_DELTA_SYNC2_GO))
     2899        { /* likely */}
     2900        else
     2901        {
     2902            TSCDELTA_DBG_SYNC_MSG(("sync/after/other: #1 u32Tmp=%#x\n", u32Tmp));
    28592903            return false; /* shouldn't ever happen! */
     2904        }
    28602905        TSCDELTA_DBG_CHECK_LOOP();
    28612906        ASMNopPause();
     
    28642909
    28652910#define TSCDELTA_MASTER_SYNC_AFTER(a_pMySync, a_pOtherSync, a_fEFlags) \
    2866     if (RT_LIKELY(supdrvTscDeltaSync2_After(a_pMySync, a_pOtherSync, a_fEFlags))) \
     2911    if (RT_LIKELY(supdrvTscDeltaSync2_After(a_pMySync, a_pOtherSync, true /*fIsMaster*/, a_fEFlags))) \
    28672912    { /* likely */ } \
    2868     else break
     2913    else if (true) \
     2914    { \
     2915        TSCDELTA_DBG_SYNC_MSG9(("sync/after/master: #97\n")); \
     2916        break; \
     2917    } else do {} while (0)
    28692918
    28702919#define TSCDELTA_MASTER_KICK_OTHER_OUT_OF_AFTER(a_pMySync, a_pOtherSync) \
     
    28742923    if (RT_LIKELY(ASMAtomicCmpXchgU32(&(a_pOtherSync)->uSyncVar, GIP_TSC_DELTA_SYNC2_READY, GIP_TSC_DELTA_SYNC2_GO))) \
    28752924    { /* likely */ } \
    2876     else break
     2925    else if (true)\
     2926    { \
     2927        TSCDELTA_DBG_SYNC_MSG(("sync/after/master: #99 uSyncVar=%#x\n", (a_pOtherSync)->uSyncVar)); \
     2928        break; \
     2929    } else do {} while (0)
    28772930
    28782931#define TSCDELTA_OTHER_SYNC_AFTER(a_pMySync, a_pOtherSync, a_fEFlags) \
     
    28862939        { \
    28872940            ASMSetFlags(a_fEFlags); \
     2941            TSCDELTA_DBG_SYNC_MSG(("sync/after/other: #0 uSyncVar=%#x\n", (a_pOtherSync)->uSyncVar)); \
    28882942            break; \
    28892943        } \
    2890         if (RT_LIKELY(supdrvTscDeltaSync2_After(a_pMySync, a_pOtherSync, a_fEFlags))) \
     2944        if (RT_LIKELY(supdrvTscDeltaSync2_After(a_pMySync, a_pOtherSync, false /*fIsMaster*/, a_fEFlags))) \
    28912945        { /* likely */ } \
    2892         else break; \
    2893     }  else do {} while (0)
     2946        else \
     2947        { \
     2948            TSCDELTA_DBG_SYNC_MSG9(("sync/after/other: #98\n")); \
     2949            break;  \
     2950        } \
     2951    } else do {} while (0)
    28942952/** @} */
    28952953
     
    29483006                      ("%#llx idMaster=%#x idWorker=%#x (idGipMaster=%#x)\n",
    29493007                       pGipCpuMaster->u64TSCSample, pGipCpuMaster->idCpu, pGipCpuWorker->idCpu, pArgs->pDevExt->idGipMaster));
    2950             TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags);
     3008            TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs);
    29513009
    29523010            do
     
    29863044
    29873045            ASMAtomicReadU64(&pGipCpuMaster->u64TSCSample);     /* Warm the cache line. */
    2988             TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags);
     3046            TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs);
    29893047
    29903048            /*
     
    30253083    }
    30263084
     3085    TSCDELTA_DBG_SYNC_MSG9(("sync/method1loop/%s: #92 iLoop=%u MyState=%#x\n", fIsMaster ? "master" : "worker", iLoop,
     3086                           pMySync->uSyncVar));
     3087
    30273088    /*
    30283089     * We must reset the worker TSC sample value in case it gets picked as a
     
    30653126 */
    30663127
    3067 # define GIP_TSC_DELTA_M2_LOOPS             (12 + GIP_TSC_DELTA_M2_PRIMER_LOOPS)
     3128# define GIP_TSC_DELTA_M2_LOOPS             (8 + GIP_TSC_DELTA_M2_PRIMER_LOOPS)
    30683129# define GIP_TSC_DELTA_M2_PRIMER_LOOPS      1
    30693130
     
    31093170    if (cHits > 2)
    31103171        pArgs->pWorker->i64TSCDelta = iBestDelta;
    3111     pArgs->M2.cHits     += cHits;
    3112 
    3113 #if 1
     3172    pArgs->M2.cHits += cHits;
     3173
     3174#if 0 /* This is pointless now with supdrvTscDeltaVerify(0). */
    31143175    /*
    31153176     * Check and see if we can quit a little early.  If the result is already
     
    32443305             * Sync up with the worker and collect data.
    32453306             */
    3246             TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags);
     3307            TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs);
    32473308            supdrvTscDeltaMethod2CollectData(pArgs->M2.pMasterData, &pArgs->M2.pWorkerData->iCurSeqNo, pArgs->M2.fLagMaster);
    32483309            TSCDELTA_MASTER_SYNC_AFTER(pMySync, pOtherSync, fEFlags);
     
    32633324             * The worker.
    32643325             */
    3265             TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags);
     3326            TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs);
    32663327            supdrvTscDeltaMethod2CollectData(pArgs->M2.pWorkerData, &pArgs->M2.pMasterData->iCurSeqNo, pArgs->M2.fLagWorker);
    32673328            TSCDELTA_OTHER_SYNC_AFTER(pMySync, pOtherSync, fEFlags);
     
    33163377                                PSUPTSCDELTASYNC2 pOtherSync, bool fIsMaster, int64_t iWorkerTscDelta)
    33173378{
    3318     PSUPGIPCPU pGipCpuWorker = pArgs->pWorker;
     3379    /*PSUPGIPCPU pGipCpuWorker = pArgs->pWorker; - unused */
    33193380    PSUPGIPCPU pGipCpuMaster = pArgs->pMaster;
    33203381    uint32_t   i;
     
    33303391        {
    33313392            uint64_t uTscWorker;
    3332             TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags);
     3393            TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs);
    33333394
    33343395            /*
     
    34253486             * The worker, master leads.
    34263487             */
    3427             TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags);
     3488            TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs);
    34283489
    34293490            for (i = 0; i < RT_ELEMENTS(pArgs->auVerifyWorkerTscs); i += 2)
     
    34923553    ASMAtomicWriteNullPtr(ppMySync);
    34933554    ASMAtomicWriteBool(&pArgs->fAbortSetup, true);
     3555    if (fTimeout)
     3556        ASMAtomicWriteBool(&pArgs->fTimedOut, true);
    34943557
    34953558    /*
     
    36273690        {
    36283691            ASMAtomicWriteS64(&pGipCpuWorker->i64TSCDelta, GIP_TSC_DELTA_INITIAL_MASTER_VALUE);
    3629             RTCpuSetDelByIndex(&pDevExt->TscDeltaCpuSet, pGipCpuMaster->iCpuSet);
    3630             RTCpuSetAddByIndex(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuMaster->iCpuSet);
    3631         }
    3632         else
    3633         {
    36343692            RTCpuSetDelByIndex(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->iCpuSet);
    36353693            RTCpuSetAddByIndex(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuWorker->iCpuSet);
     
    36453703        for (iTry = 0; iTry < 12; iTry++)
    36463704        {
    3647             if (ASMAtomicReadU32(&MySync.uSyncVar) != GIP_TSC_DELTA_SYNC2_READY)
     3705            /*
     3706             * Check the state before we start.
     3707             */
     3708            uint32_t u32Tmp = ASMAtomicReadU32(&MySync.uSyncVar);
     3709            if (   u32Tmp != GIP_TSC_DELTA_SYNC2_READY
     3710                && (fIsMaster || u32Tmp != GIP_TSC_DELTA_SYNC2_STEADY) /* worker may be late prepping for the next round */ )
     3711            {
     3712                TSCDELTA_DBG_SYNC_MSG(("sync/loop/%s: #0 iTry=%u MyState=%#x\n", fIsMaster ? "master" : "worker", iTry, u32Tmp));
    36483713                break;
     3714            }
    36493715
    36503716            /*
     
    36583724# error "huh??"
    36593725#endif
    3660             if (ASMAtomicReadU32(&MySync.uSyncVar) != GIP_TSC_DELTA_SYNC2_READY)
    3661                 break;
    36623726
    36633727            /*
    3664              * Success? If so, stop trying.
     3728             * Check the state.
    36653729             */
    3666 #if 1
    3667             if (pGipCpuWorker->i64TSCDelta != INT64_MAX)
    3668 #else
    3669             if (pGipCpuWorker->i64TSCDelta != INT64_MAX && iTry >= 11)
    3670 #endif
     3730            u32Tmp = ASMAtomicReadU32(&MySync.uSyncVar);
     3731            if (   u32Tmp != GIP_TSC_DELTA_SYNC2_READY
     3732                && (fIsMaster || u32Tmp != GIP_TSC_DELTA_SYNC2_STEADY) /* worker may be late prepping for the next round */ )
    36713733            {
    36723734                if (fIsMaster)
    3673                 {
    3674                     RTCpuSetDelByIndex(&pDevExt->TscDeltaCpuSet, pGipCpuMaster->iCpuSet);
    3675                     RTCpuSetAddByIndex(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuMaster->iCpuSet);
    3676                 }
     3735                    TSCDELTA_DBG_SYNC_MSG(("sync/loop/master: #1 iTry=%u MyState=%#x\n", iTry, u32Tmp));
    36773736                else
     3737                    TSCDELTA_DBG_SYNC_MSG2(("sync/loop/worker: #1 iTry=%u MyState=%#x\n", iTry, u32Tmp));
     3738                break;
     3739            }
     3740
     3741            /*
     3742             * Success? If so, stop trying. Master decides.
     3743             */
     3744            if (fIsMaster)
     3745            {
     3746#if 0
     3747                if (pGipCpuWorker->i64TSCDelta != INT64_MAX)
     3748#else
     3749                if (pGipCpuWorker->i64TSCDelta != INT64_MAX && iTry >= 11)
     3750#endif
    36783751                {
    36793752                    RTCpuSetDelByIndex(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->iCpuSet);
    36803753                    RTCpuSetAddByIndex(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuWorker->iCpuSet);
     3754                    TSCDELTA_DBG_SYNC_MSG2(("sync/loop/master: #9 iTry=%u MyState=%#x\n", iTry, MySync.uSyncVar));
     3755                    break;
    36813756                }
    3682                 break;
    36833757            }
    36843758        }
     3759        if (fIsMaster)
     3760            pArgs->iTry = iTry;
    36853761    }
    36863762
     
    38583934                {
    38593935#if 0
    3860                     SUPR0Printf("mponpair ticks: %9llu %9llu  max: %9llu\n", pArgs->cElapsedMasterTscTicks,
    3861                                 pArgs->cElapsedWorkerTscTicks, pArgs->cMaxTscTicks);
     3936                    SUPR0Printf("mponpair ticks: %9llu %9llu  max: %9llu  iTry: %u%s\n", pArgs->cElapsedMasterTscTicks,
     3937                                pArgs->cElapsedWorkerTscTicks, pArgs->cMaxTscTicks, pArgs->iTry,
     3938                                pArgs->fTimedOut ? " timed out" :"");
    38623939#endif
    38633940#if 0
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