VirtualBox

Changeset 60593 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 20, 2016 11:02:38 AM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
106732
Message:

VMM/APIC: Profiling and reduce 8 atomic ops to 4.

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r60516 r60593  
    793793    GEN_CHECK_OFF(APICCPU, StatMsrWriteRC);
    794794    GEN_CHECK_OFF(APICCPU, StatUpdatePendingIntrs);
    795     GEN_CHECK_OFF(APICCPU, StatPostInterrupt);
     795    GEN_CHECK_OFF(APICCPU, StatPostIntr);
     796    GEN_CHECK_OFF(APICCPU, StatPostIntrAlreadyPending);
    796797#else
    797798    /* PC/DevAPIC.cpp */
  • trunk/src/VBox/VMM/VMMAll/APICAll.cpp

    r60573 r60593  
    5858 * @param   uVector         The vector to check if set.
    5959 */
    60 DECLINLINE(bool) apicTestVectorInReg(volatile XAPIC256BITREG *pApicReg, uint8_t uVector)
    61 {
    62     volatile uint8_t *pbBitmap = (volatile uint8_t *)&pApicReg->u[0];
     60DECLINLINE(bool) apicTestVectorInReg(const volatile XAPIC256BITREG *pApicReg, uint8_t uVector)
     61{
     62    const volatile uint8_t *pbBitmap = (const volatile uint8_t *)&pApicReg->u[0];
    6363    return ASMBitTest(pbBitmap + XAPIC_REG256_VECTOR_OFF(uVector), XAPIC_REG256_VECTOR_BIT(uVector));
    6464}
     
    24202420    PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
    24212421
    2422     STAM_PROFILE_START(&pApicCpu->StatPostInterrupt, a);
    2423 
    2424     /* Validate the vector. See Intel spec. 10.5.2 "Valid Interrupt Vectors". */
     2422    STAM_PROFILE_START(&pApicCpu->StatPostIntr, a);
     2423
     2424    /*
     2425     * Only post valid interrupt vectors.
     2426     * See Intel spec. 10.5.2 "Valid Interrupt Vectors".
     2427     */
    24252428    if (RT_LIKELY(uVector > XAPIC_ILLEGAL_VECTOR_END))
    24262429    {
    2427         Log4(("APIC%u: APICPostInterrupt: uVector=%#x\n", pVCpu->idCpu, uVector));
    2428         if (enmTriggerMode == XAPICTRIGGERMODE_EDGE)
    2429         {
    2430             if (pApic->fPostedIntrsEnabled)
    2431             { /** @todo posted-interrupt call to hardware */ }
     2430        /*
     2431         * If the interrupt is already pending in the vIRR we can skip the
     2432         * potential expensive operation of poking the guest EMT out of execution.
     2433         */
     2434        PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
     2435        if (!apicTestVectorInReg(&pXApicPage->irr, uVector))     /* PAV */
     2436        {
     2437            Log4(("APIC%u: APICPostInterrupt: uVector=%#x\n", pVCpu->idCpu, uVector));
     2438            if (enmTriggerMode == XAPICTRIGGERMODE_EDGE)
     2439            {
     2440                if (pApic->fPostedIntrsEnabled)
     2441                { /** @todo posted-interrupt call to hardware */ }
     2442                else
     2443                {
     2444                    Assert(CTX_SUFF(pApicCpu->pvApicPib));
     2445                    apicSetVectorInPib(CTX_SUFF(pApicCpu->pvApicPib), uVector);
     2446                    bool const fAlreadySet = apicSetNotificationBitInPib(CTX_SUFF(pApicCpu->pvApicPib));
     2447                    if (!fAlreadySet)
     2448                        APICSetInterruptFF(pVCpu, PDMAPICIRQ_HARDWARE);
     2449                }
     2450            }
    24322451            else
    24332452            {
    2434                 Assert(CTX_SUFF(pApicCpu->pvApicPib));
    2435                 apicSetVectorInPib(CTX_SUFF(pApicCpu->pvApicPib), uVector);
    2436                 bool const fAlreadySet = apicSetNotificationBitInPib(CTX_SUFF(pApicCpu->pvApicPib));
     2453                /*
     2454                 * Level-triggered interrupts requires updating of the TMR and thus cannot be
     2455                 * delivered asynchronously.
     2456                 */
     2457                apicSetVectorInPib(&pApicCpu->ApicPibLevel.aVectorBitmap[0], uVector);
     2458                bool const fAlreadySet = apicSetNotificationBitInPib(&pApicCpu->ApicPibLevel.aVectorBitmap[0]);
    24372459                if (!fAlreadySet)
    24382460                    APICSetInterruptFF(pVCpu, PDMAPICIRQ_HARDWARE);
     
    24402462        }
    24412463        else
    2442         {
    2443             /*
    2444              * Level-triggered interrupts requires updating of the TMR and thus cannot be
    2445              * delivered asynchronously.
    2446              */
    2447             apicSetVectorInPib(&pApicCpu->ApicPibLevel.aVectorBitmap[0], uVector);
    2448             bool const fAlreadySet = apicSetNotificationBitInPib(&pApicCpu->ApicPibLevel.aVectorBitmap[0]);
    2449             if (!fAlreadySet)
    2450                 APICSetInterruptFF(pVCpu, PDMAPICIRQ_HARDWARE);
    2451         }
     2464            STAM_COUNTER_INC(&pApicCpu->StatPostIntrAlreadyPending);
    24522465    }
    24532466    else
    24542467        apicSetError(pVCpu, XAPIC_ESR_RECV_ILLEGAL_VECTOR);
    24552468
    2456     STAM_PROFILE_STOP(&pApicCpu->StatPostInterrupt, a);
     2469    STAM_PROFILE_STOP(&pApicCpu->StatPostIntr, a);
    24572470}
    24582471
     
    26282641
    26292642        PAPICPIB pPib = (PAPICPIB)CTX_SUFF(pApicCpu->pvApicPib);
    2630         for (size_t i = 0; i < RT_ELEMENTS(pPib->aVectorBitmap); i++)
    2631         {
    2632             uint32_t const uFragment = ASMAtomicXchgU32(&pPib->aVectorBitmap[i], 0);
    2633             if (uFragment)
    2634             {
    2635                 pXApicPage->irr.u[i].u32Reg |=  uFragment;
    2636                 pXApicPage->tmr.u[i].u32Reg &= ~uFragment;
     2643        AssertCompile(RT_ELEMENTS(pXApicPage->irr.u) == 2 * RT_ELEMENTS(pPib->aVectorBitmap));
     2644
     2645        for (size_t idxPib = 0, idxReg = 0; idxPib < RT_ELEMENTS(pPib->aVectorBitmap); idxPib++, idxReg += 2)
     2646        {
     2647            uint64_t const u64Fragment = ASMAtomicXchgU64(&pPib->aVectorBitmap[idxPib], 0);
     2648            if (u64Fragment)
     2649            {
     2650                uint32_t const u32FragmentLo = RT_LO_U32(u64Fragment);
     2651                uint32_t const u32FragmentHi = RT_HI_U32(u64Fragment);
     2652
     2653                pXApicPage->irr.u[idxReg].u32Reg     |=  u32FragmentLo;
     2654                pXApicPage->irr.u[idxReg + 1].u32Reg |=  u32FragmentHi;
     2655
     2656                pXApicPage->tmr.u[idxReg].u32Reg     &= ~u32FragmentLo;
     2657                pXApicPage->tmr.u[idxReg + 1].u32Reg &= ~u32FragmentHi;
    26372658            }
    26382659        }
     
    26472668
    26482669        PAPICPIB pPib = (PAPICPIB)&pApicCpu->ApicPibLevel;
    2649         for (size_t i = 0; i < RT_ELEMENTS(pPib->aVectorBitmap); i++)
    2650         {
    2651             uint32_t const uFragment = ASMAtomicXchgU32(&pPib->aVectorBitmap[i], 0);
    2652             if (uFragment)
    2653             {
    2654                 pXApicPage->irr.u[i].u32Reg |= uFragment;
    2655                 pXApicPage->tmr.u[i].u32Reg |= uFragment;
     2670        AssertCompile(RT_ELEMENTS(pXApicPage->irr.u) == 2 * RT_ELEMENTS(pPib->aVectorBitmap));
     2671
     2672        for (size_t idxPib = 0, idxReg = 0; idxPib < RT_ELEMENTS(pPib->aVectorBitmap); idxPib++, idxReg += 2)
     2673        {
     2674            uint64_t const u64Fragment = ASMAtomicXchgU64(&pPib->aVectorBitmap[idxPib], 0);
     2675            if (u64Fragment)
     2676            {
     2677                uint32_t const u32FragmentLo = RT_LO_U32(u64Fragment);
     2678                uint32_t const u32FragmentHi = RT_HI_U32(u64Fragment);
     2679
     2680                pXApicPage->irr.u[idxReg].u32Reg     |= u32FragmentLo;
     2681                pXApicPage->irr.u[idxReg + 1].u32Reg |= u32FragmentHi;
     2682
     2683                pXApicPage->tmr.u[idxReg].u32Reg     |= u32FragmentLo;
     2684                pXApicPage->tmr.u[idxReg + 1].u32Reg |= u32FragmentHi;
    26562685            }
    26572686        }
  • trunk/src/VBox/VMM/VMMR3/APIC.cpp

    r60543 r60593  
    11841184    ApicReg.pfnLocalInterruptR3     = APICLocalInterrupt;
    11851185    ApicReg.pfnGetTimerFreqR3       = APICGetTimerFreq;
    1186     if (pApic->fRZEnabled)
     1186
     1187    /*
     1188     * We always require R0 functionality (e.g. APICGetTpr() called by HMR0 VT-x/AMD-V code).
     1189     * Hence, 'fRZEnabled' strictly only applies to MMIO and MSR read/write handlers returning
     1190     * to ring-3. We still need other handlers like APICGetTpr() in ring-0 for now.
     1191     */
    11871192    {
    11881193        ApicReg.pszGetInterruptRC   = "APICGetInterrupt";
     
    12641269            pApicCpu->pTimerR0 = TMTimerR0Ptr(pApicCpu->pTimerR3);
    12651270            pApicCpu->pTimerRC = TMTimerRCPtr(pApicCpu->pTimerR3);
    1266 #if 0
    1267             rc = PDMR3CritSectInit(pVM, &pApicCpu->TimerCritSect, RT_SRC_POS, pApicCpu->szTimerDesc);
    1268             AssertRCReturn(rc, rc);
    1269             TMR3TimerSetCritSect(pApicCpu->pTimerR3, &pApicCpu->TimerCritSect);
    1270 #endif
    12711271        }
    12721272        else
     
    13321332        APIC_PROF_COUNTER(&pApicCpu->StatUpdatePendingIntrs, "Profiling of APICUpdatePendingInterrupts",
    13331333                          "/PROF/CPU%d/APIC/UpdatePendingInterrupts");
    1334         APIC_PROF_COUNTER(&pApicCpu->StatPostInterrupt, "Profiling of APICPostInterrupt", "/PROF/CPU%d/APIC/PostInterrupt");
    1335     }
     1334        APIC_PROF_COUNTER(&pApicCpu->StatPostIntr, "Profiling of APICPostInterrupt", "/PROF/CPU%d/APIC/PostInterrupt");
     1335
     1336        APIC_REG_COUNTER(&pApicCpu->StatPostIntrAlreadyPending,  "Number of times an interrupt is already pending.",
     1337                         "/Devices/APIC/%u/PostInterruptAlreadyPending");
     1338    }
     1339# undef APIC_PROF_COUNTER
    13361340# undef APIC_REG_ACCESS_COUNTER
    13371341#endif
  • trunk/src/VBox/VMM/include/APICInternal.h

    r60542 r60593  
    473473    /** Whether this VM has an IO-APIC. */
    474474    bool                        fIoApicPresent;
    475     /** Whether RZ is enabled or not (required for MSR handling as well). */
     475    /** Whether RZ is enabled or not (applies to MSR handling as well). */
    476476    bool                        fRZEnabled;
    477477    /** Alignment padding. */
     
    591591    STAMPROFILE                 StatUpdatePendingIntrs;
    592592    /** Profiling of APICPostInterrupt().  */
    593     STAMPROFILE                 StatPostInterrupt;
     593    STAMPROFILE                 StatPostIntr;
     594    /** Number of times an interrupt is already pending in
     595     *  APICPostInterrupts().*/
     596    STAMCOUNTER                 StatPostIntrAlreadyPending;
    594597    /** @} */
    595598#endif
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