Changeset 53396 in vbox for trunk/src/VBox
- Timestamp:
- Nov 25, 2014 3:01:59 PM (10 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r53369 r53396 206 206 static volatile uint32_t g_cMpOnOffEvents; 207 207 /** TSC reading during start of TSC frequency refinement phase. */ 208 uint64_tg_u64TSCAnchor;208 static uint64_t g_u64TSCAnchor; 209 209 /** Timestamp (in nanosec) during start of TSC frequency refinement phase. */ 210 uint64_t g_u64NanoTSAnchor; 210 static uint64_t g_u64NanoTSAnchor; 211 /** Whether the host OS has already normalized the hardware TSC deltas across 212 * CPUs. */ 213 static bool g_fOsTscDeltasInSync; 211 214 212 215 /** … … 5855 5858 static int supdrvTscDeltaInit(PSUPDRVDEVEXT pDevExt) 5856 5859 { 5860 Assert(!g_fOsTscDeltasInSync); 5857 5861 int rc = RTSpinlockCreate(&pDevExt->hTscDeltaSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "VBoxTscSpnLck"); 5858 5862 if (RT_SUCCESS(rc)) … … 6067 6071 cCpus = RTMpGetArraySize(); 6068 6072 if ( cCpus > RTCPUSET_MAX_CPUS 6069 || cCpus > 256 /* ApicId is used for the mappings*/)6073 || cCpus > 256 /* ApicId is used for the mappings */) 6070 6074 { 6071 6075 SUPR0Printf("VBoxDrv: Too many CPUs (%u) for the GIP (max %u)\n", cCpus, RT_MIN(RTCPUSET_MAX_CPUS, 256)); … … 6099 6103 supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), RT_NS_1SEC / u32Interval /*=Hz*/, u32Interval, cCpus); 6100 6104 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 6101 6113 #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 } 6104 6119 #endif 6105 6120 if (RT_SUCCESS(rc)) … … 6112 6127 { 6113 6128 #ifndef SUPDRV_USE_TSC_DELTA_THREAD 6114 /*6115 * Measure the TSC deltas now that we have MP notifications.6116 */6117 int cTries = 5;6118 6129 uint16_t iCpu; 6119 do6130 if (!g_fOsTscDeltasInSync) 6120 6131 { 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 } 6127 6150 #endif 6128 6129 rc = supdrvGipMeasureTscFreq(pGip);6130 6151 if (RT_SUCCESS(rc)) 6131 6152 { 6132 if (supdrvIsInvariantTsc()) 6153 rc = supdrvGipMeasureTscFreq(pGip); 6154 if (RT_SUCCESS(rc)) 6133 6155 { 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) 6146 6164 { 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); 6149 6188 } 6150 6189 } 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 }6162 6190 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)); 6167 6192 } 6193 else 6194 OSDBGPRINT(("supdrvGipCreate: supdrvMeasureTscDeltas failed. rc=%Rrc\n", rc)); 6168 6195 } 6169 6196 else … … 6333 6360 pGip->u64CpuHz = (u64TSC - g_u64TSCAnchor) / (u64DeltaNanoTS / RT_NS_1SEC); 6334 6361 6335 for (iCpu = 0; iCpu < pGip->cCpus; iCpu++) 6336 pGip->aCPUs[iCpu].u64CpuHz = pGip->u64CpuHz; 6362 pGip->aCPUs[0].u64CpuHz = pGip->u64CpuHz; 6337 6363 g_u64TSCAnchor = 0; 6338 6364 } … … 6465 6491 * update the state and it'll get serviced when the thread's listening interval times out. 6466 6492 */ 6467 if (supdrvIsInvariantTsc()) 6493 if ( !g_fOsTscDeltasInSync 6494 && supdrvIsInvariantTsc()) 6468 6495 { 6469 6496 RTCpuSetAdd(&pDevExt->TscDeltaCpuSet, idCpu); … … 6523 6550 } 6524 6551 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); 6527 6555 6528 6556 /* commit it */ … … 6706 6734 if (!RTMpOnAllIsConcurrentSafe()) 6707 6735 { 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. */ 6708 6739 uint64_t uTscNow; 6709 6740 uint64_t uTscStart; … … 6896 6927 AssertReturn(pDevExt, VERR_INVALID_PARAMETER); 6897 6928 AssertReturn(pDevExt->pGip, VERR_INVALID_PARAMETER); 6929 Assert(!g_fOsTscDeltasInSync); 6898 6930 6899 6931 pGip = pDevExt->pGip; … … 6960 6992 uint32_t cOnlineCpus = pGip->cOnlineCpus; 6961 6993 6994 Assert(!g_fOsTscDeltasInSync); 6995 6962 6996 /* 6963 6997 * If we determined the TSC is async., don't bother with measuring deltas. … … 7056 7090 * case we have to choose the asynchronous timer mode. 7057 7091 * 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). 7059 7094 * @return false if the time stamp counters appear to be synchronized, true otherwise. 7060 7095 */ … … 7116 7151 } 7117 7152 7118 *poffMin = offMin; /* Almost RTMpOnSpecific profiling. */ 7153 if (poffMin) 7154 *poffMin = offMin; /* Almost RTMpOnSpecific profiling. */ 7119 7155 Log(("supdrvDetermineAsyncTsc: returns %d; iEndCpu=%d rc=%d offMin=%llx offMax=%llx\n", 7120 7156 fAsync, iEndCpu, rc, offMin, offMax)); … … 7200 7236 pCpu->u64TSC = ASMReadTSC(); 7201 7237 pCpu->u64TSCSample = GIP_TSC_DELTA_RSVD; 7202 pCpu->i64TSCDelta = INT64_MAX;7238 pCpu->i64TSCDelta = g_fOsTscDeltasInSync ? 0 : INT64_MAX; 7203 7239 7204 7240 ASMAtomicWriteSize(&pCpu->enmState, SUPGIPCPUSTATE_INVALID); … … 7247 7283 LogFlow(("supdrvGipInit: pGip=%p HCPhys=%lx u64NanoTS=%llu uUpdateHz=%d cCpus=%u\n", pGip, (long)HCPhys, u64NanoTS, uUpdateHz, cCpus)); 7248 7284 #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(); 7249 7291 7250 7292 /* … … 7642 7684 return VERR_INVALID_CPU_ID; 7643 7685 7686 if (g_fOsTscDeltasInSync) 7687 return VINF_SUCCESS; 7688 7644 7689 cTries = RT_MAX(pReq->u.In.cRetries + 1, 10); 7645 7690 cMsWaitRetry = RT_MAX(pReq->u.In.cMsWaitRetry, 5); … … 7737 7782 AssertMsgReturn(iCpu < pGip->cCpus, ("iCpu=%u cCpus=%u\n", iCpu, pGip->cCpus), VERR_INVALID_CPU_INDEX); 7738 7783 7784 Assert(!g_fOsTscDeltasInSync); 7739 7785 rc2 = supdrvMeasureTscDeltaOne(pDevExt, iCpu); 7740 7786 if (RT_SUCCESS(rc2)) -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r53054 r53396 751 751 bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc); 752 752 bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt); 753 bool VBOXCALL supdrvOSAreTscDeltasInSync(void); 753 754 int VBOXCALL supdrvOSEnableVTx(bool fEnabled); 754 755 bool VBOXCALL supdrvOSSuspendVTxOnCpu(void); -
trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
r52618 r53396 954 954 955 955 956 bool VBOXCALL supdrvOSAreTscDeltasInSync(void) 957 { 958 return false; 959 } 960 956 961 void VBOXCALL supdrvOSLdrNotifyOpened(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage) 957 962 { -
trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
r52576 r53396 540 540 541 541 542 bool VBOXCALL supdrvOSAreTscDeltasInSync(void) 543 { 544 return false; 545 } 546 547 542 548 int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename) 543 549 { -
trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
r53339 r53396 867 867 868 868 869 bool VBOXCALL supdrvOSAreTscDeltasInSync(void) 870 { 871 return false; 872 } 873 874 869 875 int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename) 870 876 { -
trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
r52618 r53396 407 407 408 408 409 bool VBOXCALL supdrvOSAreTscDeltasInSync(void) 410 { 411 NOREF(pDevExt); 412 return false; 413 } 414 415 409 416 int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename) 410 417 { -
trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
r53269 r53396 964 964 } 965 965 966 967 bool VBOXCALL supdrvOSAreTscDeltasInSync(void) 968 { 969 return false; 970 } 971 972 966 973 #if defined(VBOX_WITH_NATIVE_SOLARIS_LOADING) \ 967 974 && !defined(VBOX_WITHOUT_NATIVE_R0_LOADER) -
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r53329 r53396 1655 1655 1656 1656 1657 /** 1658 * Whether the hardware TSC has been synchronized by the OS. 1659 */ 1660 bool VBOXCALL supdrvOSAreTscDeltasInSync(void) 1661 { 1662 /* Windows writes back the hardware TSC registers to adjust for inter-CPU deltas. */ 1663 return true; 1664 } 1665 1666 1657 1667 #define MY_SystemLoadGdiDriverInSystemSpaceInformation 54 1658 1668 #define MY_SystemUnloadGdiDriverInformation 27
Note:
See TracChangeset
for help on using the changeset viewer.