VirtualBox

Changeset 36960 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
May 4, 2011 4:08:29 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
71556
Message:

PGM,MM: Heap and shadow pool size adjustments for large memory configs.

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

Legend:

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

    r35346 r36960  
    4545
    4646
    47 DECLINLINE(uint32_t) mmR3ComputeHyperHeapSize(PVM pVM, bool fCanUseLargerHeap)
    48 {
    49     bool fHwVirtExtForced = VMMIsHwVirtExtForced(pVM);
    50 
    51     /* Newer chipset allows for much more devices, putting additional pressure on hyperheap */
    52     /* @todo: maybe base hyperheap size upon number of devices attached too */
     47/**
     48 * Determin the default heap size.
     49 *
     50 * @returns The heap size in bytes.
     51 * @param   pVM     The VM handle.
     52 */
     53static uint32_t mmR3ComputeHyperHeapSize(PVM pVM)
     54{
     55    /*
     56     * Gather parameters.
     57     */
     58    bool const  fHwVirtExtForced = VMMIsHwVirtExtForced(pVM)
     59                                || pVM->cCpus > 1;
     60
     61    bool        fCanUseLargerHeap;
     62    int rc = CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "MM"), "CanUseLargerHeap", &fCanUseLargerHeap, false);
     63    AssertStmt(RT_SUCCESS(rc), fCanUseLargerHeap = false);
     64
     65    uint64_t    cbRam;
     66    rc = CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &cbRam);
     67    AssertStmt(RT_SUCCESS(rc), cbRam = _1G);
     68
     69    /*
     70     * We need to keep saved state compatibility if raw-mode is an option,
     71     * so lets filter out that case first.
     72     */
     73    if (   !fCanUseLargerHeap
     74        && !fHwVirtExtForced
     75        && cbRam < 16*_1G64)
     76        return 1280 * _1K;
     77
     78    /*
     79     * Calculate the heap size.
     80     */
     81    uint32_t cbHeap = _1M;
     82
     83    /* The newer chipset may have more devices attached, putting additional
     84       pressure on the heap. */
    5385    if (fCanUseLargerHeap)
    54         return _2M + pVM->cCpus * 2 * _64K;
    55 
     86        cbHeap += _1M;
     87
     88    /* More CPUs means some extra memory usage. */
    5689    if (pVM->cCpus > 1)
    57         return _1M + pVM->cCpus * 2 * _64K;
    58 
    59     if (fHwVirtExtForced)
    60     {
    61         uint64_t cbRam = 0;
    62         CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &cbRam);
    63 
    64         /* Need a bit more space for large memory guests. (@todo: only for shadow paging!) */
    65         if (cbRam >= _4G)
    66             return _1M;
    67         else
    68             return 640 * _1K;
    69     }
    70     else
    71         /* Size must be kept like this for saved state compatibility (only for raw mode though). */
    72         return 1280*_1K;
     90        cbHeap += pVM->cCpus * _64K;
     91
     92    /* Lots of memory means extra memory consumption as well (pool). */
     93    if (cbRam > 16*_1G64)
     94        cbHeap += _2M; /** @todo figure out extactly how much */
     95
     96    return RT_ALIGN(cbHeap, _256K);
    7397}
    7498
     
    101125     */
    102126    PCFGMNODE pMM = CFGMR3GetChild(CFGMR3GetRoot(pVM), "MM");
    103     bool fCanUseLargerHeap = false;
    104     int rc = CFGMR3QueryBoolDef(pMM, "CanUseLargerHeap", &fCanUseLargerHeap, false);
    105     uint32_t cbHyperHeap = mmR3ComputeHyperHeapSize(pVM, fCanUseLargerHeap);
    106     rc = CFGMR3QueryU32Def(pMM, "cbHyperHeap", &cbHyperHeap, cbHyperHeap);
     127    uint32_t cbHyperHeap;
     128    int rc = CFGMR3QueryU32Def(pMM, "cbHyperHeap", &cbHyperHeap, mmR3ComputeHyperHeapSize(pVM));
    107129    AssertLogRelRCReturn(rc, rc);
    108130
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r36911 r36960  
    39963996    else
    39973997    {
     3998        /** @todo this may fail because of /proc/sys/vm/max_map_count, so we
     3999         *        should probably restrict ourselves on linux. */
    39984000        AssertRC(rc);
    39994001#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
  • trunk/src/VBox/VMM/VMMR3/PGMPool.cpp

    r36891 r36960  
    135135int pgmR3PoolInit(PVM pVM)
    136136{
     137    int rc;
     138
    137139    AssertCompile(NIL_PGMPOOL_IDX == 0);
    138140    /* pPage->cLocked is an unsigned byte. */
     
    144146    PCFGMNODE pCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "/PGM/Pool");
    145147
    146     /* Default pgm pool size equals 1024 pages. */
    147     uint16_t cMaxPages = 4*_1M >> PAGE_SHIFT;
    148 
    149 #if HC_ARCH_BITS == 64
    150     uint64_t cbRam = 0;
    151     CFGMR3QueryU64Def(CFGMR3GetRoot(pVM), "RamSize", &cbRam, 0);
    152 
    153     /* We should increase the pgm pool size for guests with more than 2 GB of ram */
    154     if (cbRam >= UINT64_C(2) * _1G)
    155     {
    156         /* In the nested paging case we require 2 + 513 * (cbRam/1GB) pages to
    157          * store all page table descriptors.
    158          */
    159         uint64_t u64MaxPages = cbRam  / (_1G / UINT64_C(512));
    160         if (u64MaxPages > PGMPOOL_IDX_LAST)
    161             cMaxPages = PGMPOOL_IDX_LAST;
    162         else
    163             cMaxPages = (uint16_t)u64MaxPages;
    164     }
    165 #endif
    166 
    167     /** @cfgm{/PGM/Pool/MaxPages, uint16_t, #pages, 16, 0x3fff, 1024}
     148    /* Default pgm pool size is 1024 pages (4MB). */
     149    uint16_t cMaxPages = 1024;
     150
     151    /* Adjust it up relative to the RAM size, using the nested paging formula. */
     152    uint64_t cbRam;
     153    rc = CFGMR3QueryU64Def(CFGMR3GetRoot(pVM), "RamSize", &cbRam, 0); AssertRCReturn(rc, rc);
     154    uint64_t u64MaxPages = (cbRam >> 9)
     155                         + (cbRam >> 18)
     156                         + (cbRam >> 27)
     157                         + 32 * PAGE_SIZE;
     158    u64MaxPages >>= PAGE_SHIFT;
     159    if (u64MaxPages > PGMPOOL_IDX_LAST)
     160        cMaxPages = PGMPOOL_IDX_LAST;
     161    else
     162        cMaxPages = (uint16_t)u64MaxPages;
     163
     164    /** @cfgm{/PGM/Pool/MaxPages, uint16_t, #pages, 16, 0x3fff, F(ram-size)}
    168165     * The max size of the shadow page pool in pages. The pool will grow dynamically
    169166     * up to this limit.
    170167     */
    171     int rc = CFGMR3QueryU16Def(pCfg, "MaxPages", &cMaxPages, cMaxPages);
     168    rc = CFGMR3QueryU16Def(pCfg, "MaxPages", &cMaxPages, cMaxPages);
    172169    AssertLogRelRCReturn(rc, rc);
    173170    AssertLogRelMsgReturn(cMaxPages <= PGMPOOL_IDX_LAST && cMaxPages >= RT_ALIGN(PGMPOOL_IDX_FIRST, 16),
    174171                          ("cMaxPages=%u (%#x)\n", cMaxPages, cMaxPages), VERR_INVALID_PARAMETER);
    175172    cMaxPages = RT_ALIGN(cMaxPages, 16);
     173    if (cMaxPages > PGMPOOL_IDX_LAST)
     174        cMaxPages = PGMPOOL_IDX_LAST;
     175    LogRel(("PGMPool: cMaxPages=%u (u64MaxPages=%llu)\n", cMaxPages, u64MaxPages));
    176176
    177177    /** todo:
    178178     * We need to be much more careful with our allocation strategy here.
    179      * For nested paging we don't need pool user info nor extents at all, but we can't check for nested paging here (too early during init to get a confirmation it can be used)
    180      * The default for large memory configs is a bit large for shadow paging, so I've restricted the extent maximum to 2k (2k * 16 = 32k of hyper heap)
     179     * For nested paging we don't need pool user info nor extents at all, but
     180     * we can't check for nested paging here (too early during init to get a
     181     * confirmation it can be used).  The default for large memory configs is a
     182     * bit large for shadow paging, so I've restricted the extent maximum to 8k
     183     * (8k * 16 = 128k of hyper heap).
    181184     *
    182185     * Also when large page support is enabled, we typically don't need so much,
     
    196199                          ("cMaxUsers=%u (%#x)\n", cMaxUsers, cMaxUsers), VERR_INVALID_PARAMETER);
    197200
    198     /** @cfgm{/PGM/Pool/MaxPhysExts, uint16_t, #extents, 16, MaxPages * 2, MAX(MaxPages*2,0x3fff)}
     201    /** @cfgm{/PGM/Pool/MaxPhysExts, uint16_t, #extents, 16, MaxPages * 2, MIN(MaxPages*2,8192)}
    199202     * The max number of extents for tracking aliased guest pages.
    200203     */
    201204    uint16_t cMaxPhysExts;
    202     rc = CFGMR3QueryU16Def(pCfg, "MaxPhysExts", &cMaxPhysExts, RT_MAX(cMaxPages * 2, 2048 /* 2k max as this eat too much hyper heap */));
     205    rc = CFGMR3QueryU16Def(pCfg, "MaxPhysExts", &cMaxPhysExts,
     206                           RT_MIN(cMaxPages * 2, 8192 /* 8Ki max as this eat too much hyper heap */));
    203207    AssertLogRelRCReturn(rc, rc);
    204     AssertLogRelMsgReturn(cMaxPhysExts >= 16 && cMaxPages <= PGMPOOL_IDX_LAST,
     208    AssertLogRelMsgReturn(cMaxPhysExts >= 16 && cMaxPhysExts <= PGMPOOL_IDX_LAST,
    205209                          ("cMaxPhysExts=%u (%#x)\n", cMaxPhysExts, cMaxPhysExts), VERR_INVALID_PARAMETER);
    206210
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