VirtualBox

儲存庫 vbox 的更動 37178


忽略:
時間撮記:
2011-5-23 上午08:17:29 (14 年 以前)
作者:
vboxsync
訊息:

GMMR0: Leave the GMM lock when mapping a chunk into user space, it's expensive.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r37153 r37178  
    396396    /** Pointer to the previous chunk in the free list. */
    397397    PGMMCHUNK           pFreePrev;
    398     /** Pointer to the free set this chunk belongs to. NULL for
     398    /** Pointer to the free set this chunk belongs to.  NULL for
    399399     * chunks with no free pages. */
    400400    PGMMCHUNKFREESET    pSet;
     
    405405    /** The number of mappings. */
    406406    uint16_t            cMappings;
     407    /** The number of mapping operations that is in progress without owning
     408     * the semaphore. */
     409    uint16_t volatile   cMappingsInProgress;
    407410    /** The head of the list of free pages. UINT16_MAX is the NIL value. */
    408411    uint16_t            iFreeHead;
     
    413416     * When in bound memory mode this isn't a preference any longer. */
    414417    uint16_t            hGVM;
     418    /** The ID of the NUMA node the memory mostly resides on. (Reserved for
     419     *  future use.) */
     420    uint16_t            idNumaNode;
    415421    /** The number of private pages. */
    416422    uint16_t            cPrivate;
     
    461467/** The number of lists in set. */
    462468#define GMM_CHUNK_FREE_SET_LISTS    (GMM_CHUNK_NUM_PAGES >> GMM_CHUNK_FREE_SET_SHIFT)
     469
     470/** Indicates that the NUMA properies of the memory is unknown. */
     471#define GMM_CHUNK_NUMA_ID_UNKNOWN   UINT16_C(0xfffe)
    463472
    464473/**
     
    792801        SUPR0Printf("GMMR0Term: %p/%#x: cFree=%d cPrivate=%d cShared=%d cMappings=%d\n", pChunk,
    793802                    pChunk->Core.Key, pChunk->cFree, pChunk->cPrivate, pChunk->cShared, pChunk->cMappings);
     803    Assert(pChunk->cMappingsInProgress == 0);
    794804
    795805    int rc = RTR0MemObjFree(pChunk->MemObj, true /* fFreeMappings */);
     
    11831193            pChunk->cMappings = cMappings;
    11841194
     1195/** @todo Leave the GMM mutex when doing this, it's expensive. */
    11851196            int rc = RTR0MemObjFree(MemObj, false /* fFreeMappings (NA) */);
    11861197            if (RT_FAILURE(rc))
     
    17561767        pChunk->cFree = GMM_CHUNK_NUM_PAGES;
    17571768        pChunk->hGVM = hGVM;
    1758         pChunk->iFreeHead = 0;
     1769        /*pChunk->iFreeHead = 0;*/
     1770        pChunk->idNumaNode = GMM_CHUNK_NUMA_ID_UNKNOWN;
    17591771        pChunk->enmType = enmChunkType;
    17601772        for (unsigned iPage = 0; iPage < RT_ELEMENTS(pChunk->aPages) - 1; iPage++)
     
    26882700     * it won't be a likely candidate for allocations.
    26892701     */
    2690     if (pChunk->cMappings)
     2702    if (   pChunk->cMappings
     2703        || pChunk->cMappingsInProgress)
    26912704    {
    26922705        /** @todo R0 -> VM request */
    26932706        /* The chunk can be mapped by more than one VM if fBoundMemoryMode is false! */
    2694         Log(("gmmR0FreeChunk: chunk still has %d mappings; don't free!\n", pChunk->cMappings));
     2707        Log(("gmmR0FreeChunk: chunk still has %d/%d mappings; don't free!\n", pChunk->cMappings, pChunk->cMappingsInProgress));
    26952708    }
    26962709    else
     
    34003413 * @param   pGVM        Pointer to the Global VM structure.
    34013414 * @param   pChunk      Pointer to the chunk to be mapped.
     3415 * @param   fRelaxedSem Whether we can release the semaphore while doing the
     3416 *                      locking (@c true) or not.
    34023417 * @param   ppvR3       Where to store the ring-3 address of the mapping.
    34033418 *                      In the VERR_GMM_CHUNK_ALREADY_MAPPED case, this will be
    34043419 *                      contain the address of the existing mapping.
    34053420 */
    3406 static int gmmR0MapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, PRTR3PTR ppvR3)
     3421static int gmmR0MapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, bool fRelaxedSem, PRTR3PTR ppvR3)
    34073422{
    34083423    Assert(pGMM->hMtxOwner == RTThreadNativeSelf());
     
    34433458
    34443459    /*
    3445      * Do the mapping.
     3460     * Do the mapping.  Leave the semaphore when possible since mapping memory
     3461     * into the user process can be very expensive.
     3462     *
     3463     * ASSUMES that all mappers will hold the PGM lock and therefore prevent
     3464     * other threads from mapping the memory into the same process.
    34463465     */
    34473466    RTR0MEMOBJ MapObj;
    3448     int rc = RTR0MemObjMapUser(&MapObj, pChunk->MemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
     3467    int rc;
     3468    if (   !fRelaxedSem
     3469        || pChunk->cFree == GMM_CHUNK_NUM_PAGES)
     3470        rc = RTR0MemObjMapUser(&MapObj, pChunk->MemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
     3471    else
     3472    {
     3473        pChunk->cMappingsInProgress++;
     3474        gmmR0MutexRelease(pGMM);
     3475        Assert(PGMIsLockOwner(pGVM->pVM));
     3476
     3477        rc = RTR0MemObjMapUser(&MapObj, pChunk->MemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
     3478
     3479        int rc2 = gmmR0MutexAcquire(pGMM); AssertRC(rc2);
     3480        pChunk->cMappingsInProgress--;
     3481    }
    34493482    if (RT_SUCCESS(rc))
    34503483    {
     
    35733606            pMap = gmmR0GetChunk(pGMM, idChunkMap);
    35743607            if (RT_LIKELY(pMap))
    3575                 rc = gmmR0MapChunk(pGMM, pGVM, pMap, ppvR3);
     3608                rc = gmmR0MapChunk(pGMM, pGVM, pMap, true /*fRelaxedSem*/, ppvR3);
    35763609            else
    35773610            {
     
    41664199        {
    41674200            Log(("Map chunk into process!\n"));
    4168             rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk);
     4201            rc = gmmR0MapChunk(pGMM, pGVM, pChunk, false /*fRelaxedSem*/, (PRTR3PTR)&pbChunk);
    41694202            if (rc != VINF_SUCCESS)
    41704203            {
     
    44654498    if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk))
    44664499    {
    4467         int rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk);
     4500        int rc = gmmR0MapChunk(pGMM, pGVM, pChunk, false /*fRelaxedSem*/, (PRTR3PTR)&pbChunk);
    44684501        if (RT_SUCCESS(rc))
    44694502        {
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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