VirtualBox

Changeset 5086 in vbox


Ignore:
Timestamp:
Sep 27, 2007 10:12:53 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
24920
Message:

GMM.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/gmm.h

    r5035 r5086  
    2222#include <VBox/gvmm.h>
    2323
     24__BEGIN_DECLS
    2425
    2526/** @defgroup   grp_gmm     GMM - The Global Memory Manager
     
    5354#define NIL_GMM_PAGEID                  0
    5455
     56#if 0 /* wrong - these are guest page pfns and not page ids! */
     57/** Special Page ID used by unassigned pages. */
     58#define GMM_PAGEID_UNASSIGNED           0x0fffffffU
     59/** Special Page ID used by unsharable pages.
     60 * Like MMIO2, shadow and heap. This is for later, obviously. */
     61#define GMM_PAGEID_UNSHARABLE           0x0ffffffeU
     62/** The end of the valid Page IDs. This is the first special one. */
     63#define GMM_PAGEID_END                  0x0ffffff0U
     64#endif
     65
    5566
    5667/**
     
    6273    GMMOCPOLICY_INVALID = 0,
    6374    /** No over-commitment, fully backed.
    64      * The GMM guarantees that it will be able to allocate all of the 
     75     * The GMM guarantees that it will be able to allocate all of the
    6576     * guest RAM for a VM with OC policy. */
    6677    GMMOCPOLICY_NO_OC,
     
    7990{
    8091    /** The usual invalid 0 value. */
    81     GMMPRIORITY_INVALID = 0,
    82     /** High - avoid interrupting it if at all possible */
     92    GMMPRIORITY_INVALID = 0,
     93    /** High.
     94     * When ballooning, ask these VMs last.
     95     * When running out of memory, try not to interrupt these VMs. */
    8396    GMMPRIORITY_HIGH,
    84     /** Normal - pause, save it or kill it. */
     97    /** Normal.
     98     * When ballooning, don't wait to ask these.
     99     * When running out of memory, pause, save and/or kill these VMs. */
    85100    GMMPRIORITY_NORMAL,
    86     /** Low - save or kill it. */
     101    /** Low.
     102     * When ballooning, maximize these first.
     103     * When running out of memory, save or kill these VMs. */
    87104    GMMPRIORITY_LOW,
    88105    /** The end of the valid priority range. */
    89     GMMPRIORITY_END = 0, 
     106    GMMPRIORITY_END = 0,
    90107    /** The custom 32-bit type blowup. */
    91108    GMMPRIORITY_32BIT_HACK = 0x7fffffff
     
    93110
    94111
     112/**
     113 * GMM Memory Accounts.
     114 */
     115typedef enum GMMACCOUNT
     116{
     117    /** The customary invalid zero entry. */
     118    GMMACCOUNT_INVALID = 0,
     119    /** Account with the base allocations. */
     120    GMMACCOUNT_BASE,
     121    /** Account with the shadow allocations. */
     122    GMMACCOUNT_SHADOW,
     123    /** Account with the fixed allocations. */
     124    GMMACCOUNT_FIXED,
     125    /** The end of the valid values. */
     126    GMMACCOUNT_END,
     127    /** The usual 32-bit value to finish it off. */
     128    GMMACCOUNT_32BIT_HACK = 0x7fffffff
     129} GMMACCOUNT;
     130
     131
     132/**
     133 * A page descriptor for use when freeing pages.
     134 * See GMMR0FreePages, GMMR0BalloonedPages.
     135 */
     136typedef struct GMMFREEPAGEDESC
     137{
     138    /** The Page ID of the page to be freed. */
     139    uint32_t idPage;
     140} GMMFREEPAGEDESC;
     141/** Pointer to a page descriptor for freeing pages. */
     142typedef GMMFREEPAGEDESC *PGMMFREEPAGEDESC;
     143
     144
     145/**
     146 * A page descriptor for use when updating and allocating pages.
     147 *
     148 * This is a bit complicated because we want to do as much as possible
     149 * with the same structure.
     150 */
     151typedef struct GMMPAGEDESC
     152{
     153    /** The physical address of the page.
     154     *
     155     * @input   GMMR0AllocateHandyPages expects the guest physical address
     156     *          to update the GMMPAGE structure with. Pass GMM_GCPHYS_UNSHARABLE
     157     *          when appropriate and NIL_RTHCPHYS when the page wasn't used
     158     *          for any specific guest address.
     159     *
     160     *          GMMR0AllocatePage expects the guest physical address to put in
     161     *          the GMMPAGE structure for the page it allocates for this entry.
     162     *          Pass NIL_RTHCPHYS and GMM_GCPHYS_UNSHARABLE as above.
     163     *
     164     * @output  The host physical address of the allocated page.
     165     *          NIL_RTHCPHYS on allocation failure.
     166     *
     167     * ASSUMES: sizeof(RTHCPHYS) >= sizeof(RTGCPHYS).
     168     */
     169    RTHCPHYS                    HCPhysGCPhys;
     170
     171    /** The Page ID.
     172     *
     173     * @intput  GMMR0AllocateHandyPages expects the Page ID of the page to
     174     *          update here. NIL_GMM_PAGEID means no page should be updated.
     175     *
     176     *          GMMR0AllocatePages requires this to be initialized to
     177     *          NIL_GMM_PAGEID currently.
     178     *
     179     * @output  The ID of the page, NIL_GMM_PAGEID if the allocation failed.
     180     */
     181    uint32_t                    idPage;
     182
     183    /** The Page ID of the shared page was replaced by this page.
     184     *
     185     * @input   GMMR0AllocateHandyPages expects this to indicate a shared
     186     *          page that has been replaced by this page and should have its
     187     *          reference counter decremented and perhaps be freed up. Use
     188     *          NIL_GMM_PAGEID if no shared page was involved.
     189     *
     190     *          All other APIs expects NIL_GMM_PAGEID here.
     191     *
     192     * @output  All APIs sets this to NIL_GMM_PAGEID.
     193     */
     194    uint32_t                    idSharedPage;
     195} GMMPAGEDESC;
     196AssertCompileSize(GMMPAGEDESC, 16);
     197/** Pointer to a page allocation. */
     198typedef GMMPAGEDESC *PGMMPAGEDESC;
     199
     200/** GMMPAGEDESC::HCPhysGCPhys value that indicates that the page is shared. */
     201#define GMM_GCPHYS_UNSHARABLE   (RTHCPHYS)(0xfffffff0)
     202
     203
     204GMMR0DECL(int)  GMMR0Init(void);
     205GMMR0DECL(void) GMMR0Term(void);
     206GMMR0DECL(void) GMMR0InitPerVMData(PGVM pGVM);
     207GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM);
     208GMMR0DECL(int)  GMMR0InitialReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages,
     209                                        GMMOCPOLICY enmPolicy, GMMPRIORITY enmPriority);
     210GMMR0DECL(int)  GMMR0UpdateReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages);
     211GMMR0DECL(int)  GMMR0AllocateHandyPages(PVM pVM, uint32_t cPagesToUpdate, uint32_t cPagesToAlloc, PGMMPAGEDESC paPages);
     212GMMR0DECL(int)  GMMR0AllocatePages(PVM pVM, uint32_t cPages, PGMMPAGEDESC paPages, GMMACCOUNT enmAccount);
     213GMMR0DECL(int)  GMMR0FreePages(PVM pVM, uint32_t cPages, PGMMFREEPAGEDESC paPages, GMMACCOUNT enmAccount);
     214GMMR0DECL(int)  GMMR0BalloonedPages(PVM pVM, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages);
     215
     216
    95217/** @} */
    96218
     219__END_DECLS
     220
    97221#endif
    98222
  • trunk/src/VBox/VMM/PGM.cpp

    r5017 r5086  
    331331 *      4GB guest ram, 1M pages:   16MB + 12MB(+) =  28MB
    332332 *     32GB guest ram, 8M pages:  128MB + 96MB(+) = 224MB
     333 *
     334 * UPDATE - 2007-09-27:
     335 * Will need a ballooned flag/state too because we cannot
     336 * trust the guest 100% and reporting the same page as ballooned more
     337 * than once will put the GMM off balance.
    333338 *
    334339 *
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r5064 r5086  
    6868 *
    6969 *
    70  * @section sec_gmm_costs      Page Allocation Strategy
     70 * @section sec_gmm_alloc_strat Page Allocation Strategy
    7171 *
    7272 * The strategy for allocating pages has to take fragmentation and shared
     
    423423    GMMCHUNKFREESET     Shared;
    424424
    425     /** The number of allocated pages. */
    426     uint64_t            cPages;
     425    /** The maximum number of pages we're allowed to allocate.
     426     * @gcfgm   64-bit GMM/MaxPages Direct.
     427     * @gcfgm   32-bit GMM/PctPages Relative to the number of host pages. */
     428    uint64_t            cMaxPages;
     429    /** The number of pages that has been reserved.
     430     * The deal is that cReservedPages - cOverCommittedPages <= cMaxPages. */
     431    uint64_t            cReservedPages;
     432    /** The number of pages that we have over-committed in reservations. */
     433    uint64_t            cOverCommittedPages;
     434    /** The number of actually allocated (committed if you like) pages. */
     435    uint64_t            cAllocatedPages;
     436    /** The number of pages that are shared. A subset of cAllocatedPages. */
     437    uint64_t            cSharedPages;
     438    /** The number of allocation chunks.
     439     * (The number of pages we've allocated from the host can be derived from this.) */
     440    uint32_t            cChunks;
     441
    427442    /** The legacy mode indicator.
    428443     * This is determined at initialization time. */
    429444    bool                fLegacyMode;
    430     /** The number of active VMs. */
    431     uint16_t            cActiveVMs;
     445    /** The number of registered VMs. */
     446    uint16_t            cRegisteredVMs;
    432447} GMM;
    433448/** Pointer to the GMM instance. */
     
    615630    AssertRelease(RT_SIZEOFMEMB(GVM,gmm.s) <= RT_SIZEOFMEMB(GVM,gmm.padding));
    616631
    617     //pGVM->gmm.s.cBasePages = 0;
    618     //pGVM->gmm.s.cPrivatePages = 0;
    619     //pGVM->gmm.s.cSharedPages = 0;
    620632    pGVM->gmm.s.enmPolicy = GMMOCPOLICY_INVALID;
    621633    pGVM->gmm.s.enmPriority = GMMPRIORITY_INVALID;
     
    656668     * references behind (shouldn't happen of course, but you never know).
    657669     */
    658     pGMM->cActiveVMs--;
    659     if (!pGMM->cActiveVMs)
     670    pGMM->cRegisteredVMs--;
     671    if (!pGMM->cRegisteredVMs)
    660672    {
    661673
     
    764776 * future allocations requests will fail as well.
    765777 *
     778 * These are just the initial reservations made very very early during the VM creation
     779 * process and will be adjusted later in the GMMR0UpdateReservation call after the
     780 * ring-3 init has completed.
     781 *
    766782 * @returns VBox status code.
    767783 * @retval  VERR_GMM_NOT_SUFFICENT_MEMORY
     
    769785 *
    770786 * @param   pVM             Pointer to the shared VM structure.
    771  * @param   cBasePages      The number of pages of RAM. This is *only* the RAM, it does
    772  *                          not take additional pages for the ROMs and MMIO2 into account.
    773  *                          These allocations will have to be reported when the initialization
    774  *                          process has completed.
    775  * @param   cShadowPages    The max number of pages that will be allocated for shadow pageing structures.
     787 * @param   cBasePages      The number of pages that may be allocated for the base RAM and ROMs.
     788 *                          This does not include MMIO2 and similar.
     789 * @param   cShadowPages    The number of pages that may be allocated for shadow pageing structures.
     790 * @param   cFixedPages     The number of pages that may be allocated for fixed objects like the
     791 *                          hyper heap, MMIO2 and similar.
    776792 * @param   enmPolicy       The OC policy to use on this VM.
    777793 * @param   enmPriority     The priority in an out-of-memory situation.
    778794 */
    779 GMMR0DECL(int) GMMR0InitialReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, GMMOCPOLICY enmPolicy, GMMPRIORITY enmPriority)
    780 {
    781     LogFlow(("GMMR0InitialReservation: pVM=%p cBasePages=%#llx cShadowPages=%#x enmPolicy=%d enmPriority=%d\n",
    782              pVM, cBasePages, cShadowPages, enmPolicy, enmPriority));
     795GMMR0DECL(int) GMMR0InitialReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages,
     796                                       GMMOCPOLICY enmPolicy, GMMPRIORITY enmPriority)
     797{
     798    LogFlow(("GMMR0InitialReservation: pVM=%p cBasePages=%#llx cShadowPages=%#x cFixedPages=%#x enmPolicy=%d enmPriority=%d\n",
     799             pVM, cBasePages, cShadowPages, cFixedPages, enmPolicy, enmPriority));
    783800
    784801    /*
     
    788805    GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR);
    789806    PGVM pGVM = GVMMR0ByVM(pVM);
    790     if (!pVM)
     807    if (!pGVM)
    791808        return VERR_INVALID_PARAMETER;
     809
     810    AssertReturn(cBasePages, VERR_INVALID_PARAMETER);
     811    AssertReturn(cShadowPages, VERR_INVALID_PARAMETER);
     812    AssertReturn(cFixedPages, VERR_INVALID_PARAMETER);
     813    AssertReturn(enmPolicy > GMMOCPOLICY_INVALID && enmPolicy < GMMOCPOLICY_END, VERR_INVALID_PARAMETER);
     814    AssertReturn(enmPriority > GMMPRIORITY_INVALID && enmPriority < GMMPRIORITY_END, VERR_INVALID_PARAMETER);
    792815
    793816    int rc = RTSemFastMutexRequest(pGMM->Mtx);
    794817    AssertRC(rc);
    795818
    796 
    797     pGMM->cActiveVMs++;
    798 
    799 
     819    if (    !pGVM->gmm.s.Reserved.cBasePages
     820        &&  !pGVM->gmm.s.Reserved.cFixedPages
     821        &&  !pGVM->gmm.s.Reserved.cShadowPages)
     822    {
     823        /*
     824         * Check if we can accomodate this.
     825         */
     826        /* ... later ... */
     827        if (RT_SUCCESS(rc))
     828        {
     829            /*
     830             * Update the records.
     831             */
     832            pGVM->gmm.s.Reserved.cBasePages = cBasePages;
     833            pGVM->gmm.s.Reserved.cFixedPages = cFixedPages;
     834            pGVM->gmm.s.Reserved.cShadowPages = cShadowPages;
     835            pGVM->gmm.s.enmPolicy = enmPolicy;
     836            pGVM->gmm.s.enmPriority = enmPriority;
     837            pGVM->gmm.s.fMayAllocate = true;
     838
     839            pGMM->cReservedPages += cBasePages + cFixedPages + cShadowPages;
     840            pGMM->cRegisteredVMs++;
     841        }
     842    }
     843    else
     844        rc = VERR_WRONG_ORDER;
    800845
    801846    RTSemFastMutexRelease(pGMM->Mtx);
     
    812857 *
    813858 * @param   pVM             Pointer to the shared VM structure.
    814  * @param   cExtraPages     The number of pages that makes up ROM ranges outside the normal
    815  *                          RAM and MMIO2 memory.
    816  * @param   cMisc           Miscellaneous fixed commitments like the heap, VM structure and such.
    817  */
    818 GMMR0DECL(int) GMMR0ReservationUpdate(PVM pVM, uint64_t cExtraPages)
    819 {
    820     LogFlow(("GMMR0ReservationUpdate: pVM=%p cExtraPages=%#llx\n", pVM, cExtraPages));
     859 * @param   cBasePages      The number of pages that may be allocated for the base RAM and ROMs.
     860 *                          This does not include MMIO2 and similar.
     861 * @param   cShadowPages    The number of pages that may be allocated for shadow pageing structures.
     862 * @param   cFixedPages     The number of pages that may be allocated for fixed objects like the
     863 *                          hyper heap, MMIO2 and similar.
     864 * @param   enmPolicy       The OC policy to use on this VM.
     865 * @param   enmPriority     The priority in an out-of-memory situation.
     866 */
     867GMMR0DECL(int) GMMR0UpdateReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages)
     868{
     869    LogFlow(("GMMR0UpdateReservation: pVM=%p cBasePages=%#llx cShadowPages=%#x cFixedPages=%#x\n",
     870             pVM, cBasePages, cShadowPages, cFixedPages));
    821871
    822872    /*
     
    826876    GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR);
    827877    PGVM pGVM = GVMMR0ByVM(pVM);
    828     if (!pVM)
     878    if (!pGVM)
    829879        return VERR_INVALID_PARAMETER;
     880
     881    AssertReturn(cBasePages, VERR_INVALID_PARAMETER);
     882    AssertReturn(cShadowPages, VERR_INVALID_PARAMETER);
     883    AssertReturn(cFixedPages, VERR_INVALID_PARAMETER);
    830884
    831885    int rc = RTSemFastMutexRequest(pGMM->Mtx);
    832886    AssertRC(rc);
    833887
    834 
     888    if (    pGVM->gmm.s.Reserved.cBasePages
     889        &&  pGVM->gmm.s.Reserved.cFixedPages
     890        &&  pGVM->gmm.s.Reserved.cShadowPages)
     891    {
     892        /*
     893         * Check if we can accomodate this.
     894         */
     895        /* ... later ... */
     896        if (RT_SUCCESS(rc))
     897        {
     898            /*
     899             * Update the records.
     900             */
     901            pGMM->cReservedPages -= pGVM->gmm.s.Reserved.cBasePages
     902                                  + pGVM->gmm.s.Reserved.cFixedPages
     903                                  + pGVM->gmm.s.Reserved.cShadowPages;
     904            pGMM->cReservedPages += cBasePages + cFixedPages + cShadowPages;
     905
     906            pGVM->gmm.s.Reserved.cBasePages = cBasePages;
     907            pGVM->gmm.s.Reserved.cFixedPages = cFixedPages;
     908            pGVM->gmm.s.Reserved.cShadowPages = cShadowPages;
     909        }
     910    }
     911    else
     912        rc = VERR_WRONG_ORDER;
    835913
    836914    RTSemFastMutexRelease(pGMM->Mtx);
    837     LogFlow(("GMMR0ReservationUpdate: returns %Rrc\n", rc));
     915    LogFlow(("GMMR0UpdateReservation: returns %Rrc\n", rc));
    838916    return rc;
    839917}
    840918
    841919
    842 
     920/**
     921 * Updates the previous allocations and allocates more pages.
     922 *
     923 * The handy pages are always taken from the 'base' memory account.
     924 *
     925 * @returns VBox status code:
     926 * @retval  xxx
     927 *
     928 * @param   pVM                 Pointer to the shared VM structure.
     929 * @param   cPagesToUpdate      The number of pages to update (starting from the head).
     930 * @param   cPagesToAlloc       The number of pages to allocate (starting from the head).
     931 * @param   paPages             The array of page descriptors.
     932 *                              See GMMPAGEDESC for details on what is expected on input.
     933 */
     934GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, uint32_t cPagesToUpdate, uint32_t cPagesToAlloc, PGMMPAGEDESC paPages)
     935{
     936    return VERR_NOT_IMPLEMENTED;
     937}
     938
     939
     940/**
     941 * Allocate one or more pages.
     942 *
     943 * This is typically used for ROMs and MMIO2 (VRAM) during VM creation.
     944 *
     945 * @returns VBox status code:
     946 * @retval  xxx
     947 *
     948 * @param   pVM                 Pointer to the shared VM structure.
     949 * @param   cPages              The number of pages to allocate.
     950 * @param   paPages             Pointer to the page descriptors.
     951 *                              See GMMPAGEDESC for details on what is expected on input.
     952 * @param   enmAccount          The account to charge.
     953 */
     954GMMR0DECL(int) GMMR0AllocatePages(PVM pVM, uint32_t cPages, PGMMPAGEDESC paPages, GMMACCOUNT enmAccount)
     955{
     956    return VERR_NOT_IMPLEMENTED;
     957}
     958
     959
     960/**
     961 * Free one or more pages.
     962 *
     963 * This is typically used at reset time or power off.
     964 *
     965 * @returns VBox status code:
     966 * @retval  xxx
     967 *
     968 * @param   pVM                 Pointer to the shared VM structure.
     969 * @param   cPages              The number of pages to allocate.
     970 * @param   paPages             Pointer to the page descriptors containing the Page IDs for each page.
     971 * @param   enmAccount          The account this relates to.
     972 */
     973GMMR0DECL(int) GMMR0FreePages(PVM pVM, uint32_t cPages, PGMMFREEPAGEDESC paPages, GMMACCOUNT enmAccount)
     974{
     975    return VERR_NOT_IMPLEMENTED;
     976}
     977
     978
     979/**
     980 * Report ballooned pages optionally together with be page to free.
     981 *
     982 * The pages to be freed are always base (RAM) pages.
     983 *
     984 * @returns VBox status code:
     985 * @retval  xxx
     986 *
     987 * @param   pVM                 Pointer to the shared VM structure.
     988 * @param   cBalloonedPages     The number of pages that was ballooned.
     989 * @param   cPagesToFree        The number of pages to be freed.
     990 * @param   paPages             Pointer to the page descriptors for the pages that's to be freed.
     991 */
     992GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages)
     993{
     994    return VERR_NOT_IMPLEMENTED;
     995}
     996
     997
  • trunk/src/VBox/VMM/VMMR0/GMMR0Internal.h

    r5064 r5086  
    4545    /** The reservations. */
    4646    GMMVMSIZES      Reserved;
    47     /** The actual allocations. */
     47    /** The actual allocations.
     48     * This includes both private and shared page allocations. */
    4849    GMMVMSIZES      Allocated;
     50
    4951    /** The current number of private pages. */
    5052    uint64_t        cPrivatePages;
    5153    /** The current number of shared pages. */
    5254    uint64_t        cSharedPages;
     55    /** The current over-comitment policy. */
     56    GMMOCPOLICY     enmPolicy;
     57    /** The VM priority for arbitrating VMs in low and out of memory situation.
     58     * Like which VMs to start sequeezing first. */
     59    GMMPRIORITY     enmPriority;
     60
    5361    /** The current number of ballooned pages. */
    5462    uint64_t        cBalloonedPages;
    5563    /** The max number of pages that can be ballooned. */
    5664    uint64_t        cMaxBalloonedPages;
    57     /** The current over-comitment policy. */
    58     GMMOCPOLICY     enmPolicy;
    59     /** The VM priority for arbitrating VMs in an out-of-memory situation. */
    60     GMMPRIORITY     enmPriority;
     65    /** The number of pages we've currently requested the guest to give us. */
     66    uint64_t        cReqBalloonedPages;
     67    /** Whether ballooning is enabled or not. */
     68    bool            fBallooningEnabled;
     69
    6170    /** Whether the VM is allowed to allocate memory or not.
    6271     * This is used when the reservation update request fails or when the VM has
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