VirtualBox

Changeset 105616 in vbox


Ignore:
Timestamp:
Aug 7, 2024 8:22:21 PM (6 months ago)
Author:
vboxsync
Message:

VMM/IEM: Another iemTlbInvalidateLargePageWorkerInner optimization attempt and some stats. bugref:10727

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r105607 r105616  
    642642 */
    643643template<bool const a_fGlobal>
    644 DECL_FORCE_INLINE(void) iemTlbLoadedLargePage(IEMTLB *pTlb, RTGCPTR uTagNoRev, bool f2MbLargePages)
     644DECL_FORCE_INLINE(void) iemTlbLoadedLargePage(PVMCPUCC pVCpu, IEMTLB *pTlb, RTGCPTR uTagNoRev, bool f2MbLargePages)
    645645{
    646646    if (a_fGlobal)
     
    648648    else
    649649        pTlb->cTlbNonGlobalLargePageCurLoads++;
     650
     651# ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     652    RTGCPTR const idxBit = IEMTLB_TAG_TO_EVEN_INDEX(uTagNoRev) + a_fGlobal;
     653    ASMBitSet(pTlb->bmLargePage, idxBit);
     654# endif
    650655
    651656    AssertCompile(IEMTLB_CALC_TAG_NO_REV((RTGCPTR)0x8731U << GUEST_PAGE_SHIFT) == 0x8731U);
     
    661666    if (uTagNoRev > pRange->uLastTag)
    662667        pRange->uLastTag = uTagNoRev;
     668
     669    RT_NOREF_PV(pVCpu);
    663670}
    664671#endif
     
    832839    AssertCompile(IEMTLB_ENTRY_COUNT >= 16); /* prefetching + unroll assumption */
    833840
     841    if (a_fGlobal)
     842        pTlb->cTlbInvlPgLargeGlobal += 1;
     843    if (a_fNonGlobal)
     844        pTlb->cTlbInvlPgLargeNonGlobal += 1;
     845
    834846    /*
    835847     * Set up the scan.
     
    845857     * relevant host architectures.
    846858     */
    847     /** @todo benchmark this code from the guest side.   */
     859    /** @todo benchmark this code from the guest side. */
    848860    bool const      fPartialScan = IEMTLB_ENTRY_COUNT > (a_f2MbLargePage ? 512 : 1024);
     861#ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     862    uintptr_t       idxBitmap    = fPartialScan ? IEMTLB_TAG_TO_EVEN_INDEX(GCPtrTag) / 64 : 0;
     863    uintptr_t const idxBitmapEnd = fPartialScan ? idxBitmap + ((a_f2MbLargePage ? 512 : 1024) * 2) / 64
     864                                                : IEMTLB_ENTRY_COUNT * 2 / 64;
     865#else
    849866    uintptr_t       idxEven      = fPartialScan ? IEMTLB_TAG_TO_EVEN_INDEX(GCPtrTag) : 0;
    850     MY_PREFETCH_256(&pTlb->aEntries[0 + !a_fNonGlobal]);
     867    MY_PREFETCH_256(&pTlb->aEntries[idxEven + !a_fNonGlobal]);
    851868    uintptr_t const idxEvenEnd   = fPartialScan ? idxEven + ((a_f2MbLargePage ? 512 : 1024) * 2) : IEMTLB_ENTRY_COUNT * 2;
     869#endif
    852870    RTGCPTR const   GCPtrTagMask = fPartialScan ? ~(RTGCPTR)0
    853871                                 : ~(RTGCPTR)(  (RT_BIT_32(a_f2MbLargePage ? 9 : 10) - 1U)
     
    873891     * Do the scanning.
    874892     */
     893#ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     894    uint64_t const bmMask  = a_fGlobal && a_fNonGlobal ? UINT64_MAX
     895                           : a_fGlobal ? UINT64_C(0xaaaaaaaaaaaaaaaa) : UINT64_C(0x5555555555555555);
     896    /* Scan bitmap entries (64 bits at the time): */
     897    for (;;)
     898    {
     899# if 1
     900        uint64_t bmEntry = pTlb->bmLargePage[idxBitmap] & bmMask;
     901        if (bmEntry)
     902        {
     903            /* Scan the non-zero 64-bit value in groups of 8 bits: */
     904            uint64_t  bmToClear = 0;
     905            uintptr_t idxEven   = idxBitmap * 64;
     906            uint32_t  idxTag    = 0;
     907            for (;;)
     908            {
     909                if (bmEntry & 0xff)
     910                {
     911#  define ONE_PAIR(a_idxTagIter, a_idxEvenIter, a_bmNonGlobal, a_bmGlobal) \
     912                        if (a_fNonGlobal) \
     913                        { \
     914                            if (bmEntry & a_bmNonGlobal) \
     915                            { \
     916                                Assert(pTlb->aEntries[a_idxEvenIter].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); \
     917                                if ((pTlb->aEntries[a_idxEvenIter].uTag & GCPtrTagMask) == (GCPtrTag + a_idxTagIter)) \
     918                                { \
     919                                    IEMTLBTRACE_LARGE_EVICT_SLOT(pVCpu, GCPtrTag + a_idxTagIter, \
     920                                                                 pTlb->aEntries[a_idxEvenIter].GCPhys, \
     921                                                                 a_idxEvenIter, a_fDataTlb); \
     922                                    pTlb->aEntries[a_idxEvenIter].uTag = 0; \
     923                                    bmToClearSub8 |= a_bmNonGlobal; \
     924                                } \
     925                            } \
     926                            else \
     927                                Assert(   !(pTlb->aEntries[a_idxEvenIter].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE)\
     928                                       ||    (pTlb->aEntries[a_idxEvenIter].uTag & IEMTLB_REVISION_MASK) \
     929                                          != (GCPtrTag & IEMTLB_REVISION_MASK)); \
     930                        } \
     931                        if (a_fGlobal) \
     932                        { \
     933                            if (bmEntry & a_bmGlobal) \
     934                            {  \
     935                                Assert(pTlb->aEntries[a_idxEvenIter + 1].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); \
     936                                if ((pTlb->aEntries[a_idxEvenIter + 1].uTag & GCPtrTagMask) == (GCPtrTagGlob + a_idxTagIter)) \
     937                                { \
     938                                    IEMTLBTRACE_LARGE_EVICT_SLOT(pVCpu, GCPtrTagGlob + a_idxTagIter, \
     939                                                                 pTlb->aEntries[a_idxEvenIter + 1].GCPhys, \
     940                                                                 a_idxEvenIter + 1, a_fDataTlb); \
     941                                    pTlb->aEntries[a_idxEvenIter + 1].uTag = 0; \
     942                                    bmToClearSub8 |= a_bmGlobal; \
     943                                } \
     944                            } \
     945                            else \
     946                                Assert(   !(pTlb->aEntries[a_idxEvenIter + 1].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE)\
     947                                       ||    (pTlb->aEntries[a_idxEvenIter + 1].uTag & IEMTLB_REVISION_MASK) \
     948                                          != (GCPtrTagGlob & IEMTLB_REVISION_MASK)); \
     949                        }
     950                    uint64_t bmToClearSub8 = 0;
     951                    ONE_PAIR(idxTag + 0, idxEven + 0, 0x01, 0x02)
     952                    ONE_PAIR(idxTag + 1, idxEven + 2, 0x04, 0x08)
     953                    ONE_PAIR(idxTag + 2, idxEven + 4, 0x10, 0x20)
     954                    ONE_PAIR(idxTag + 3, idxEven + 6, 0x40, 0x80)
     955                    bmToClear |= bmToClearSub8 << (idxTag * 2);
     956#  undef ONE_PAIR
     957                }
     958
     959                /* advance to the next 8 bits. */
     960                bmEntry >>= 8;
     961                if (!bmEntry)
     962                    break;
     963                idxEven  += 8;
     964                idxTag   += 4;
     965            }
     966
     967            /* Clear the large page flags we covered. */
     968            pTlb->bmLargePage[idxBitmap] &= ~bmToClear;
     969        }
     970# else
     971        uint64_t const bmEntry = pTlb->bmLargePage[idxBitmap] & bmMask;
     972        if (bmEntry)
     973        {
     974            /* Scan the non-zero 64-bit value completely unrolled: */
     975            uintptr_t const idxEven   = idxBitmap * 64;
     976            uint64_t        bmToClear = 0;
     977#  define ONE_PAIR(a_idxTagIter, a_idxEvenIter, a_bmNonGlobal, a_bmGlobal) \
     978                if (a_fNonGlobal) \
     979                { \
     980                    if (bmEntry & a_bmNonGlobal) \
     981                    { \
     982                        Assert(pTlb->aEntries[a_idxEvenIter].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); \
     983                        if ((pTlb->aEntries[a_idxEvenIter].uTag & GCPtrTagMask) == (GCPtrTag + a_idxTagIter)) \
     984                        { \
     985                            IEMTLBTRACE_LARGE_EVICT_SLOT(pVCpu, GCPtrTag + a_idxTagIter, \
     986                                                         pTlb->aEntries[a_idxEvenIter].GCPhys, \
     987                                                         a_idxEvenIter, a_fDataTlb); \
     988                            pTlb->aEntries[a_idxEvenIter].uTag = 0; \
     989                            bmToClear |= a_bmNonGlobal; \
     990                        } \
     991                    } \
     992                    else \
     993                        Assert(   !(pTlb->aEntriqes[a_idxEvenIter].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE)\
     994                               ||    (pTlb->aEntries[a_idxEvenIter].uTag & IEMTLB_REVISION_MASK) \
     995                                  != (GCPtrTag & IEMTLB_REVISION_MASK)); \
     996                } \
     997                if (a_fGlobal) \
     998                { \
     999                    if (bmEntry & a_bmGlobal) \
     1000                    {  \
     1001                        Assert(pTlb->aEntries[a_idxEvenIter + 1].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); \
     1002                        if ((pTlb->aEntries[a_idxEvenIter + 1].uTag & GCPtrTagMask) == (GCPtrTagGlob + a_idxTagIter)) \
     1003                        { \
     1004                            IEMTLBTRACE_LARGE_EVICT_SLOT(pVCpu, GCPtrTagGlob + a_idxTagIter, \
     1005                                                         pTlb->aEntries[a_idxEvenIter + 1].GCPhys, \
     1006                                                         a_idxEvenIter + 1, a_fDataTlb); \
     1007                            pTlb->aEntries[a_idxEvenIter + 1].uTag = 0; \
     1008                            bmToClear |= a_bmGlobal; \
     1009                        } \
     1010                    } \
     1011                    else \
     1012                        Assert(   !(pTlb->aEntries[a_idxEvenIter + 1].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE)\
     1013                               ||    (pTlb->aEntries[a_idxEvenIter + 1].uTag & IEMTLB_REVISION_MASK) \
     1014                                  != (GCPtrTagGlob & IEMTLB_REVISION_MASK)); \
     1015                } ((void)0)
     1016#  define FOUR_PAIRS(a_iByte, a_cShift) \
     1017                ONE_PAIR(0 + a_iByte * 4, idxEven + 0 + a_iByte * 8, UINT64_C(0x01) << a_cShift, UINT64_C(0x02) << a_cShift); \
     1018                ONE_PAIR(1 + a_iByte * 4, idxEven + 2 + a_iByte * 8, UINT64_C(0x04) << a_cShift, UINT64_C(0x08) << a_cShift); \
     1019                ONE_PAIR(2 + a_iByte * 4, idxEven + 4 + a_iByte * 8, UINT64_C(0x10) << a_cShift, UINT64_C(0x20) << a_cShift); \
     1020                ONE_PAIR(3 + a_iByte * 4, idxEven + 6 + a_iByte * 8, UINT64_C(0x40) << a_cShift, UINT64_C(0x80) << a_cShift)
     1021            if (bmEntry & (uint32_t)UINT16_MAX)
     1022            {
     1023                FOUR_PAIRS(0,  0);
     1024                FOUR_PAIRS(1,  8);
     1025            }
     1026            if (bmEntry & ((uint32_t)UINT16_MAX << 16))
     1027            {
     1028                FOUR_PAIRS(2, 16);
     1029                FOUR_PAIRS(3, 24);
     1030            }
     1031            if (bmEntry & ((uint64_t)UINT16_MAX << 32))
     1032            {
     1033                FOUR_PAIRS(4, 32);
     1034                FOUR_PAIRS(5, 40);
     1035            }
     1036            if (bmEntry & ((uint64_t)UINT16_MAX << 16))
     1037            {
     1038                FOUR_PAIRS(6, 48);
     1039                FOUR_PAIRS(7, 56);
     1040            }
     1041#  undef FOUR_PAIRS
     1042
     1043            /* Clear the large page flags we covered. */
     1044            pTlb->bmLargePage[idxBitmap] &= ~bmToClear;
     1045        }
     1046# endif
     1047
     1048        /* advance */
     1049        idxBitmap++;
     1050        if (idxBitmap >= idxBitmapEnd)
     1051            break;
     1052        if (a_fNonGlobal)
     1053            GCPtrTag     += 32;
     1054        if (a_fGlobal)
     1055            GCPtrTagGlob += 32;
     1056    }
     1057
     1058#else  /* !IEMTLB_WITH_LARGE_PAGE_BITMAP */
     1059
    8751060    for (; idxEven < idxEvenEnd; idxEven += 8)
    8761061    {
    877 #define ONE_ITERATION(a_idxEvenIter) \
     1062# define ONE_ITERATION(a_idxEvenIter) \
    8781063            if (a_fNonGlobal)  \
    8791064            { \
     
    9091094        ONE_ITERATION(idxEven + 4)
    9101095        ONE_ITERATION(idxEven + 6)
    911 #undef ONE_ITERATION
    912     }
     1096# undef ONE_ITERATION
     1097    }
     1098#endif /* !IEMTLB_WITH_LARGE_PAGE_BITMAP */
    9131099}
    9141100
     
    9421128DECLINLINE(void) iemTlbInvalidatePageWorker(PVMCPUCC pVCpu, IEMTLB *pTlb, RTGCPTR GCPtrTag, uintptr_t idxEven) RT_NOEXCEPT
    9431129{
     1130    pTlb->cTlbInvlPg += 1;
     1131
    9441132    /*
    9451133     * Flush the entry pair.
     
    12711459        {
    12721460            /* likely when executing lots of code, otherwise unlikely */
    1273 # ifdef IEM_WITH_TLB_STATISTICS
     1461#  ifdef IEM_WITH_TLB_STATISTICS
    12741462            pVCpu->iem.s.CodeTlb.cTlbCoreHits++;
    1275 # endif
     1463#  endif
    12761464            Assert(!(pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_ACCESSED));
    12771465
     
    13211509            else
    13221510            {
    1323 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
     1511#  ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
    13241512                /** @todo Nested VMX: Need to handle EPT violation/misconfig here?  OF COURSE! */
    13251513                Assert(!(Walk.fFailed & PGM_WALKFAIL_EPT));
    1326 #endif
     1514#  endif
    13271515                Log(("iemOpcodeFetchMoreBytes: %RGv - rc=%Rrc\n", GCPtrFirst, rc));
    13281516                iemRaisePageFaultJmp(pVCpu, GCPtrFirst, 1, IEM_ACCESS_INSTRUCTION, rc);
     
    13361524                pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevision;
    13371525                if (WalkFast.fInfo & PGM_WALKINFO_BIG_PAGE)
    1338                     iemTlbLoadedLargePage<false>(&pVCpu->iem.s.CodeTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     1526                    iemTlbLoadedLargePage<false>(pVCpu, &pVCpu->iem.s.CodeTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     1527#  ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     1528                else
     1529                    ASMBitClear(pVCpu->iem.s.CodeTlb.bmLargePage, IEMTLB_TAG_TO_EVEN_INDEX(uTagNoRev));
     1530#  endif
    13391531            }
    13401532            else
     
    13431535                pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal;
    13441536                if (WalkFast.fInfo & PGM_WALKINFO_BIG_PAGE)
    1345                     iemTlbLoadedLargePage<true>(&pVCpu->iem.s.CodeTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     1537                    iemTlbLoadedLargePage<true>(pVCpu, &pVCpu->iem.s.CodeTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     1538#  ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     1539                else
     1540                    ASMBitClear(pVCpu->iem.s.CodeTlb.bmLargePage, IEMTLB_TAG_TO_EVEN_INDEX(uTagNoRev) + 1);
     1541#  endif
    13461542            }
    13471543            pTlbe->fFlagsAndPhysRev = (~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A))
     
    68026998# ifdef IEM_WITH_TLB_STATISTICS
    68036999        pVCpu->iem.s.DataTlb.cTlbCoreHits++;
    6804 #endif
     7000# endif
    68057001
    68067002        /* If the page is either supervisor only or non-writable, we need to do
     
    68917087                pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision;
    68927088                if (WalkFast.fInfo & PGM_WALKINFO_BIG_PAGE)
    6893                     iemTlbLoadedLargePage<false>(&pVCpu->iem.s.DataTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     7089                    iemTlbLoadedLargePage<false>(pVCpu, &pVCpu->iem.s.DataTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     7090# ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     7091                else
     7092                    ASMBitClear(pVCpu->iem.s.DataTlb.bmLargePage, IEMTLB_TAG_TO_EVEN_INDEX(uTagNoRev));
     7093# endif
    68947094            }
    68957095            else
     
    68987098                pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal;
    68997099                if (WalkFast.fInfo & PGM_WALKINFO_BIG_PAGE)
    6900                     iemTlbLoadedLargePage<true>(&pVCpu->iem.s.DataTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     7100                    iemTlbLoadedLargePage<true>(pVCpu, &pVCpu->iem.s.DataTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     7101# ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     7102                else
     7103                    ASMBitClear(pVCpu->iem.s.DataTlb.bmLargePage, IEMTLB_TAG_TO_EVEN_INDEX(uTagNoRev) + 1);
     7104# endif
    69017105            }
    69027106        }
     
    72957499                pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision;
    72967500                if (WalkFast.fInfo & PGM_WALKINFO_BIG_PAGE)
    7297                     iemTlbLoadedLargePage<false>(&pVCpu->iem.s.DataTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     7501                    iemTlbLoadedLargePage<false>(pVCpu, &pVCpu->iem.s.DataTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     7502# ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     7503                else
     7504                    ASMBitClear(pVCpu->iem.s.DataTlb.bmLargePage, IEMTLB_TAG_TO_EVEN_INDEX(uTagNoRev));
     7505# endif
    72987506            }
    72997507            else
     
    73057513                pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal;
    73067514                if (WalkFast.fInfo & PGM_WALKINFO_BIG_PAGE)
    7307                     iemTlbLoadedLargePage<true>(&pVCpu->iem.s.DataTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     7515                    iemTlbLoadedLargePage<true>(pVCpu, &pVCpu->iem.s.DataTlb, uTagNoRev, RT_BOOL(pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE));
     7516# ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     7517                else
     7518                    ASMBitClear(pVCpu->iem.s.DataTlb.bmLargePage, IEMTLB_TAG_TO_EVEN_INDEX(uTagNoRev) + 1);
     7519# endif
    73087520            }
    73097521        }
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r105591 r105616  
    387387                        "Code TLB non-global large page range: last tag",   "/IEM/CPU%u/Tlb/Code/LargePageNonGlobalLastTag", idCpu);
    388388
     389        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbInvlPg, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
     390                        "Code TLB page invalidation requests",          "/IEM/CPU%u/Tlb/Code/InvlPg", idCpu);
     391        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbInvlPgLargeGlobal, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
     392                        "Code TLB page invlpg scanning for global large pages",     "/IEM/CPU%u/Tlb/Code/InvlPg/LargeGlobal", idCpu);
     393        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbInvlPgLargeNonGlobal, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
     394                        "Code TLB page invlpg scanning for non-global large pages", "/IEM/CPU%u/Tlb/Code/InvlPg/LargeNonGlobal", idCpu);
     395
    389396        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbCoreMisses,      STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    390397                        "Code TLB misses",                              "/IEM/CPU%u/Tlb/Code/Misses", idCpu);
     
    474481        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.NonGlobalLargePageRange.uLastTag, STAMTYPE_X64, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    475482                        "Data TLB non-global large page range: last tag",   "/IEM/CPU%u/Tlb/Data/LargePageNonGlobalLastTag", idCpu);
     483
     484        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbInvlPg, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
     485                        "Data TLB page invalidation requests",          "/IEM/CPU%u/Tlb/Data/InvlPg", idCpu);
     486        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbInvlPgLargeGlobal, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
     487                        "Data TLB page invlpg scanning for global large pages",     "/IEM/CPU%u/Tlb/Data/InvlPg/LargeGlobal", idCpu);
     488        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbInvlPgLargeNonGlobal, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
     489                        "Data TLB page invlpg scanning for non-global large pages", "/IEM/CPU%u/Tlb/Data/InvlPg/LargeNonGlobal", idCpu);
    476490
    477491        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbCoreMisses,      STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r105579 r105616  
    558558#endif
    559559
     560/** Enable the large page bitmap TLB optimization.
     561 *
     562 * The idea here is to avoid scanning the full 32 KB (2MB pages, 2*512 TLB
     563 * entries) or 64 KB (4MB pages, 2*1024 TLB entries) worth of TLB entries during
     564 * invlpg when large pages are used, and instead just scan 128 or 256 bytes of
     565 * the bmLargePage bitmap to determin which TLB entires that might be containing
     566 * large pages and actually require checking.
     567 *
     568 * There is a good posibility of false positives since we currently don't clear
     569 * the bitmap when flushing the TLB, but it should help reduce the workload when
     570 * the large pages aren't fully loaded into the TLB in their entirity...
     571 */
     572#define IEMTLB_WITH_LARGE_PAGE_BITMAP
    560573
    561574/**
     
    672685    uint32_t            cTlbPhysRevRollovers;
    673686
    674     /*uint32_t            au32Padding[2];*/
     687    /** Number of INVLPG (and similar) operations. */
     688    uint32_t            cTlbInvlPg;
     689    /** Subset of cTlbInvlPg that involved non-global large pages. */
     690    uint32_t            cTlbInvlPgLargeNonGlobal;
     691    /** Subset of cTlbInvlPg that involved global large pages. */
     692    uint32_t            cTlbInvlPgLargeGlobal;
     693
     694    uint32_t            au32Padding[13];
    675695
    676696    /** The TLB entries.
     
    678698     * Odd  entries are for PTE.G=1 and uses uTlbRevisionGlobal. */
    679699    IEMTLBENTRY         aEntries[IEMTLB_ENTRY_COUNT * 2];
     700#ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     701    /** Bitmap tracking TLB entries for large pages.
     702     * This duplicates IEMTLBE_F_PT_LARGE_PAGE for each TLB entry. */
     703    uint64_t            bmLargePage[IEMTLB_ENTRY_COUNT * 2 / 64];
     704#endif
    680705} IEMTLB;
    681706AssertCompileSizeAlignment(IEMTLB, 64);
     707#ifdef IEMTLB_WITH_LARGE_PAGE_BITMAP
     708AssertCompile(IEMTLB_ENTRY_COUNT >= 32 /* bmLargePage ASSUMPTION */);
     709#endif
    682710/** The width (in bits) of the address portion of the TLB tag.   */
    683711#define IEMTLB_TAG_ADDR_WIDTH   36
     
    862890    iemTlbTrace(a_pVCpu, kIemTlbTraceType_User3, a_u64Param1, a_u64Param2, a_bParam, a_u32Param)
    863891#else
     892# define IEMTLBTRACE_USER0(a_pVCpu, a_u64Param1, a_u64Param2, a_u32Param, a_bParam) do { } while (0)
    864893# define IEMTLBTRACE_USER1(a_pVCpu, a_u64Param1, a_u64Param2, a_u32Param, a_bParam) do { } while (0)
    865894# define IEMTLBTRACE_USER2(a_pVCpu, a_u64Param1, a_u64Param2, a_u32Param, a_bParam) do { } while (0)
    866895# define IEMTLBTRACE_USER3(a_pVCpu, a_u64Param1, a_u64Param2, a_u32Param, a_bParam) do { } while (0)
    867 # define IEMTLBTRACE_USER4(a_pVCpu, a_u64Param1, a_u64Param2, a_u32Param, a_bParam) do { } while (0)
    868896#endif
    869897
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