VirtualBox

Changeset 30807 in vbox


Ignore:
Timestamp:
Jul 13, 2010 4:49:13 PM (14 years ago)
Author:
vboxsync
Message:

Started with chunk unmap changes. Code is in an unused path.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PGMPhys.cpp

    r30756 r30807  
    33393339}
    33403340
     3341/**
     3342 * Rendezvous callback used by pgmR3PhysUnmapChunk that clears all shadow pages
     3343 * and all modification counters.
     3344 *
     3345 * This is only called on one of the EMTs while the other ones are waiting for
     3346 * it to complete this function.
     3347 *
     3348 * @returns VINF_SUCCESS (VBox strict status code).
     3349 * @param   pVM         The VM handle.
     3350 * @param   pVCpu       The VMCPU for the EMT we're being called on. Unused.
     3351 * @param   pvUser      User pointer. Unused
     3352 *
     3353 */
     3354DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysUnmapChunkRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
     3355{
     3356    int rc = VINF_SUCCESS;
     3357    pgmLock(pVM);
     3358
     3359    if (pVM->pgm.s.ChunkR3Map.c >= pVM->pgm.s.ChunkR3Map.cMax)
     3360    {
     3361        /*
     3362         * Request the ring-0 part to unmap a chunk to make space in the mapping cache.
     3363         */
     3364        GMMMAPUNMAPCHUNKREQ Req;
     3365        Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     3366        Req.Hdr.cbReq = sizeof(Req);
     3367        Req.pvR3 = NULL;
     3368        Req.idChunkMap = NIL_GMM_CHUNKID;
     3369        Req.idChunkUnmap = pgmR3PhysChunkFindUnmapCandidate(pVM);
     3370
     3371        rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_MAP_UNMAP_CHUNK, 0, &Req.Hdr);
     3372        if (RT_SUCCESS(rc))
     3373        {
     3374            /* remove the unmapped one. */
     3375            PPGMCHUNKR3MAP pUnmappedChunk = (PPGMCHUNKR3MAP)RTAvlU32Remove(&pVM->pgm.s.ChunkR3Map.pTree, Req.idChunkUnmap);
     3376            AssertRelease(pUnmappedChunk);
     3377            pUnmappedChunk->pv = NULL;
     3378            pUnmappedChunk->Core.Key = UINT32_MAX;
     3379#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
     3380            MMR3HeapFree(pUnmappedChunk);
     3381#else
     3382            MMR3UkHeapFree(pVM, pUnmappedChunk, MM_TAG_PGM_CHUNK_MAPPING);
     3383#endif
     3384            pVM->pgm.s.ChunkR3Map.c--;
     3385
     3386            /* Chunk removed, so clear the chunk map TLB; PGMR3PhysChunkInvalidateTLB clears the page map TLB as well. */
     3387            PGMR3PhysChunkInvalidateTLB(pVM);
     3388
     3389            /* Flush all REM caches. */
     3390            REMFlushTBs(pVM);
     3391            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     3392                CPUMSetChangedFlags(&pVM->aCpus[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
     3393
     3394            /* Flush the pgm pool cache; call the internal rendezvous handler as we're already in a rendezvous handler here. */
     3395            pgmR3PoolClearAllRendezvous(pVM, &pVM->aCpus[0], false /* no need to flush the REM TLB as we already did that above */);
     3396        }
     3397    }
     3398    pgmUnlock(pVM);
     3399    return rc;
     3400}
     3401
     3402/**
     3403 * Unmap a chunk to free up virtual address space (request packet handler for pgmR3PhysChunkMap)
     3404 *
     3405 * @returns VBox status code.
     3406 * @param   pVM         The VM to operate on.
     3407 */
     3408void pgmR3PhysUnmapChunk(PVM pVM)
     3409{
     3410    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysUnmapChunkRendezvous, NULL);
     3411    AssertRC(rc);
     3412}
    33413413
    33423414/**
     
    33743446
    33753447    /*
    3376      * Request the ring-0 part to map the chunk in question and if
    3377      * necessary unmap another one to make space in the mapping cache.
     3448     * Request the ring-0 part to map the chunk in question.
    33783449     */
    33793450    GMMMAPUNMAPCHUNKREQ Req;
     
    33833454    Req.idChunkMap = idChunk;
    33843455    Req.idChunkUnmap = NIL_GMM_CHUNKID;
    3385     if (pVM->pgm.s.ChunkR3Map.c >= pVM->pgm.s.ChunkR3Map.cMax)
    3386         Req.idChunkUnmap = pgmR3PhysChunkFindUnmapCandidate(pVM);
    33873456
    33883457    /* Must be callable from any thread, so can't use VMMR3CallR0. */
     
    34033472        AssertRelease(fRc);
    34043473
    3405         /* remove the unmapped one. */
    3406         if (Req.idChunkUnmap != NIL_GMM_CHUNKID)
    3407         {
    3408             PPGMCHUNKR3MAP pUnmappedChunk = (PPGMCHUNKR3MAP)RTAvlU32Remove(&pVM->pgm.s.ChunkR3Map.pTree, Req.idChunkUnmap);
    3409             AssertRelease(pUnmappedChunk);
    3410             pUnmappedChunk->pv = NULL;
    3411             pUnmappedChunk->Core.Key = UINT32_MAX;
    3412 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
    3413             MMR3HeapFree(pUnmappedChunk);
    3414 #else
    3415             MMR3UkHeapFree(pVM, pUnmappedChunk, MM_TAG_PGM_CHUNK_MAPPING);
    3416 #endif
    3417             pVM->pgm.s.ChunkR3Map.c--;
    3418 
    3419             /* Chunk removed, so clear the page map TLB as well (might still be referenced). */
    3420             PGMPhysInvalidatePageMapTLB(pVM);
     3474        /* If we're running out of virtual address space, then we should unmap another chunk. */
     3475        if (pVM->pgm.s.ChunkR3Map.c >= pVM->pgm.s.ChunkR3Map.cMax)
     3476        {
     3477            /* Postpone the unmap operation (which requires a rendezvous operation) as we own the PGM lock here. */
     3478            int rc = VMR3ReqCallNoWaitU(pVM->pUVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3PhysUnmapChunk, 1, pVM);
     3479            AssertRC(rc);
    34213480        }
    34223481    }
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