VirtualBox

Changeset 88344 in vbox for trunk


Ignore:
Timestamp:
Apr 1, 2021 11:25:37 AM (4 years ago)
Author:
vboxsync
Message:

Forward ported r143567 from 6.1: vmmR0DoHalt fix - need to re-check FFs after changing the state. oem2ticketref:40

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r88330 r88344  
    826826                    }
    827827
    828                     /* Block.  We have to set the state to VMCPUSTATE_STARTED_HALTED here so ring-3
    829                        knows when to notify us (cannot access VMINTUSERPERVMCPU::fWait from here). */
    830                     VMCPU_CMPXCHG_STATE(pGVCpu, VMCPUSTATE_STARTED_HALTED, VMCPUSTATE_STARTED);
    831                     uint64_t const u64StartSchedHalt   = RTTimeNanoTS();
    832                     int rc = GVMMR0SchedHalt(pGVM, pGVCpu, u64GipTime);
    833                     uint64_t const u64EndSchedHalt     = RTTimeNanoTS();
    834                     uint64_t const cNsElapsedSchedHalt = u64EndSchedHalt - u64StartSchedHalt;
    835                     VMCPU_CMPXCHG_STATE(pGVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_HALTED);
    836                     STAM_REL_PROFILE_ADD_PERIOD(&pGVCpu->vmm.s.StatR0HaltBlock, cNsElapsedSchedHalt);
    837                     if (   rc == VINF_SUCCESS
    838                         || rc == VERR_INTERRUPTED)
    839 
     828                    /*
     829                     * We have to set the state to VMCPUSTATE_STARTED_HALTED here so ring-3
     830                     * knows when to notify us (cannot access VMINTUSERPERVMCPU::fWait from here).
     831                     * After changing the state we must recheck the force flags of course.
     832                     */
     833                    if (VMCPU_CMPXCHG_STATE(pGVCpu, VMCPUSTATE_STARTED_HALTED, VMCPUSTATE_STARTED))
    840834                    {
    841                         /* Keep some stats like ring-3 does. */
    842                         int64_t const cNsOverslept = u64EndSchedHalt - u64GipTime;
    843                         if (cNsOverslept > 50000)
    844                             STAM_REL_PROFILE_ADD_PERIOD(&pGVCpu->vmm.s.StatR0HaltBlockOverslept, cNsOverslept);
    845                         else if (cNsOverslept < -50000)
    846                             STAM_REL_PROFILE_ADD_PERIOD(&pGVCpu->vmm.s.StatR0HaltBlockInsomnia,  cNsElapsedSchedHalt);
    847                         else
    848                             STAM_REL_PROFILE_ADD_PERIOD(&pGVCpu->vmm.s.StatR0HaltBlockOnTime,    cNsElapsedSchedHalt);
    849 
    850                         /*
    851                          * Recheck whether we can resume execution or have to go to ring-3.
    852                          */
    853835                        if (   !VM_FF_IS_ANY_SET(pGVM, fVmFFs)
    854836                            && !VMCPU_FF_IS_ANY_SET(pGVCpu, fCpuFFs))
     
    856838                            if (VMCPU_FF_TEST_AND_CLEAR(pGVCpu, VMCPU_FF_UPDATE_APIC))
    857839                                APICUpdatePendingInterrupts(pGVCpu);
     840
    858841                            if (VMCPU_FF_IS_ANY_SET(pGVCpu, fIntMask))
    859842                            {
    860                                 STAM_REL_COUNTER_INC(&pGVCpu->vmm.s.StatR0HaltExecFromBlock);
     843                                VMCPU_CMPXCHG_STATE(pGVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_HALTED);
    861844                                return vmmR0DoHaltInterrupt(pGVCpu, uMWait, enmInterruptibility);
    862845                            }
     846
     847                            /* Okay, block! */
     848                            uint64_t const u64StartSchedHalt   = RTTimeNanoTS();
     849                            int rc = GVMMR0SchedHalt(pGVM, pGVCpu, u64GipTime);
     850                            uint64_t const u64EndSchedHalt     = RTTimeNanoTS();
     851                            uint64_t const cNsElapsedSchedHalt = u64EndSchedHalt - u64StartSchedHalt;
     852
     853                            VMCPU_CMPXCHG_STATE(pGVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_HALTED);
     854                            STAM_REL_PROFILE_ADD_PERIOD(&pGVCpu->vmm.s.StatR0HaltBlock, cNsElapsedSchedHalt);
     855                            if (   rc == VINF_SUCCESS
     856                                || rc == VERR_INTERRUPTED)
     857                            {
     858                                /* Keep some stats like ring-3 does. */
     859                                int64_t const cNsOverslept = u64EndSchedHalt - u64GipTime;
     860                                if (cNsOverslept > 50000)
     861                                    STAM_REL_PROFILE_ADD_PERIOD(&pGVCpu->vmm.s.StatR0HaltBlockOverslept, cNsOverslept);
     862                                else if (cNsOverslept < -50000)
     863                                    STAM_REL_PROFILE_ADD_PERIOD(&pGVCpu->vmm.s.StatR0HaltBlockInsomnia,  cNsElapsedSchedHalt);
     864                                else
     865                                    STAM_REL_PROFILE_ADD_PERIOD(&pGVCpu->vmm.s.StatR0HaltBlockOnTime,    cNsElapsedSchedHalt);
     866
     867                                /*
     868                                 * Recheck whether we can resume execution or have to go to ring-3.
     869                                 */
     870                                if (   !VM_FF_IS_ANY_SET(pGVM, fVmFFs)
     871                                    && !VMCPU_FF_IS_ANY_SET(pGVCpu, fCpuFFs))
     872                                {
     873                                    if (VMCPU_FF_TEST_AND_CLEAR(pGVCpu, VMCPU_FF_UPDATE_APIC))
     874                                        APICUpdatePendingInterrupts(pGVCpu);
     875                                    if (VMCPU_FF_IS_ANY_SET(pGVCpu, fIntMask))
     876                                    {
     877                                        STAM_REL_COUNTER_INC(&pGVCpu->vmm.s.StatR0HaltExecFromBlock);
     878                                        return vmmR0DoHaltInterrupt(pGVCpu, uMWait, enmInterruptibility);
     879                                    }
     880                                }
     881                            }
    863882                        }
     883                        else
     884                            VMCPU_CMPXCHG_STATE(pGVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_HALTED);
    864885                    }
    865886                }
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r87821 r88344  
    540540        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltExecFromSpin,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltExec/FromSpin", i);
    541541        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltExecFromBlock,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltExec/FromBlock", i);
     542        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltToR3FromSpin,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltToR3FromSpin", i);
    542543        STAMR3RegisterF(pVM, &pVCpu->vmm.s.cR0Halts,                 STAMTYPE_U32,     STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltHistoryCounter", i);
    543544        STAMR3RegisterF(pVM, &pVCpu->vmm.s.cR0HaltsSucceeded,        STAMTYPE_U32,     STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltHistorySucceeded", i);
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