Changeset 32489 in vbox
- Timestamp:
- Sep 14, 2010 3:50:31 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/gvmm.h
r30237 r32489 148 148 GVMMR0DECL(int) GVMMR0SchedWakeUpAndPokeCpus(PVM pVM, PCVMCPUSET pSleepSet, PCVMCPUSET pPokeSet); 149 149 GVMMR0DECL(int) GVMMR0SchedPoll(PVM pVM, VMCPUID idCpu, bool fYield); 150 GVMMR0DECL(void) GVMMR0SchedUpdatePeriodicPreemptionTimer(PVM pVM, RTCPUID idHostCpu, uint32_t uHz); 150 151 GVMMR0DECL(int) GVMMR0QueryStatistics(PGVMMSTATS pStats, PSUPDRVSESSION pSession, PVM pVM); 151 152 GVMMR0DECL(int) GVMMR0ResetStatistics(PCGVMMSTATS pStats, PSUPDRVSESSION pSession, PVM pVM); -
trunk/include/VBox/hwaccm.h
r30241 r32489 139 139 VMMR3DECL(int) HWACCMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 140 140 VMMR3DECL(bool) HWACCMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx); 141 VMMR3DECL(bool) HWACCMR3IsVmxPreemptionTimerUsed(PVM pVM); 141 142 142 143 /** @} */ -
trunk/include/VBox/tm.h
r32484 r32489 92 92 #endif 93 93 VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM); 94 VMM_INT_DECL(uint32_t) TMCalcHostTimerFrequency(PVM pVM, PVMCPU pVCpu); 94 95 #ifdef IN_RING3 95 96 VMMR3DECL(int) TMR3GetCpuLoadTimes(PVM pVM, VMCPUID idCpu, uint64_t *pcNsTotal, uint64_t *pcNsExecuting, -
trunk/src/VBox/VMM/HWACCM.cpp
r32378 r32489 2436 2436 2437 2437 /** 2438 * Checks if the VMX-preemption timer is being used. 2439 * 2440 * @returns true if it is, false if it isn't. 2441 * @param pVM The VM handle. 2442 */ 2443 VMMR3DECL(bool) HWACCMR3IsVmxPreemptionTimerUsed(PVM pVM) 2444 { 2445 return HWACCMIsEnabled(pVM) 2446 && pVM->hwaccm.s.vmx.fEnabled 2447 && pVM->hwaccm.s.vmx.fUsePreemptTimer; 2448 } 2449 2450 /** 2438 2451 * Restart an I/O instruction that was refused in ring-0 2439 2452 * -
trunk/src/VBox/VMM/VMM.cpp
r32140 r32489 141 141 pVM->vmm.s.hEvtMulRendezvousDone = NIL_RTSEMEVENTMULTI; 142 142 pVM->vmm.s.hEvtRendezvousDoneCaller = NIL_RTSEMEVENT; 143 int rc = CFGMR3QueryU32(CFGMR3GetRoot(pVM), "YieldEMTInterval", &pVM->vmm.s.cYieldEveryMillies); 144 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 145 pVM->vmm.s.cYieldEveryMillies = 23; /* Value arrived at after experimenting with the grub boot prompt. */ 146 //pVM->vmm.s.cYieldEveryMillies = 8; //debugging 147 else 148 AssertMsgRCReturn(rc, ("Configuration error. Failed to query \"YieldEMTInterval\", rc=%Rrc\n", rc), rc); 143 144 /** @cfgm{YieldEMTInterval, uint32_t, 1, UINT32_MAX, 23, ms} 145 * The EMT yield interval. The EMT yielding is a hack we employ to play a 146 * bit nicer with the rest of the system (like for instance the GUI). 147 */ 148 int rc = CFGMR3QueryU32Def(CFGMR3GetRoot(pVM), "YieldEMTInterval", &pVM->vmm.s.cYieldEveryMillies, 149 23 /* Value arrived at after experimenting with the grub boot prompt. */); 150 AssertMsgRCReturn(rc, ("Configuration error. Failed to query \"YieldEMTInterval\", rc=%Rrc\n", rc), rc); 151 152 153 /** @cfgm{VMM/UsePeriodicPreemptionTimers, boolean, true} 154 * Controls whether we employ per-cpu preemption timers to limit the time 155 * spent executing guest code. This option is not available on all 156 * platforms and we will silently ignore this setting then. If we are 157 * running in VT-x mode, we will use the VMX-preemption timer instead of 158 * this one when possible. 159 */ 160 PCFGMNODE pCfgVMM = CFGMR3GetChild(CFGMR3GetRoot(pVM), "VMM"); 161 rc = CFGMR3QueryBoolDef(pCfgVMM, "UsePeriodicPreemptionTimers", &pVM->vmm.s.fUsePeriodicPreemptionTimers, true); 162 AssertMsgRCReturn(rc, ("Configuration error. Failed to query \"VMM/UsePeriodicPreemptionTimers\", rc=%Rrc\n", rc), rc); 149 163 150 164 /* … … 493 507 #endif 494 508 509 /* 510 * Disable the periodic preemption timers if we can use the VMX-preemption 511 * timer instead. 512 */ 513 if ( pVM->vmm.s.fUsePeriodicPreemptionTimers 514 && HWACCMR3IsVmxPreemptionTimerUsed(pVM)) 515 pVM->vmm.s.fUsePeriodicPreemptionTimers = false; 516 LogRel(("VMM: fUsePeriodicPreemptionTimers=%RTbool\n", pVM->vmm.s.fUsePeriodicPreemptionTimers)); 517 495 518 return VINF_SUCCESS; 496 519 } -
trunk/src/VBox/VMM/VMMAll/TMAll.cpp
r32484 r32489 2275 2275 * @param pVM The VM handle. 2276 2276 */ 2277 VMMDECL(uint32_t) TMGetFrequencyHint(PVM pVM)2277 static uint32_t tmGetFrequencyHint(PVM pVM) 2278 2278 { 2279 2279 /* … … 2326 2326 } 2327 2327 ASMAtomicWriteU32(&pVM->tm.s.uMaxHzHint, uMaxHzHint); 2328 Log((" TMGetFrequencyHint: New value %u Hz\n", uMaxHzHint));2328 Log(("tmGetFrequencyHint: New value %u Hz\n", uMaxHzHint)); 2329 2329 tmTimerUnlock(pVM); 2330 2330 } … … 2332 2332 return uMaxHzHint; 2333 2333 } 2334 2335 2336 /** 2337 * Calculates a host timer frequency that would be suitable for the current 2338 * timer load. 2339 * 2340 * This will take the highest timer frequency, adjust for catch-up and warp 2341 * driver, and finally add a little fudge factor. The caller (VMM) will use 2342 * the result to adjust the per-cpu preemption timer. 2343 * 2344 * @returns The highest frequency. 0 if no important timers around. 2345 * @param pVM The VM handle. 2346 * @param pVCpu The current CPU. 2347 */ 2348 VMM_INT_DECL(uint32_t) TMCalcHostTimerFrequency(PVM pVM, PVMCPU pVCpu) 2349 { 2350 uint32_t uHz = tmGetFrequencyHint(pVM); 2351 2352 /* Catch up. */ 2353 if (ASMAtomicUoReadBool(&pVM->tm.s.fVirtualSyncCatchUp)) 2354 { 2355 uint32_t u32Pct = ASMAtomicReadU32(&pVM->tm.s.u32VirtualSyncCatchUpPercentage); 2356 if (ASMAtomicReadBool(&pVM->tm.s.fVirtualSyncCatchUp)) 2357 { 2358 uHz *= u32Pct + 100; 2359 uHz /= 100; 2360 } 2361 } 2362 2363 /* Warp drive */ 2364 if (ASMAtomicUoReadBool(&pVM->tm.s.fVirtualWarpDrive)) 2365 { 2366 uint32_t u32Pct = ASMAtomicReadU32(&pVM->tm.s.u32VirtualWarpDrivePercentage); 2367 if (ASMAtomicReadBool(&pVM->tm.s.fVirtualWarpDrive)) 2368 { 2369 uHz *= u32Pct; 2370 uHz /= 100; 2371 } 2372 } 2373 2374 /* Fudge factor. */ 2375 /** @todo make this configurable. */ 2376 uHz *= 110 + pVCpu->idCpu == pVM->tm.s.idTimerCpu; 2377 uHz /= 100; 2378 2379 return uHz; 2380 } -
trunk/src/VBox/VMM/VMMInternal.h
r29902 r32489 262 262 /** Whether log flushing has been disabled or not. */ 263 263 bool fRCLoggerFlushingDisabled; 264 bool afAlignment[ 6]; /**< Alignment padding. */264 bool afAlignment[5]; /**< Alignment padding. */ 265 265 /** @} */ 266 266 267 267 /** Whether the stack guard pages have been stationed or not. */ 268 268 bool fStackGuardsStationed; 269 /** Whether we should use the periodic preemption timers. */ 270 bool fUsePeriodicPreemptionTimers; 269 271 270 272 /** The EMT yield timer. */ -
trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
r31407 r32489 1888 1888 1889 1889 /** 1890 * Updates the periodic preemption timer for the calling CPU. 1891 * 1892 * The caller must have disabled preemption! 1893 * 1894 * @param pVM The VM handle. 1895 * @param idHostCpu The current host CPU id. 1896 * @param uHz The desired frequency. 1897 */ 1898 GVMMR0DECL(void) GVMMR0SchedUpdatePeriodicPreemptionTimer(PVM pVM, RTCPUID idHostCpu, uint32_t uHz) 1899 { 1900 1901 } 1902 1903 1904 /** 1890 1905 * Retrieves the GVMM statistics visible to the caller. 1891 1906 * -
trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
r32361 r32489 1435 1435 VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled) 1436 1436 { 1437 Assert(!(ASMGetFlags() & X86_EFL_IF) );1437 Assert(!(ASMGetFlags() & X86_EFL_IF) || !RTThreadPreemptIsEnabled(NIL_RTTHREAD)); 1438 1438 1439 1439 *pfVTxDisabled = false; -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r32431 r32489 530 530 case VMMR0_DO_RAW_RUN: 531 531 { 532 /* Safety precaution as hwaccm disables the switcher. */ 533 if (RT_LIKELY(!pVM->vmm.s.fSwitcherDisabled)) 532 /* Some safety precautions first. */ 533 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 534 if (RT_LIKELY( !pVM->vmm.s.fSwitcherDisabled /* hwaccm */ 535 && pVM->cCpus == 1 /* !smp */ 536 && PGMGetHyperCR3(pVCpu))) 537 #else 538 if (RT_LIKELY( !pVM->vmm.s.fSwitcherDisabled 539 && pVM->cCpus == 1)) 540 #endif 534 541 { 535 RTCCUINTREG uFlags = ASMIntDisableFlags(); 536 int rc; 537 bool fVTxDisabled; 538 539 if (RT_UNLIKELY(pVM->cCpus > 1)) 542 /* Disable preemption and update the periodic preemption timer. */ 543 RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER; 544 RTThreadPreemptDisable(&PreemptState); 545 ASMAtomicWriteU32(&pVCpu->idHostCpu, RTMpCpuId()); 546 if (pVM->vmm.s.fUsePeriodicPreemptionTimers) 547 GVMMR0SchedUpdatePeriodicPreemptionTimer(pVM, pVCpu->idHostCpu, TMCalcHostTimerFrequency(pVM, pVCpu)); 548 549 /* We might need to disable VT-x if the active switcher turns off paging. */ 550 bool fVTxDisabled; 551 int rc = HWACCMR0EnterSwitcher(pVM, &fVTxDisabled); 552 if (RT_SUCCESS(rc)) 540 553 { 541 pVCpu->vmm.s.iLastGZRc = VERR_RAW_MODE_INVALID_SMP; 554 RTCCUINTREG uFlags = ASMIntDisableFlags(); 555 VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC); 556 557 TMNotifyStartOfExecution(pVCpu); 558 rc = pVM->vmm.s.pfnHostToGuestR0(pVM); 559 pVCpu->vmm.s.iLastGZRc = rc; 560 TMNotifyEndOfExecution(pVCpu); 561 562 VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED); 563 564 /* Re-enable VT-x if previously turned off. */ 565 HWACCMR0LeaveSwitcher(pVM, fVTxDisabled); 566 567 if ( rc == VINF_EM_RAW_INTERRUPT 568 || rc == VINF_EM_RAW_INTERRUPT_HYPER) 569 TRPMR0DispatchHostInterrupt(pVM); 570 542 571 ASMSetFlags(uFlags); 543 return; 572 573 #ifdef VBOX_WITH_STATISTICS 574 STAM_COUNTER_INC(&pVM->vmm.s.StatRunRC); 575 vmmR0RecordRC(pVM, pVCpu, rc); 576 #endif 544 577 } 545 546 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 547 if (RT_UNLIKELY(!PGMGetHyperCR3(pVCpu))) 548 { 549 pVCpu->vmm.s.iLastGZRc = VERR_PGM_NO_CR3_SHADOW_ROOT; 550 ASMSetFlags(uFlags); 551 return; 552 } 553 #endif 554 555 /* We might need to disable VT-x if the active switcher turns off paging. */ 556 rc = HWACCMR0EnterSwitcher(pVM, &fVTxDisabled); 557 if (RT_FAILURE(rc)) 558 { 578 else 559 579 pVCpu->vmm.s.iLastGZRc = rc; 560 ASMSetFlags(uFlags);561 return;562 }563 564 ASMAtomicWriteU32(&pVCpu->idHostCpu, RTMpCpuId());565 VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC);566 567 TMNotifyStartOfExecution(pVCpu);568 rc = pVM->vmm.s.pfnHostToGuestR0(pVM);569 pVCpu->vmm.s.iLastGZRc = rc;570 TMNotifyEndOfExecution(pVCpu);571 572 VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);573 580 ASMAtomicWriteU32(&pVCpu->idHostCpu, NIL_RTCPUID); 574 575 /* Re-enable VT-x if previously turned off. */ 576 HWACCMR0LeaveSwitcher(pVM, fVTxDisabled); 577 578 if ( rc == VINF_EM_RAW_INTERRUPT 579 || rc == VINF_EM_RAW_INTERRUPT_HYPER) 580 TRPMR0DispatchHostInterrupt(pVM); 581 582 ASMSetFlags(uFlags); 583 584 #ifdef VBOX_WITH_STATISTICS 585 STAM_COUNTER_INC(&pVM->vmm.s.StatRunRC); 586 vmmR0RecordRC(pVM, pVCpu, rc); 587 #endif 581 RTThreadPreemptRestore(&PreemptState); 588 582 } 589 583 else … … 591 585 Assert(!pVM->vmm.s.fSwitcherDisabled); 592 586 pVCpu->vmm.s.iLastGZRc = VERR_NOT_SUPPORTED; 587 if (pVM->cCpus != 1) 588 pVCpu->vmm.s.iLastGZRc = VERR_RAW_MODE_INVALID_SMP; 589 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 590 if (!PGMGetHyperCR3(pVCpu)) 591 pVCpu->vmm.s.iLastGZRc = VERR_PGM_NO_CR3_SHADOW_ROOT; 592 #endif 593 593 } 594 594 break; … … 604 604 case VMMR0_DO_HWACC_RUN: 605 605 { 606 int rc;607 608 STAM_COUNTER_INC(&pVM->vmm.s.StatRunRC);609 610 606 #ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION 611 607 RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER; … … 615 611 #endif 616 612 ASMAtomicWriteU32(&pVCpu->idHostCpu, RTMpCpuId()); 613 if (pVM->vmm.s.fUsePeriodicPreemptionTimers) 614 GVMMR0SchedUpdatePeriodicPreemptionTimer(pVM, pVCpu->idHostCpu, TMCalcHostTimerFrequency(pVM, pVCpu)); 617 615 618 616 #ifdef LOG_ENABLED … … 629 627 } 630 628 #endif 629 int rc; 631 630 if (!HWACCMR0SuspendPending()) 632 631 { … … 638 637 AssertRC(rc2); 639 638 } 639 STAM_COUNTER_INC(&pVM->vmm.s.StatRunRC); 640 640 } 641 641 else -
trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp
r32484 r32489 992 992 GEN_CHECK_OFF(VMM, fRCLoggerFlushingDisabled); 993 993 GEN_CHECK_OFF(VMM, fStackGuardsStationed); 994 GEN_CHECK_OFF(VMM, fUsePeriodicPreemptionTimers); 994 995 GEN_CHECK_OFF(VMM, pYieldTimer); 995 996 GEN_CHECK_OFF(VMM, cYieldResumeMillies);
Note:
See TracChangeset
for help on using the changeset viewer.