VirtualBox

vbox的更動 41652 路徑 trunk/src/VBox/Runtime/r0drv


忽略:
時間撮記:
2012-6-11 下午02:13:01 (12 年 以前)
作者:
vboxsync
訊息:

Runtime/r0drv/solaris: Proper high limit constraint on PHYS_NC allocations, fall back to contig_alloc().

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c

    r41629 r41652  
    6868     *  allocation. */
    6969    bool                fLargePage;
     70    /** Whether we have individual pages or a kernel-mapped virtual memory block in
     71     *  an RTR0MEMOBJTYPE_PHYS_NC allocation. */
     72    bool                fIndivPages;
    7073} RTR0MEMOBJSOL, *PRTR0MEMOBJSOL;
    7174
     
    154157    {
    155158        /*
    156          * Lock this page into memory "long term" to prevent paging out of this page.
     159         * Lock this page into memory "long term" to prevent paging out of this page
     160         * when we drop the page lock temporarily (during free).
    157161         */
    158162        page_pp_lock(pPage, 0 /* COW */, 1 /* Kernel */);
     
    169173 * Allocates physical, non-contiguous memory of pages.
    170174 *
    171  * @param uPhysHi   The upper physical address limit (inclusive).
    172175 * @param puPhys    Where to store the physical address of first page. Optional,
    173176 *                  can be NULL.
     
    176179 * @return Array of allocated pages, NULL on failure.
    177180 */
    178 static page_t **rtR0MemObjSolPagesAlloc(uint64_t uPhysHi, uint64_t *puPhys, size_t cb)
     181static page_t **rtR0MemObjSolPagesAlloc(uint64_t *puPhys, size_t cb)
    179182{
    180183    /*
     
    191194     * Non-pageable memory reservation request for _4K pages, don't sleep.
    192195     */
    193     pgcnt_t cPages = (cb + PAGE_SIZE - 1) >> PAGE_SHIFT;
     196    size_t cPages = (cb + PAGE_SIZE - 1) >> PAGE_SHIFT;
    194197    int rc = page_resv(cPages, KM_NOSLEEP);
    195198    if (rc)
     
    203206             * we don't yet have the 'virtAddr' to which this memory may be mapped.
    204207             */
    205             caddr_t virtAddr = NULL;
     208            caddr_t virtAddr = 0;
    206209            for (size_t i = 0; i < cPages; i++, virtAddr += PAGE_SIZE)
    207210            {
    208                 uint32_t cTries = 3;
    209                 page_t *pPage   = NULL;
    210                 while (cTries > 0)
    211                 {
    212                     /*
    213                      * Get a page from the free list locked exclusively. The page will be named (hashed in)
    214                      * and we rely on it during free. Downgrade the page to a shared lock to prevent the page
    215                      * from being relocated.
    216                      */
    217                     pPage = rtR0MemObjSolPageAlloc(virtAddr, PAGE_SIZE);
    218                     if (!pPage)
    219                         break;
    220 
    221                     /*
    222                      * Check if the physical address backing the page is within the requested range if any.
    223                      * If it isn't, discard the page and try again.
    224                      */
    225                     /** @todo Remove this constraint here, force all high-limit applicable cases
    226                      *        through rtR0SolMemAlloc() */
    227                     if (uPhysHi != NIL_RTHCPHYS)
    228                     {
    229                         uint64_t uPhys = rtR0MemObjSolPagePhys(pPage);
    230                         if (uPhys > uPhysHi)
    231                         {
    232                             page_destroy(pPage, 0 /* move it to the free list */);
    233                             pPage = NULL;
    234                             --cTries;
    235                             continue;
    236                         }
    237                     }
    238 
    239                     ppPages[i] = pPage;
    240                     break;
    241                 }
    242 
     211                /*
     212                 * Get a page from the free list locked exclusively. The page will be named (hashed in)
     213                 * and we rely on it during free. Downgrade the page to a shared lock to prevent the page
     214                 * from being relocated.
     215                 */
     216                page_t *pPage = rtR0MemObjSolPageAlloc(virtAddr, PAGE_SIZE);
    243217                if (RT_UNLIKELY(!pPage))
    244218                {
     
    252226                    return NULL;
    253227                }
     228
     229                ppPages[i] = pPage;
    254230            }
    255231
     
    595571
    596572        case RTR0MEMOBJTYPE_PHYS_NC:
    597             rtR0MemObjSolPagesFree(pMemSolaris->pvHandle, pMemSolaris->Core.cb);
     573            if (pMemSolaris->fIndivPages)
     574                rtR0MemObjSolPagesFree(pMemSolaris->pvHandle, pMemSolaris->Core.cb);
     575            else
     576                rtR0SolMemFree(pMemSolaris->Core.pv, pMemSolaris->Core.cb);
    598577            break;
    599578
     
    688667        return VERR_NO_MEMORY;
    689668
    690     uint64_t PhysAddr = UINT64_MAX;
    691     void *pvPages = rtR0MemObjSolPagesAlloc((uint64_t)PhysHighest, &PhysAddr, cb);
    692     if (!pvPages)
    693     {
    694         LogRel(("rtR0MemObjNativeAllocPhysNC: rtR0MemObjSolPagesAlloc failed for cb=%u.\n", cb));
    695         rtR0MemObjDelete(&pMemSolaris->Core);
    696         return VERR_NO_MEMORY;
    697     }
    698     pMemSolaris->Core.pv   = NULL;
    699     pMemSolaris->pvHandle  = pvPages;
    700 
    701     Assert(PhysAddr != UINT64_MAX);
    702     Assert(!(PhysAddr & PAGE_OFFSET_MASK));
    703     *ppMem = &pMemSolaris->Core;
    704     return VINF_SUCCESS;
     669    if (PhysHighest == NIL_RTHCPHYS)
     670    {
     671        uint64_t PhysAddr = UINT64_MAX;
     672        void *pvPages = rtR0MemObjSolPagesAlloc(&PhysAddr, cb);
     673        if (!pvPages)
     674        {
     675            LogRel(("rtR0MemObjNativeAllocPhysNC: rtR0MemObjSolPagesAlloc failed for cb=%u.\n", cb));
     676            rtR0MemObjDelete(&pMemSolaris->Core);
     677            return VERR_NO_MEMORY;
     678        }
     679        Assert(PhysAddr != UINT64_MAX);
     680        Assert(!(PhysAddr & PAGE_OFFSET_MASK));
     681
     682        pMemSolaris->Core.pv     = NULL;
     683        pMemSolaris->pvHandle    = pvPages;
     684        pMemSolaris->fIndivPages = true;
     685        *ppMem = &pMemSolaris->Core;
     686        return VINF_SUCCESS;
     687    }
     688    else
     689    {
     690        /*
     691         * If we must satisfy an upper limit constraint, it isn't feasible to grab individual pages.
     692         * We fall back to using contig_alloc().
     693         */
     694        uint64_t PhysAddr = UINT64_MAX;
     695        void *pvMem = rtR0SolMemAlloc(PhysHighest, &PhysAddr, cb, PAGE_SIZE, false /* fContig */);
     696        if (!pvMem)
     697        {
     698            LogRel(("rtR0MemObjNativeAllocPhysNC: rtR0SolMemAlloc failed for cb=%u PhysHighest=%RHp.\n", cb, PhysHighest));
     699            rtR0MemObjDelete(&pMemSolaris->Core);
     700            return VERR_NO_MEMORY;
     701        }
     702        Assert(PhysAddr != UINT64_MAX);
     703        Assert(!(PhysAddr & PAGE_OFFSET_MASK));
     704
     705        pMemSolaris->Core.pv     = pvMem;
     706        pMemSolaris->pvHandle    = NULL;
     707        pMemSolaris->fIndivPages = false;
     708        *ppMem = &pMemSolaris->Core;
     709        return VINF_SUCCESS;
     710    }
    705711
    706712#else /* 32 bit: */
     
    10011007         * Prepare the pages for mapping according to type.
    10021008         */
    1003         if (pMemToMapSolaris->Core.enmType == RTR0MEMOBJTYPE_PHYS_NC)
     1009        if (   pMemToMapSolaris->Core.enmType == RTR0MEMOBJTYPE_PHYS_NC
     1010            && pMemToMapSolaris->fIndivPages)
    10041011        {
    10051012            page_t **ppPages = pMemToMapSolaris->pvHandle;
     1013            AssertPtr(ppPages);
    10061014            for (size_t iPage = 0; iPage < cPages; iPage++)
    10071015                paPhysAddrs[iPage] = rtR0MemObjSolPagePhys(ppPages[iPage]);
     
    10861094    {
    10871095        case RTR0MEMOBJTYPE_PHYS_NC:
    1088             if (pMemSolaris->Core.u.Phys.fAllocated)
     1096            if (   pMemSolaris->Core.u.Phys.fAllocated
     1097                || !pMemSolaris->fIndivPages)
    10891098            {
    10901099                uint8_t *pb = (uint8_t *)pMemSolaris->Core.pv + ((size_t)iPage << PAGE_SHIFT);
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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