Changeset 54306 in vbox
- Timestamp:
- Feb 19, 2015 6:40:36 PM (10 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r54298 r54306 6041 6041 && rc != VERR_TIMEOUT) 6042 6042 return supdrvTscDeltaThreadButchered(pDevExt, false /* fSpinlockHeld */, "RTThreadUserWait", rc); 6043 RTThreadUserReset(pDevExt->hTscDeltaThread); 6043 6044 break; 6044 6045 } … … 6061 6062 if (!cTimesMeasured++) 6062 6063 { 6063 rc = supdrvMeasureTscDeltas(pDevExt, NULL /* pidxMaster */); 6064 RTCpuSetCopy(&pDevExt->TscDeltaObtainedCpuSet, &pDevExt->pGip->OnlineCpuSet); 6064 int cTries = 8; 6065 int cMsWaitPerTry = 10; 6066 do 6067 { 6068 rc = supdrvMeasureTscDeltas(pDevExt, NULL /* pidxMaster */); 6069 if ( RT_SUCCESS(rc) 6070 || ( RT_FAILURE(rc) 6071 && rc != VERR_TRY_AGAIN 6072 && rc != VERR_CPU_OFFLINE)) 6073 { 6074 break; 6075 } 6076 RTThreadSleep(cMsWaitPerTry); 6077 } while (cTries-- > 0); 6065 6078 } 6066 6079 else … … 6081 6094 { 6082 6095 rc |= supdrvMeasureTscDeltaOne(pDevExt, iCpu); 6083 RTCpuSetDel(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->idCpu);6084 if (pGipCpuWorker->i64TSCDelta != INT64_MAX)6085 RTCpuSetAdd(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuWorker->idCpu);6086 6096 } 6087 6097 } … … 6231 6241 if (RT_SUCCESS(rc)) 6232 6242 { 6233 pDevExt->enmTscDeltaThreadState 6243 pDevExt->enmTscDeltaThreadState = kTscDeltaThreadState_Creating; 6234 6244 pDevExt->cMsTscDeltaTimeout = 1; 6235 RTCpuSetEmpty(&pDevExt->TscDeltaCpuSet);6236 RTCpuSetEmpty(&pDevExt->TscDeltaObtainedCpuSet);6237 6245 rc = RTThreadCreate(&pDevExt->hTscDeltaThread, supdrvTscDeltaThread, pDevExt, 0 /* cbStack */, 6238 6246 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VBoxTscThread"); … … 6314 6322 return VERR_THREAD_NOT_WAITABLE; 6315 6323 6316 cMsTotalWait = RT_MIN(pGip->cPresentCpus + 2, 150);6324 cMsTotalWait = RT_MIN(pGip->cPresentCpus + 10, 200); 6317 6325 while (cTriesLeft-- > 0) 6318 6326 { … … 6733 6741 } 6734 6742 6743 RTCpuSetEmpty(&pDevExt->TscDeltaCpuSet); 6744 RTCpuSetEmpty(&pDevExt->TscDeltaObtainedCpuSet); 6735 6745 #ifdef SUPDRV_USE_TSC_DELTA_THREAD 6736 6746 if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED) … … 6759 6769 { 6760 6770 rc = supdrvMeasureTscDeltas(pDevExt, NULL /* pidxMaster */); 6761 if (rc != VERR_TRY_AGAIN) 6771 if ( rc != VERR_TRY_AGAIN 6772 && rc != VERR_CPU_OFFLINE) 6762 6773 break; 6763 6774 } while (--cTries > 0); … … 6943 6954 6944 6955 ASMSetFlags(uFlags); 6956 6957 #ifdef SUPDRV_USE_TSC_DELTA_THREAD 6958 if ( pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED 6959 && !RTCpuSetIsEmpty(&pDevExt->TscDeltaCpuSet)) 6960 { 6961 RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock); 6962 if ( pDevExt->enmTscDeltaThreadState == kTscDeltaThreadState_Listening 6963 || pDevExt->enmTscDeltaThreadState == kTscDeltaThreadState_Measuring) 6964 pDevExt->enmTscDeltaThreadState = kTscDeltaThreadState_WaitAndMeasure; 6965 RTSpinlockRelease(pDevExt->hTscDeltaSpinlock); 6966 /** @todo Do the actual poking using -- RTThreadUserSignal() */ 6967 } 6968 #endif 6945 6969 } 6946 6970 … … 7063 7087 ASMAtomicIncU32(&pDevExt->cMpOnOffEvents); 7064 7088 7089 /* Add this CPU to the set of CPUs for which we need to calculate their TSC-deltas. */ 7090 if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED) 7091 { 7092 RTCpuSetAdd(&pDevExt->TscDeltaCpuSet, idCpu); 7065 7093 #ifdef SUPDRV_USE_TSC_DELTA_THREAD 7066 /*7067 * Add this CPU to the set of CPUs that require their TSC delta to be measured.7068 *7069 * We cannot poke the TSC-delta measurement thread from this context (on all OSs), so we only7070 * update the state and it'll get serviced when the thread's listening interval times out.7071 */7072 if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED)7073 {7074 7094 RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock); 7075 RTCpuSetAdd(&pDevExt->TscDeltaCpuSet, idCpu);7076 7095 if ( pDevExt->enmTscDeltaThreadState == kTscDeltaThreadState_Listening 7077 7096 || pDevExt->enmTscDeltaThreadState == kTscDeltaThreadState_Measuring) … … 7080 7099 } 7081 7100 RTSpinlockRelease(pDevExt->hTscDeltaSpinlock); 7082 }7083 7101 #endif 7102 } 7084 7103 7085 7104 /* commit it */ … … 7128 7147 } 7129 7148 7130 /* Reset the TSC delta, we will recalculate it lazily. */7131 7149 if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED) 7132 7150 { 7151 /* Reset the TSC delta, we will recalculate it lazily. */ 7133 7152 ASMAtomicWriteS64(&pGip->aCPUs[i].i64TSCDelta, INT64_MAX); 7134 #ifdef SUPDRV_USE_TSC_DELTA_THREAD7135 7153 /* Remove this CPU from the set of CPUs that we have obtained the TSC deltas. */ 7136 7154 RTCpuSetDel(&pDevExt->TscDeltaObtainedCpuSet, idCpu); 7137 #endif7138 7155 } 7139 7156 … … 7439 7456 7440 7457 if (pGipCpuWorker->i64TSCDelta != INT64_MAX) 7458 { 7459 if (idCpu == idMaster) 7460 { 7461 RTCpuSetDel(&pDevExt->TscDeltaCpuSet, pGipCpuMaster->idCpu); 7462 RTCpuSetAdd(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuMaster->idCpu); 7463 } 7464 else 7465 { 7466 RTCpuSetDel(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->idCpu); 7467 RTCpuSetAdd(&pDevExt->TscDeltaObtainedCpuSet, pGipCpuWorker->idCpu); 7468 } 7441 7469 break; 7470 } 7442 7471 } 7443 7472 } … … 7616 7645 PSUPGIPCPU pGipCpuWorker = &pGip->aCPUs[iCpu]; 7617 7646 if ( iCpu != idxMaster 7618 && RTCpuSetIsMember(&p Gip->OnlineCpuSet, pGipCpuWorker->idCpu))7647 && RTCpuSetIsMember(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->idCpu)) 7619 7648 { 7620 7649 rc = supdrvMeasureTscDeltaOne(pDevExt, iCpu); … … 7628 7657 if (ASMAtomicReadU32(&pDevExt->cMpOnOffEvents) != cMpOnOffEvents) 7629 7658 { 7630 SUPR0Printf("One or more CPUs transitioned between online & offline states. I'm confused, retry ing...\n");7659 SUPR0Printf("One or more CPUs transitioned between online & offline states. I'm confused, retry...\n"); 7631 7660 rc = VERR_TRY_AGAIN; 7632 7661 break; … … 8065 8094 } 8066 8095 8067 8068 8096 /* 8069 8097 * TSC History. -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r54301 r54306 231 231 #endif 232 232 233 #if 0233 #if 1 234 234 /** Use a dedicated kernel thread to service TSC-delta measurement requests. 235 235 * @todo Test on servers with many CPUs and sockets. */ … … 712 712 /** Aligned pointer to the TSC delta sync. struct. */ 713 713 PSUPTSCDELTASYNC pTscDeltaSync; 714 /** The set of CPUs we need to take measurements for. */ 715 RTCPUSET TscDeltaCpuSet; 716 /** The set of CPUs we have completed taken measurements for. */ 717 RTCPUSET TscDeltaObtainedCpuSet; 714 718 /** @} */ 715 719 … … 727 731 /** Thread timeout time before rechecking state in ms. */ 728 732 RTMSINTERVAL cMsTscDeltaTimeout; 729 /** The set of CPUs we need to take measurements for. */730 RTCPUSET TscDeltaCpuSet;731 /** The set of CPUs we have completed taken measurements for. */732 RTCPUSET TscDeltaObtainedCpuSet;733 733 /** Whether the TSC-delta measurement was successful. */ 734 734 int32_t volatile rcTscDelta; -
trunk/src/VBox/HostDrivers/Support/testcase/tstSupTscDelta.cpp
r54288 r54306 165 165 if (pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE) 166 166 { 167 rc = SUPR3TscDeltaMeasure(pGip->aCPUs[iCpu].idCpu, false /*fAsync*/, true /*fForce*/, 167 rc = SUPR3TscDeltaMeasure(pGip->aCPUs[iCpu].idCpu, false /*fAsync*/, true /*fForce*/, 64, 16 /*ms*/); 168 168 if (RT_FAILURE(rc)) 169 169 RTTestFailed(hTest, "SUPR3TscDeltaMeasure failed on %#x: %Rrc", pGip->aCPUs[iCpu].idCpu, rc);
Note:
See TracChangeset
for help on using the changeset viewer.