Changeset 54462 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Feb 24, 2015 5:54:23 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp
r54458 r54462 2610 2610 /** The time the master spent in the MP worker. */ 2611 2611 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; 2612 2616 /** Pointer to the master's synchronization struct (on stack). */ 2613 2617 PSUPTSCDELTASYNC2 volatile pSyncMaster; … … 2660 2664 # define TSCDELTA_DBG_CHECK_LOOP() ((void)0) 2661 2665 #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 2662 2681 2663 2682 2664 2683 static bool supdrvTscDeltaSync2_Before(PSUPTSCDELTASYNC2 pMySync, PSUPTSCDELTASYNC2 pOtherSync, 2665 bool fIsMaster, PRTCCUINTREG pfEFlags )2684 bool fIsMaster, PRTCCUINTREG pfEFlags, PSUPDRVGIPTSCDELTARGS pArgs) 2666 2685 { 2667 2686 uint32_t iMySeq = fIsMaster ? 0 : 256; … … 2682 2701 { /* likely*/ } 2683 2702 else 2703 { 2704 TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #1 uSyncVar=%#x\n", fIsMaster ? "master" : "worker", pOtherSync->uSyncVar)); 2684 2705 return false; 2706 } 2685 2707 } 2686 2708 … … 2695 2717 if (u32Tmp == GIP_TSC_DELTA_SYNC2_STEADY) 2696 2718 break; 2697 2698 2719 ASMSetFlags(fEFlags); 2699 2720 ASMNopPause(); … … 2701 2722 /* Abort? */ 2702 2723 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 } 2704 2728 2705 2729 /* Check for timeouts every so often (not every loop in case RDTSC is … … 2719 2743 if (ASMAtomicCmpXchgU32(&pMySync->uSyncVar, GIP_TSC_DELTA_SYNC2_TIMEOUT, GIP_TSC_DELTA_SYNC2_READY)) 2720 2744 { 2745 TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: timeout\n", fIsMaster ? "master" : "worker")); 2721 2746 ASMAtomicCmpXchgU32(&pOtherSync->uSyncVar, GIP_TSC_DELTA_SYNC2_TIMEOUT, GIP_TSC_DELTA_SYNC2_STEADY); 2747 ASMAtomicWriteBool(&pArgs->fTimedOut, true); 2722 2748 return false; 2723 2749 } … … 2743 2769 { 2744 2770 ASMSetFlags(fEFlags); 2771 TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #3 uSyncVar=%#x\n", fIsMaster ? "master" : "worker", pOtherSync->uSyncVar)); 2745 2772 return false; 2746 2773 } … … 2757 2784 { 2758 2785 ASMSetFlags(fEFlags); 2786 TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #4 uSyncVar=%#x\n", fIsMaster ? "master" : "worker", pOtherSync->uSyncVar)); 2759 2787 return false; 2760 2788 } … … 2775 2803 { 2776 2804 ASMSetFlags(fEFlags); 2805 TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #5 u32Tmp=%#x\n", fIsMaster ? "master" : "worker", u32Tmp)); 2777 2806 return false; 2778 2807 } … … 2792 2821 { 2793 2822 ASMSetFlags(fEFlags); 2823 TSCDELTA_DBG_SYNC_MSG(("sync/before/%s: #6 uSyncVar=%#x\n", fIsMaster ? "master" : "worker", pOtherSync->uSyncVar)); 2794 2824 return false; 2795 2825 } … … 2828 2858 } 2829 2859 2830 #define TSCDELTA_MASTER_SYNC_BEFORE(a_pMySync, a_pOtherSync, a_pfEFlags ) \2831 if (RT_LIKELY(supdrvTscDeltaSync2_Before(a_pMySync, a_pOtherSync, true /*f Master*/, 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))) \ 2832 2862 { /*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))) \ 2836 2870 { /*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 2878 static bool supdrvTscDeltaSync2_After(PSUPTSCDELTASYNC2 pMySync, PSUPTSCDELTASYNC2 pOtherSync, 2879 bool fIsMaster, RTCCUINTREG fEFlags) 2841 2880 { 2842 2881 TSCDELTA_DBG_VARS(); … … 2853 2892 { 2854 2893 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 */ ) 2856 2896 return true; 2857 2897 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)); 2859 2903 return false; /* shouldn't ever happen! */ 2904 } 2860 2905 TSCDELTA_DBG_CHECK_LOOP(); 2861 2906 ASMNopPause(); … … 2864 2909 2865 2910 #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))) \ 2867 2912 { /* 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) 2869 2918 2870 2919 #define TSCDELTA_MASTER_KICK_OTHER_OUT_OF_AFTER(a_pMySync, a_pOtherSync) \ … … 2874 2923 if (RT_LIKELY(ASMAtomicCmpXchgU32(&(a_pOtherSync)->uSyncVar, GIP_TSC_DELTA_SYNC2_READY, GIP_TSC_DELTA_SYNC2_GO))) \ 2875 2924 { /* 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) 2877 2930 2878 2931 #define TSCDELTA_OTHER_SYNC_AFTER(a_pMySync, a_pOtherSync, a_fEFlags) \ … … 2886 2939 { \ 2887 2940 ASMSetFlags(a_fEFlags); \ 2941 TSCDELTA_DBG_SYNC_MSG(("sync/after/other: #0 uSyncVar=%#x\n", (a_pOtherSync)->uSyncVar)); \ 2888 2942 break; \ 2889 2943 } \ 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))) \ 2891 2945 { /* 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) 2894 2952 /** @} */ 2895 2953 … … 2948 3006 ("%#llx idMaster=%#x idWorker=%#x (idGipMaster=%#x)\n", 2949 3007 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); 2951 3009 2952 3010 do … … 2986 3044 2987 3045 ASMAtomicReadU64(&pGipCpuMaster->u64TSCSample); /* Warm the cache line. */ 2988 TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags );3046 TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs); 2989 3047 2990 3048 /* … … 3025 3083 } 3026 3084 3085 TSCDELTA_DBG_SYNC_MSG9(("sync/method1loop/%s: #92 iLoop=%u MyState=%#x\n", fIsMaster ? "master" : "worker", iLoop, 3086 pMySync->uSyncVar)); 3087 3027 3088 /* 3028 3089 * We must reset the worker TSC sample value in case it gets picked as a … … 3065 3126 */ 3066 3127 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) 3068 3129 # define GIP_TSC_DELTA_M2_PRIMER_LOOPS 1 3069 3130 … … 3109 3170 if (cHits > 2) 3110 3171 pArgs->pWorker->i64TSCDelta = iBestDelta; 3111 pArgs->M2.cHits 3112 3113 #if 13172 pArgs->M2.cHits += cHits; 3173 3174 #if 0 /* This is pointless now with supdrvTscDeltaVerify(0). */ 3114 3175 /* 3115 3176 * Check and see if we can quit a little early. If the result is already … … 3244 3305 * Sync up with the worker and collect data. 3245 3306 */ 3246 TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags );3307 TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs); 3247 3308 supdrvTscDeltaMethod2CollectData(pArgs->M2.pMasterData, &pArgs->M2.pWorkerData->iCurSeqNo, pArgs->M2.fLagMaster); 3248 3309 TSCDELTA_MASTER_SYNC_AFTER(pMySync, pOtherSync, fEFlags); … … 3263 3324 * The worker. 3264 3325 */ 3265 TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags );3326 TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs); 3266 3327 supdrvTscDeltaMethod2CollectData(pArgs->M2.pWorkerData, &pArgs->M2.pMasterData->iCurSeqNo, pArgs->M2.fLagWorker); 3267 3328 TSCDELTA_OTHER_SYNC_AFTER(pMySync, pOtherSync, fEFlags); … … 3316 3377 PSUPTSCDELTASYNC2 pOtherSync, bool fIsMaster, int64_t iWorkerTscDelta) 3317 3378 { 3318 PSUPGIPCPU pGipCpuWorker = pArgs->pWorker;3379 /*PSUPGIPCPU pGipCpuWorker = pArgs->pWorker; - unused */ 3319 3380 PSUPGIPCPU pGipCpuMaster = pArgs->pMaster; 3320 3381 uint32_t i; … … 3330 3391 { 3331 3392 uint64_t uTscWorker; 3332 TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags );3393 TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs); 3333 3394 3334 3395 /* … … 3425 3486 * The worker, master leads. 3426 3487 */ 3427 TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags );3488 TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs); 3428 3489 3429 3490 for (i = 0; i < RT_ELEMENTS(pArgs->auVerifyWorkerTscs); i += 2) … … 3492 3553 ASMAtomicWriteNullPtr(ppMySync); 3493 3554 ASMAtomicWriteBool(&pArgs->fAbortSetup, true); 3555 if (fTimeout) 3556 ASMAtomicWriteBool(&pArgs->fTimedOut, true); 3494 3557 3495 3558 /* … … 3627 3690 { 3628 3691 ASMAtomicWriteS64(&pGipCpuWorker->i64TSCDelta, GIP_TSC_DELTA_INITIAL_MASTER_VALUE); 3629 RTCpuSetDelByIndex(&pDevExt->TscDeltaCpuSet, pGipCpuMaster->iCpuSet);3630 RTCpuSetAddByIndex(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuMaster->iCpuSet);3631 }3632 else3633 {3634 3692 RTCpuSetDelByIndex(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->iCpuSet); 3635 3693 RTCpuSetAddByIndex(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuWorker->iCpuSet); … … 3645 3703 for (iTry = 0; iTry < 12; iTry++) 3646 3704 { 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)); 3648 3713 break; 3714 } 3649 3715 3650 3716 /* … … 3658 3724 # error "huh??" 3659 3725 #endif 3660 if (ASMAtomicReadU32(&MySync.uSyncVar) != GIP_TSC_DELTA_SYNC2_READY)3661 break;3662 3726 3663 3727 /* 3664 * Success? If so, stop trying.3728 * Check the state. 3665 3729 */ 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 */ ) 3671 3733 { 3672 3734 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)); 3677 3736 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 3678 3751 { 3679 3752 RTCpuSetDelByIndex(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->iCpuSet); 3680 3753 RTCpuSetAddByIndex(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuWorker->iCpuSet); 3754 TSCDELTA_DBG_SYNC_MSG2(("sync/loop/master: #9 iTry=%u MyState=%#x\n", iTry, MySync.uSyncVar)); 3755 break; 3681 3756 } 3682 break;3683 3757 } 3684 3758 } 3759 if (fIsMaster) 3760 pArgs->iTry = iTry; 3685 3761 } 3686 3762 … … 3858 3934 { 3859 3935 #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" :""); 3862 3939 #endif 3863 3940 #if 0
Note:
See TracChangeset
for help on using the changeset viewer.