VirtualBox

Changeset 92368 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Nov 11, 2021 1:31:21 PM (3 years ago)
Author:
vboxsync
Message:

VMM/PGM,GMM: Baked PGMR3PhysAllocateLargePage into PGMR0PhysAllocateLargePage eliminating VMMCALLRING3_PGM_ALLOCATE_LARGE_HANDY_PAGE; adjusted GMMR0AllocateLargePage to be ring-0 callable. Changed the large page allocation backoff logic a bit. Some more release stats. bugref:10093

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PGM.cpp

    r92326 r92368  
    11571157    STAM_REL_REG(pVM, &pPGM->cLargePages,                        STAMTYPE_U32,     "/PGM/Page/cLargePages",              STAMUNIT_COUNT,     "The number of large pages allocated (includes disabled).");
    11581158    STAM_REL_REG(pVM, &pPGM->cLargePagesDisabled,                STAMTYPE_U32,     "/PGM/Page/cLargePagesDisabled",      STAMUNIT_COUNT,     "The number of disabled large pages.");
    1159     STAM_REL_REG(pVM, &pPGM->cRelocations,                       STAMTYPE_COUNTER, "/PGM/cRelocations",                  STAMUNIT_OCCURENCES,"Number of hypervisor relocations.");
    11601159    STAM_REL_REG(pVM, &pPGM->ChunkR3Map.c,                       STAMTYPE_U32,     "/PGM/ChunkR3Map/c",                  STAMUNIT_COUNT,     "Number of mapped chunks.");
    11611160    STAM_REL_REG(pVM, &pPGM->ChunkR3Map.cMax,                    STAMTYPE_U32,     "/PGM/ChunkR3Map/cMax",               STAMUNIT_COUNT,     "Maximum number of mapped chunks.");
     
    11901189    STAM_REL_REG_USED(pVM, &pPGM->LiveSave.Mmio2.cMonitoredPages,STAMTYPE_U32,     "/PGM/LiveSave/Mmio2/cMonitoredPages",STAMUNIT_COUNT,     "MMIO2: Write monitored pages.");
    11911190
    1192 #ifdef VBOX_WITH_STATISTICS
    1193 
    1194 # define PGM_REG_COUNTER(a, b, c) \
     1191#define PGM_REG_COUNTER(a, b, c) \
    11951192        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b); \
    11961193        AssertRC(rc);
    11971194
    1198 # define PGM_REG_COUNTER_BYTES(a, b, c) \
     1195#define PGM_REG_COUNTER_BYTES(a, b, c) \
    11991196        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, c, b); \
    12001197        AssertRC(rc);
    12011198
    1202 # define PGM_REG_PROFILE(a, b, c) \
     1199#define PGM_REG_PROFILE(a, b, c) \
    12031200        rc = STAMR3RegisterF(pVM, a, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, c, b); \
    12041201        AssertRC(rc);
    1205 
    1206     PGMSTATS *pStats = &pVM->pgm.s.Stats;
    1207 
    1208     PGM_REG_PROFILE(&pStats->StatAllocLargePage,                "/PGM/LargePage/Alloc",               "Time spent by the host OS for large page allocation.");
    1209     PGM_REG_PROFILE(&pStats->StatClearLargePage,                "/PGM/LargePage/Clear",               "Time spent clearing the newly allocated large pages.");
    1210     PGM_REG_COUNTER(&pStats->StatLargePageOverflow,             "/PGM/LargePage/Overflow",            "The number of times allocating a large page took too long.");
     1202#define PGM_REG_PROFILE_NS(a, b, c) \
     1203        rc = STAMR3RegisterF(pVM, a, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, c, b); \
     1204        AssertRC(rc);
     1205
     1206#ifdef VBOX_WITH_STATISTICS
     1207    PGMSTATS *pStats = &pPGM->Stats;
     1208#endif
     1209
     1210    PGM_REG_PROFILE_NS(&pPGM->StatLargePageAlloc,               "/PGM/LargePage/Alloc",               "Time spent by the host OS for large page allocation.");
     1211    PGM_REG_COUNTER(&pPGM->StatLargePageOverflow,               "/PGM/LargePage/Overflow",            "The number of times allocating a large page took too long.");
     1212#ifdef VBOX_WITH_STATISTICS
     1213    PGM_REG_PROFILE(&pStats->StatLargePageSetup,                "/PGM/LargePage/Setup",               "Time spent setting up the newly allocated large pages.");
    12111214    PGM_REG_PROFILE(&pStats->StatR3IsValidLargePage,            "/PGM/LargePage/IsValidR3",           "pgmPhysIsValidLargePage profiling - R3.");
    12121215    PGM_REG_PROFILE(&pStats->StatRZIsValidLargePage,            "/PGM/LargePage/IsValidRZ",           "pgmPhysIsValidLargePage profiling - RZ.");
     
    12871290    PGM_REG_COUNTER(&pStats->StatTrackNoExtentsLeft,            "/PGM/Track/NoExtentLeft",            "The number of times the extent list was exhausted.");
    12881291    PGM_REG_PROFILE(&pStats->StatTrackDeref,                    "/PGM/Track/Deref",                   "Profiling of SyncPageWorkerTrackDeref (expensive).");
    1289 
    1290 # undef PGM_REG_COUNTER
    1291 # undef PGM_REG_PROFILE
    12921292#endif
     1293
     1294#undef PGM_REG_COUNTER
     1295#undef PGM_REG_PROFILE
     1296#undef PGM_REG_PROFILE_NS
    12931297
    12941298    /*
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r92341 r92368  
    21762176    /*
    21772177     * Flush the handy pages updates to make sure no shared pages are hiding
    2178      * in there.  (No unlikely if the VM shuts down, apparently.)
     2178     * in there.  (Not unlikely if the VM shuts down, apparently.)
    21792179     */
    21802180    rc = VMMR3CallR0(pVM, VMMR0_DO_PGM_FLUSH_HANDY_PAGES, 0, NULL);
     
    58155815
    58165816/**
    5817  * Response to VMMCALLRING3_PGM_ALLOCATE_LARGE_HANDY_PAGE to allocate a large
    5818  * (2MB) page for use with a nested paging PDE.
    5819  *
    5820  * @returns The following VBox status codes.
    5821  * @retval  VINF_SUCCESS on success.
    5822  * @retval  VINF_EM_NO_MEMORY if we're out of memory.
    5823  *
    5824  * @param   pVM         The cross context VM structure.
    5825  * @param   GCPhys      GC physical start address of the 2 MB range
    5826  */
    5827 VMMR3_INT_DECL(int) PGMR3PhysAllocateLargePage(PVM pVM, RTGCPHYS GCPhys)
    5828 {
    5829 #ifdef PGM_WITH_LARGE_PAGES
    5830     PGM_LOCK_VOID(pVM);
    5831 
    5832     STAM_PROFILE_START(&pVM->pgm.s.Stats.StatAllocLargePage, a);
    5833     uint64_t const msAllocStart = RTTimeMilliTS();
    5834     int rc = VMMR3CallR0(pVM, VMMR0_DO_PGM_ALLOCATE_LARGE_HANDY_PAGE, 0, NULL);
    5835     uint64_t const cMsElapsed   = RTTimeMilliTS() - msAllocStart;
    5836     STAM_PROFILE_STOP(&pVM->pgm.s.Stats.StatAllocLargePage, a);
    5837     if (RT_SUCCESS(rc))
    5838     {
    5839         Assert(pVM->pgm.s.cLargeHandyPages == 1);
    5840 
    5841         uint32_t idPage = pVM->pgm.s.aLargeHandyPage[0].idPage;
    5842         RTHCPHYS HCPhys = pVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys;
    5843         Assert(pVM->pgm.s.aLargeHandyPage[0].fZeroed);
    5844 
    5845         /*
    5846          * Enter the pages into PGM.
    5847          */
    5848         STAM_PROFILE_START(&pVM->pgm.s.Stats.StatClearLargePage, b);
    5849         for (unsigned i = 0; i < _2M/PAGE_SIZE; i++)
    5850         {
    5851             PPGMPAGE pPage;
    5852             rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
    5853             AssertRC(rc);
    5854 
    5855             Assert(PGM_PAGE_IS_ZERO(pPage));
    5856             STAM_COUNTER_INC(&pVM->pgm.s.Stats.StatRZPageReplaceZero);
    5857             pVM->pgm.s.cZeroPages--;
    5858 
    5859             /*
    5860              * Do the PGMPAGE modifications.
    5861              */
    5862             pVM->pgm.s.cPrivatePages++;
    5863             PGM_PAGE_SET_HCPHYS(pVM, pPage, HCPhys);
    5864             PGM_PAGE_SET_PAGEID(pVM, pPage, idPage);
    5865             PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
    5866             PGM_PAGE_SET_PDE_TYPE(pVM, pPage, PGM_PAGE_PDE_TYPE_PDE);
    5867             PGM_PAGE_SET_PTE_INDEX(pVM, pPage, 0);
    5868             PGM_PAGE_SET_TRACKING(pVM, pPage, 0);
    5869 
    5870             /* Somewhat dirty assumption that page ids are increasing. */
    5871             idPage++;
    5872 
    5873             HCPhys += PAGE_SIZE;
    5874             GCPhys += PAGE_SIZE;
    5875             Log3(("PGMR3PhysAllocateLargePage: idPage=%#x HCPhys=%RGp\n", idPage, HCPhys));
    5876         }
    5877         STAM_PROFILE_STOP(&pVM->pgm.s.Stats.StatClearLargePage, b);
    5878 
    5879         /* Flush all TLBs. */
    5880         PGM_INVL_ALL_VCPU_TLBS(pVM);
    5881         pgmPhysInvalidatePageMapTLB(pVM);
    5882 
    5883         pVM->pgm.s.cLargeHandyPages = 0;
    5884     }
    5885 
    5886     if (RT_SUCCESS(rc))
    5887     {
    5888         static uint32_t cTimeOut = 0;
    5889         if (cMsElapsed > 100)
    5890         {
    5891             STAM_COUNTER_INC(&pVM->pgm.s.Stats.StatLargePageOverflow);
    5892             if (   ++cTimeOut > 10
    5893                 || cMsElapsed > 1000 /* more than one second forces an early retirement from allocating large pages. */)
    5894             {
    5895                 /* If repeated attempts to allocate a large page takes more than 100 ms, then we fall back to normal 4k pages.
    5896                  * E.g. Vista 64 tries to move memory around, which takes a huge amount of time.
    5897                  */
    5898                 LogRel(("PGMR3PhysAllocateLargePage: allocating large pages takes too long (last attempt %RU64 ms; nr of timeouts %d); DISABLE\n", cMsElapsed, cTimeOut));
    5899                 PGMSetLargePageUsage(pVM, false);
    5900             }
    5901         }
    5902         else if (cTimeOut > 0)
    5903             cTimeOut--;
    5904     }
    5905 
    5906     PGM_UNLOCK(pVM);
    5907     return rc;
    5908 #else
    5909     RT_NOREF(pVM, GCPhys);
    5910     return VERR_NOT_IMPLEMENTED;
    5911 #endif /* PGM_WITH_LARGE_PAGES */
    5912 }
    5913 
    5914 
    5915 /**
    59165817 * Response to VM_FF_PGM_NEED_HANDY_PAGES and VMMCALLRING3_PGM_ALLOCATE_HANDY_PAGES.
    59175818 *
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r91271 r92368  
    25092509
    25102510        /*
    2511          * Allocates a large page.
    2512          */
    2513         case VMMCALLRING3_PGM_ALLOCATE_LARGE_HANDY_PAGE:
    2514         {
    2515             pVCpu->vmm.s.rcCallRing3 = PGMR3PhysAllocateLargePage(pVM, pVCpu->vmm.s.u64CallRing3Arg);
    2516             break;
    2517         }
    2518 
    2519         /*
    25202511         * Signal a ring 0 hypervisor assertion.
    25212512         * Cancel the longjmp operation that's in progress.
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