VirtualBox

Ignore:
Timestamp:
Nov 11, 2021 1:31:21 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
148222
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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 *
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette