VirtualBox

Changeset 41627 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Jun 8, 2012 4:16:04 PM (13 years ago)
Author:
vboxsync
Message:

Runtime/r0drv/solaris: Fix to prevent paging out during freeing of 4K pages, fix unsigned overflow while freeing pages in the failure case and some comment fixes and cleanup.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c

    r41622 r41627  
    151151    KernelSeg.s_as = &kas;
    152152    page_t *pPage = page_create_va(&g_PageVnode, offPage, cbPage, PG_WAIT | PG_NORELOC, &KernelSeg, virtAddr);
     153
     154    if (RT_LIKELY(pPage))
     155    {
     156        /*
     157         * Lock this page into memory "long term" to prevent paging out of this page.
     158         */
     159        page_pp_lock(pPage, 0 /* COW */, 1 /* Kernel */);
     160        page_io_unlock(pPage);
     161        page_downgrade(pPage);
     162        Assert(PAGE_LOCKED_SE(pPage, SE_SHARED));
     163    }
     164
    153165    return pPage;
    154166}
     
    200212                {
    201213                    /*
    202                      * Get a page from the free list locked exclusively. The page will be named (hashed in).
    203                      * Hashing out the page has no real benefits. Downgrade the page to a shared lock to                                     .
    204                      * prevent the page from being relocated.
     214                     * Get a page from the free list locked exclusively. The page will be named (hashed in)
     215                     * and we rely on it during free. Downgrade the page to a shared lock to prevent the page
     216                     * from being relocated.
    205217                     */
    206218                    pPage = rtR0MemObjSolPageAlloc(virtAddr, PAGE_SIZE);
     
    208220                        break;
    209221
    210                     page_io_unlock(pPage);
    211                     page_downgrade(pPage);
    212                     Assert(PAGE_LOCKED_SE(pPage, SE_SHARED));
    213 
    214222                    /*
    215223                     * Check if the physical address backing the page is within the requested range if any.
    216224                     * If it isn't, discard the page and try again.
    217225                     */
     226                    /** @todo Remove this constraint here, force all high-limit applicable cases
     227                     *        through rtR0SolMemAlloc() */
    218228                    if (uPhysHi != NIL_RTHCPHYS)
    219229                    {
     
    237247                     * No pages found or found pages didn't meet requirements, release what was grabbed so far.
    238248                     */
    239                     while (--i >= 0)
    240                         page_destroy(ppPages[i], 0 /* move it to the free list */);
     249                    for (size_t k = 0; k <= i; k++)
     250                        page_destroy(ppPages[k], 0 /* move it to the free list */);
    241251                    kmem_free(ppPages, cbPages);
    242252                    page_unresv(cPages);
     
    288298        }
    289299        Assert(PAGE_LOCKED_SE(pPage, SE_EXCL));
     300        page_pp_unlock(pPage, 0 /* COW */, 1 /* Kernel */);
    290301        page_destroy(pPage, 0 /* move it to the free list */);
    291302    }
     
    296307
    297308/**
    298  * Allocates one large page. There is currently no way on Solaris to request
    299  * a block larger than one page backed with physically contiguous memory, i.e.
    300  * PG_PHYSCONTIG is not yet supported.
     309 * Allocates one large page.
    301310 *
    302311 * @param puPhys        Where to store the physical address of the allocated
     
    347356
    348357                    /*
    349                      * Lock the page into memory "long term". This prevents the pageout scanner (page_try_demote_pages()) from
    350                      * demoting the large page into smaller pages while we temporarily release the exclusive lock (during free).
     358                     * Lock the page into memory "long term". This prevents callers of page_try_demote_pages() (such as the
     359                     * pageout scanner) from demoting the large page into smaller pages while we temporarily release the
     360                     * exclusive lock (during free). We pass "0, 1" since we've already accounted for availrmem during
     361                     * page_resv().
    351362                     */
    352363                    page_pp_lock(pPage, 0 /* COW */, 1 /* Kernel */);
     
    415426            page_t *pFoundPage = page_lookup(&g_LargePageVnode, offPage, SE_EXCL);
    416427            AssertRelease(pFoundPage);
     428
    417429#if 0
    418430            /*
     
    425437
    426438            /*
    427              * Check for page demotion (regardless of relocation). In VM1, the uncorrectable memory error scanner
    428              * does -not- respect the long-term page lock we have, so it might have demoted the page to _4K pages
    429              * while the page lock was dropped.
     439             * Check for page demotion (regardless of relocation). Some places in Solaris (e.g. VM1 page_retire())
     440             * could possibly demote the large page to _4K pages between our call to page_unlock() and page_lookup().
    430441             */
    431442            if (page_get_pagecnt(pFoundPage->p_szc) == 1)   /* Base size of only _4K associated with this page. */
    432443                fDemoted = true;
    433 
     444            pPage          = pFoundPage;
    434445            ppPages[iPage] = pFoundPage;
    435             pPage          = pFoundPage;
    436446        }
    437447        Assert(PAGE_LOCKED_SE(pPage, SE_EXCL));
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