VirtualBox

Changeset 4612 in vbox


Ignore:
Timestamp:
Sep 7, 2007 3:26:28 PM (17 years ago)
Author:
vboxsync
Message:

Implemented ballooning on the guest side. (completely untested and disabled)

Location:
trunk/src/VBox/Additions/WINNT/VBoxGuest
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxGuest/NTLegacy.cpp

    r4071 r4612  
    250250    /** @todo cleanup on failure */
    251251
     252    VBoxInitMemBalloon(pDevExt);
     253
    252254    // ready to rumble!
    253255    pDevExt->devState = WORKING;
     
    349351    // unmap mem/io resources
    350352    hlpVBoxUnmapVMMDevMemory (pDevExt);
     353
     354    VBoxCleanupMemBalloon(pDevExt);
    351355}
    352356
  • trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuest.cpp

    r4580 r4612  
    252252    hlpVBoxUnmapVMMDevMemory (pDevExt);
    253253
     254    VBoxCleanupMemBalloon(pDevExt);
     255
    254256    /*
    255257     * I don't think it's possible to unload a driver which processes have
     
    428430}
    429431
     432#ifdef VBOX_WITH_MANAGEMENT
     433static int VBoxGuestSetBalloonSize(PVBOXGUESTDEVEXT pDevExt, uint32_t u32BalloonSize)
     434{
     435    VMMDevChangeMemBalloon *req = NULL;
     436    int rc = VINF_SUCCESS;
     437
     438    if (u32BalloonSize > pDevExt->MemBalloon.cMaxBalloons)
     439    {
     440        AssertMsgFailed(("VBoxGuestSetBalloonSize illegal balloon size %d (max=%d)\n", u32BalloonSize, pDevExt->MemBalloon.cMaxBalloons));
     441        return VERR_INVALID_PARAMETER;
     442    }
     443
     444    if (u32BalloonSize == pDevExt->MemBalloon.cBalloons)
     445        return VINF_SUCCESS;    /* nothing to do */
     446
     447    /* Allocate request packet */
     448    rc = VbglGRAlloc((VMMDevRequestHeader **)&req, RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]), VMMDevReq_ChangeMemBalloon);
     449    if (VBOX_FAILURE(rc))
     450        return rc;
     451
     452    vmmdevInitRequest(&req->header, VMMDevReq_ChangeMemBalloon);
     453
     454    if (u32BalloonSize > pDevExt->MemBalloon.cBalloons)
     455    {
     456        /* inflate */
     457        for (uint32_t i=pDevExt->MemBalloon.cBalloons;i<u32BalloonSize;i++)
     458        {
     459            PVOID pvBalloon;
     460
     461            pvBalloon = ExAllocatePoolWithTag(PagedPool, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, 'MBAL');
     462            if (!pvBalloon)
     463            {
     464                rc = VERR_NO_MEMORY;
     465                goto end;
     466            }
     467
     468            PMDL pMdl = IoAllocateMdl (pvBalloon, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, FALSE, FALSE, NULL);
     469            if (pMdl == NULL)
     470            {
     471                rc = VERR_NO_MEMORY;
     472                ExFreePoolWithTag(pvBalloon, 'MBAL');
     473                AssertMsgFailed(("IoAllocateMdl %VGv %x failed!!\n", pvBalloon, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE));
     474                goto end;
     475            }
     476            else
     477            {
     478                __try {
     479                    /* Calls to MmProbeAndLockPages must be enclosed in a try/except block. */
     480                    MmProbeAndLockPages (pMdl, KernelMode, IoModifyAccess);
     481                }
     482                __except(EXCEPTION_EXECUTE_HANDLER)
     483                {
     484                    rc = VERR_NO_MEMORY;
     485                    IoFreeMdl (pMdl);
     486                    ExFreePoolWithTag(pvBalloon, 'MBAL');
     487                    goto end;
     488                }
     489            }
     490
     491            PPFN_NUMBER pPageDesc = MmGetMdlPfnArray(pMdl);
     492
     493            /* Copy manually as RTGCPHYS is always 64 bits */
     494            for (uint32_t j=0;j<VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;j++)
     495                req->aPhysPage[j] = pPageDesc[j];
     496
     497            req->cPages   = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
     498            req->fInflate = true;
     499
     500            rc = VbglGRPerform(&req->header);
     501            if (VBOX_FAILURE(rc) || VBOX_FAILURE(req->header.rc))
     502            {
     503                dprintf(("VBoxGuest::VBoxGuestSetBalloonSize: error issuing request to VMMDev!"
     504                         "rc = %d, VMMDev rc = %Vrc\n", rc, req->header.rc));
     505
     506                IoFreeMdl (pMdl);
     507                ExFreePoolWithTag(pvBalloon, 'MBAL');
     508                goto end;
     509            }
     510            else
     511            {
     512                pDevExt->MemBalloon.paMdlMemBalloon[i] = pMdl;
     513                pDevExt->MemBalloon.cBalloons++;
     514            }
     515        }
     516    }
     517    else
     518    {
     519        /* deflate */
     520        for (uint32_t i=pDevExt->MemBalloon.cBalloons-1;i>=u32BalloonSize;i--)
     521        {
     522            PMDL  pMdl      = pDevExt->MemBalloon.paMdlMemBalloon[i];
     523            PVOID pvBalloon = MmGetMdlVirtualAddress(pMdl);
     524
     525            PPFN_NUMBER pPageDesc = MmGetMdlPfnArray(pMdl);
     526
     527            /* Copy manually as RTGCPHYS is always 64 bits */
     528            for (uint32_t j=0;j<VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;j++)
     529                req->aPhysPage[j] = pPageDesc[j];
     530
     531            req->cPages   = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
     532            req->fInflate = false;
     533
     534            rc = VbglGRPerform(&req->header);
     535            if (VBOX_FAILURE(rc) || VBOX_FAILURE(req->header.rc))
     536            {
     537                AssertMsgFailed(("VBoxGuest::VBoxGuestSetBalloonSize: error issuing request to VMMDev! rc = %d, VMMDev rc = %Vrc\n", rc, req->header.rc));
     538                /* ignore error and just continue; this should never fail */
     539            }
     540
     541            /* Free the ballooned memory */
     542            MmUnlockPages (pMdl);
     543            IoFreeMdl (pMdl);
     544            ExFreePoolWithTag(pvBalloon, 'MBAL');
     545
     546            pDevExt->MemBalloon.paMdlMemBalloon[i] = NULL;
     547            pDevExt->MemBalloon.cBalloons--;
     548        }
     549    }
     550    Assert(pDevExt->MemBalloon.cBalloons <= pDevExt->MemBalloon.cMaxBalloons);
     551
     552end:
     553    VbglGRFree(&req->header);
     554    return rc;
     555}
     556
    430557static int VBoxGuestQueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, ULONG *pMemBalloonSize)
    431558{
    432     /** @todo */
    433     return VINF_SUCCESS;
    434 
    435559    /* just perform the request */
    436560    VMMDevGetMemBalloonChangeRequest *req = NULL;
     
    453577        else
    454578        {
    455 
     579            if (!pDevExt->MemBalloon.paMdlMemBalloon)
     580            {
     581                pDevExt->MemBalloon.paMdlMemBalloon = (PMDL *)ExAllocatePoolWithTag(PagedPool, req->u32PhysMemSize * sizeof(PMDL), 'MBAL');
     582                Assert(pDevExt->MemBalloon.paMdlMemBalloon);
     583                if (!pDevExt->MemBalloon.paMdlMemBalloon)
     584                    return VERR_NO_MEMORY;
     585            }
     586
     587            rc = VBoxGuestSetBalloonSize(pDevExt, req->u32BalloonSize);
     588            if (pMemBalloonSize)
     589                *pMemBalloonSize = pDevExt->MemBalloon.cBalloons;
    456590        }
    457591
     
    460594    return rc;
    461595}
    462 
     596#endif
     597
     598void VBoxInitMemBalloon(PVBOXGUESTDEVEXT pDevExt)
     599{
     600#ifdef VBOX_WITH_MANAGEMENT
     601    ULONG dummy;
     602
     603    pDevExt->MemBalloon.cBalloons       = 0;
     604    pDevExt->MemBalloon.cMaxBalloons    = 0;
     605    pDevExt->MemBalloon.paMdlMemBalloon = NULL;
     606
     607    VBoxGuestQueryMemoryBalloon(pDevExt, &dummy);
     608#endif
     609}
     610
     611void VBoxCleanupMemBalloon(PVBOXGUESTDEVEXT pDevExt)
     612{
     613#ifdef VBOX_WITH_MANAGEMENT
     614    if (pDevExt->MemBalloon.paMdlMemBalloon)
     615    {
     616        /* Clean up the memory balloon leftovers */
     617        VBoxGuestSetBalloonSize(pDevExt, 0);
     618        ExFreePoolWithTag(pDevExt->MemBalloon.paMdlMemBalloon, 'MBAL');
     619        pDevExt->MemBalloon.paMdlMemBalloon = NULL;
     620    }
     621    Assert(pDevExt->MemBalloon.cBalloons == 0);
     622#endif
     623}
    463624
    464625/**
  • trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuestPnP.cpp

    r4071 r4612  
    236236                KeInitializeEvent(&pDevExt->keventNotification, NotificationEvent, FALSE);
    237237
     238                VBoxInitMemBalloon(pDevExt);
     239
    238240                // ready to rumble!
    239241                dprintf(("VBoxGuest::VBoxGuestPnp: device is ready!\n"));
  • trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuest_Internal.h

    r4301 r4612  
    192192    VMMDevEvents *irqAckEvents;
    193193
     194
     195    struct
     196    {
     197        uint32_t     cBalloons;
     198        uint32_t     cMaxBalloons;
     199        PMDL        *paMdlMemBalloon;
     200    } MemBalloon;
     201
    194202} VBOXGUESTDEVEXT, *PVBOXGUESTDEVEXT;
    195203
     
    212220NTSTATUS createThreads(PVBOXGUESTDEVEXT pDevExt);
    213221VOID     unreserveHypervisorMemory(PVBOXGUESTDEVEXT pDevExt);
     222void     VBoxInitMemBalloon(PVBOXGUESTDEVEXT pDevExt);
     223void     VBoxCleanupMemBalloon(PVBOXGUESTDEVEXT pDevExt);
    214224}
    215225
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