VirtualBox

Changeset 27023 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 4, 2010 1:32:45 PM (15 years ago)
Author:
vboxsync
Message:

Guest Additions: memory ballooning for guests without support for RTR0MemObjAllocPhysNC()

Location:
trunk/src/VBox
Files:
9 edited

Legend:

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

    r26999 r27023  
    558558
    559559#ifdef VBOX_WITH_MANAGEMENT
    560 static int VBoxGuestSetBalloonSize(PVBOXGUESTDEVEXT pDevExt, uint32_t u32BalloonSize)
     560static int VBoxGuestSetBalloonSize(PVBOXGUESTDEVEXT pDevExt, uint32_t cBalloonChunks)
    561561{
    562562    VMMDevChangeMemBalloon *req = NULL;
     
    564564    uint32_t i;
    565565
    566     if (u32BalloonSize > pDevExt->MemBalloon.cMaxBalloons)
    567     {
    568         AssertMsgFailed(("VBoxGuestSetBalloonSize illegal balloon size %d (max=%d)\n", u32BalloonSize, pDevExt->MemBalloon.cMaxBalloons));
     566    if (cBalloonChunks > pDevExt->MemBalloon.cMaxBalloonChunks)
     567    {
     568        AssertMsgFailed(("VBoxGuestSetBalloonSize illegal balloon size %d (max=%d)\n", cBalloonChunks, pDevExt->MemBalloon.cMaxBalloonChunks));
    569569        return VERR_INVALID_PARAMETER;
    570570    }
    571571
    572     if (u32BalloonSize == pDevExt->MemBalloon.cBalloons)
     572    if (cBalloonChunks == pDevExt->MemBalloon.cBalloonChunks)
    573573        return VINF_SUCCESS;    /* nothing to do */
    574574
     
    578578        return rc;
    579579
    580     if (u32BalloonSize > pDevExt->MemBalloon.cBalloons)
     580    if (cBalloonChunks > pDevExt->MemBalloon.cBalloonChunks)
    581581    {
    582582        /* inflate */
    583         for (i = pDevExt->MemBalloon.cBalloons; i < u32BalloonSize; i++)
     583        for (i = pDevExt->MemBalloon.cBalloonChunks; i < cBalloonChunks; i++)
    584584        {
    585585#ifndef TARGET_NT4
     
    669669#endif
    670670                pDevExt->MemBalloon.paMdlMemBalloon[i] = pMdl;
    671                 pDevExt->MemBalloon.cBalloons++;
     671                pDevExt->MemBalloon.cBalloonChunks++;
    672672            }
    673673        }
     
    676676    {
    677677        /* deflate */
    678         for (i = pDevExt->MemBalloon.cBalloons; i > u32BalloonSize; i--)
     678        for (i = pDevExt->MemBalloon.cBalloonChunks; i > cBalloonChunks; i--)
    679679        {
    680680            uint32_t index = i - 1;
     
    718718
    719719                pDevExt->MemBalloon.paMdlMemBalloon[index] = NULL;
    720                 pDevExt->MemBalloon.cBalloons--;
    721             }
    722         }
    723     }
    724     Assert(pDevExt->MemBalloon.cBalloons <= pDevExt->MemBalloon.cMaxBalloons);
     720                pDevExt->MemBalloon.cBalloonChunks--;
     721            }
     722        }
     723    }
     724    Assert(pDevExt->MemBalloon.cBalloonChunks <= pDevExt->MemBalloon.cMaxBalloonChunks);
    725725
    726726end:
     
    752752            if (!pDevExt->MemBalloon.paMdlMemBalloon)
    753753            {
    754                 pDevExt->MemBalloon.cMaxBalloons = req->u32PhysMemSize;
    755                 pDevExt->MemBalloon.paMdlMemBalloon = (PMDL *)ExAllocatePool(PagedPool, req->u32PhysMemSize * sizeof(PMDL));
     754                pDevExt->MemBalloon.cMaxBalloonChunks = req->cPhysMemChunks;
     755                pDevExt->MemBalloon.paMdlMemBalloon = (PMDL *)ExAllocatePool(PagedPool, req->cPhysMemChunks * sizeof(PMDL));
    756756                Assert(pDevExt->MemBalloon.paMdlMemBalloon);
    757757                if (!pDevExt->MemBalloon.paMdlMemBalloon)
    758758                    return VERR_NO_MEMORY;
    759759            }
    760             Assert(pDevExt->MemBalloon.cMaxBalloons == req->u32PhysMemSize);
    761 
    762             rc = VBoxGuestSetBalloonSize(pDevExt, req->u32BalloonSize);
     760            Assert(pDevExt->MemBalloon.cMaxBalloonChunks == req->cPhysMemChunks);
     761
     762            rc = VBoxGuestSetBalloonSize(pDevExt, req->cBalloonChunks);
    763763            /* ignore out of memory failures */
    764764            if (rc == VERR_NO_MEMORY)
     
    766766
    767767            if (pMemBalloonSize)
    768                 *pMemBalloonSize = pDevExt->MemBalloon.cBalloons;
     768                *pMemBalloonSize = pDevExt->MemBalloon.cBalloonChunks;
    769769        }
    770770
     
    780780    ULONG dummy;
    781781
    782     pDevExt->MemBalloon.cBalloons      = 0;
    783     pDevExt->MemBalloon.cMaxBalloons    = 0;
     782    pDevExt->MemBalloon.cBalloonChunks = 0;
     783    pDevExt->MemBalloon.cMaxBalloonChunks = 0;
    784784    pDevExt->MemBalloon.paMdlMemBalloon = NULL;
    785785
     
    798798        pDevExt->MemBalloon.paMdlMemBalloon = NULL;
    799799    }
    800     Assert(pDevExt->MemBalloon.cBalloons == 0);
     800    Assert(pDevExt->MemBalloon.cBalloonChunks == 0);
    801801#endif
    802802}
     
    13821382        case VBOXGUEST_IOCTL_CHECK_BALLOON:
    13831383        {
    1384             ULONG *pMemBalloonSize = (ULONG *) pBuf;
     1384            VBoxGuestCheckBalloonInfo *pInfo = (VBoxGuestCheckBalloonInfo *)pBuf;
    13851385
    13861386            if (pStack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG))
     
    13921392            }
    13931393
    1394             int rc = VBoxGuestQueryMemoryBalloon(pDevExt, pMemBalloonSize);
     1394            ULONG cMemoryBalloonChunks;
     1395            int rc = VBoxGuestQueryMemoryBalloon(pDevExt, &cMemoryBalloonChunks);
    13951396            if (RT_FAILURE(rc))
    13961397            {
     
    14011402            {
    14021403                cbOut = pStack->Parameters.DeviceIoControl.OutputBufferLength;
     1404                pInfo->cBalloonChunks = cMemoryBalloonChunks;
     1405                pInfo->fHandleInR3 = false;
    14031406            }
    14041407            break;
  • trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuest_Internal.h

    r25022 r27023  
    216216    struct
    217217    {
    218         uint32_t     cBalloons;
    219         uint32_t     cMaxBalloons;
     218        uint32_t     cBalloonChunks;
     219        uint32_t     cMaxBalloonChunks;
    220220        PMDL        *paMdlMemBalloon;
    221221    } MemBalloon;
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r26999 r27023  
    4848#endif
    4949
     50const size_t cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
    5051
    5152
     
    259260{
    260261    VMMDevReportGuestInfo *pReq;
    261     int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_ReportGuestInfo);
     262    int rc;
     263    rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_ReportGuestInfo);
    262264    if (RT_SUCCESS(rc))
    263265    {
     
    274276}
    275277
     278/**
     279 * Inflate the balloon by one chunk represented by an R0 memory object.
     280 *
     281 * @returns IPRT status code.
     282 * @param   pMemObj     Pointer to the R0 memory object.
     283 * @param   pReq        The pre-allocated request for performing the VMMDev call.
     284 */
     285static int vboxGuestBalloonInflate(PRTR0MEMOBJ pMemObj, VMMDevChangeMemBalloon *pReq)
     286{
     287    uint32_t iPage;
     288    int rc;
     289
     290    for (iPage = 0; iPage < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; iPage++)
     291    {
     292        RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(*pMemObj, iPage);
     293        pReq->aPhysPage[iPage] = phys;
     294    }
     295
     296    /* Protect this memory from being accessed. Doesn't work on every platform and probably
     297     * doesn't work for R3-provided memory, therefore ignore the return value. Unprotect
     298     * done when object is freed. */
     299    rc = RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_NONE);
     300    NOREF(rc);
     301
     302    pReq->fInflate = true;
     303    pReq->header.size = cbChangeMemBalloonReq;
     304    pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
     305
     306    return VbglGRPerform(&pReq->header);
     307}
     308
     309/**
     310 * Deflate the balloon by one chunk represented by an R0 memory object.
     311 *
     312 * @returns IPRT status code.
     313 * @param   pMemObj     Pointer to the R0 memory object.
     314 *                      The memory object will be freed afterwards.
     315 * @param   pReq        The pre-allocated request for performing the VMMDev call.
     316 */
     317static int vboxGuestBalloonDeflate(PRTR0MEMOBJ pMemObj, VMMDevChangeMemBalloon *pReq)
     318{
     319    uint32_t iPage;
     320    int rc;
     321
     322    for (iPage = 0; iPage < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; iPage++)
     323    {
     324        RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(*pMemObj, iPage);
     325        pReq->aPhysPage[iPage] = phys;
     326    }
     327
     328    pReq->fInflate = false;
     329    pReq->header.size = cbChangeMemBalloonReq;
     330    pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
     331
     332    rc = VbglGRPerform(&pReq->header);
     333    if (RT_FAILURE(rc))
     334        return rc;
     335
     336    rc = RTR0MemObjFree(*pMemObj, true);
     337    if (RT_FAILURE(rc))
     338        return rc;
     339
     340    *pMemObj = NIL_RTR0MEMOBJ;
     341    return VINF_SUCCESS;
     342}
     343
    276344
    277345/**
     
    279347 *
    280348 * @returns VBox status code.
    281  * @param   pDevExt     The device extension
    282  * @param   u32BalloonSize The new size of the balloon in chunks of 1MB.
    283  */
    284 static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t u32BalloonSize)
     349 * @param   pDevExt         The device extension
     350 * @param   cBalloonChunks The new size of the balloon in chunks of 1MB.
     351 */
     352static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t cBalloonChunks)
    285353{
    286354    int rc = VINF_SUCCESS;
     
    289357    {
    290358        VMMDevChangeMemBalloon *pReq;
    291         uint32_t i, j;
    292         const size_t cbReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
    293 
    294         if (u32BalloonSize > pDevExt->MemBalloon.cMaxChunks)
     359        uint32_t i;
     360
     361        if (cBalloonChunks > pDevExt->MemBalloon.cMaxChunks)
    295362        {
    296363            AssertMsgFailed(("vboxGuestSetBalloonSize illegal balloon size %d (max=%d)\n",
    297                              u32BalloonSize, pDevExt->MemBalloon.cMaxChunks));
     364                             cBalloonChunks, pDevExt->MemBalloon.cMaxChunks));
    298365            return VERR_INVALID_PARAMETER;
    299366        }
    300367
    301         if (u32BalloonSize == pDevExt->MemBalloon.cMaxChunks)
     368        if (cBalloonChunks == pDevExt->MemBalloon.cMaxChunks)
    302369            return VINF_SUCCESS;   /* nothing to do */
    303370
    304         rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbReq, VMMDevReq_ChangeMemBalloon);
     371        if (   cBalloonChunks > pDevExt->MemBalloon.cChunks
     372            && !pDevExt->MemBalloon.paMemObj)
     373        {
     374            pDevExt->MemBalloon.paMemObj = (RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
     375            if (!pDevExt->MemBalloon.paMemObj)
     376            {
     377                LogRel(("VBoxGuestSetBalloonSizeKernel: no memory for paMemObj!\n"));
     378                return VERR_NO_MEMORY;
     379            }
     380        }
     381
     382        rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
    305383        if (RT_FAILURE(rc))
    306384            return rc;
    307385
    308         if (u32BalloonSize > pDevExt->MemBalloon.cChunks)
     386        if (cBalloonChunks > pDevExt->MemBalloon.cChunks)
    309387        {
    310388            /* inflate */
    311             for (i = pDevExt->MemBalloon.cChunks; i < u32BalloonSize; i++)
     389            for (i = pDevExt->MemBalloon.cChunks; i < cBalloonChunks; i++)
    312390            {
    313391                rc = RTR0MemObjAllocPhysNC(&pDevExt->MemBalloon.paMemObj[i],
    314                                            VMMDEV_MEMORY_BALLOON_CHUNK_PAGES * PAGE_SIZE, NIL_RTHCPHYS);
     392                                           VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, NIL_RTHCPHYS);
    315393                if (RT_UNLIKELY(rc == VERR_NOT_SUPPORTED))
    316394                {
     395                    /* not supported -- fall back to the R3-allocated memory */
    317396                    pDevExt->MemBalloon.fUseKernelAPI = false;
    318397                    break;
     
    329408                }
    330409
    331                 RTR0MEMOBJ MemObj = pDevExt->MemBalloon.paMemObj[i];
    332                 for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++)
    333                 {
    334                     RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(MemObj, j);
    335                     pReq->aPhysPage[j] = phys;
    336                 }
    337 
    338                 pReq->header.size = cbReq;
    339                 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
    340                 pReq->fInflate = true;
    341 
    342                 rc = VbglGRPerform(&pReq->header);
     410                rc = vboxGuestBalloonInflate(&pDevExt->MemBalloon.paMemObj[i], pReq);
    343411                if (RT_FAILURE(rc))
    344412                {
    345                     Log(("vboxGuestSetBalloonSize(inflate): VbglGRPerform failed, rc=%Rrc!\n", rc));
     413                    Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc));
    346414                    break;
    347415                }
     
    352420        {
    353421            /* deflate */
    354             for (i = pDevExt->MemBalloon.cChunks; i > u32BalloonSize; i--)
     422            for (i = pDevExt->MemBalloon.cChunks; i-- > cBalloonChunks;)
    355423            {
    356                 RTR0MEMOBJ MemObj = pDevExt->MemBalloon.paMemObj[i];
    357                 for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++)
    358                 {
    359                     RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(MemObj, j);
    360                     pReq->aPhysPage[j] = phys;
    361                 }
    362 
    363                 pReq->header.size = cbReq;
    364                 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
    365                 pReq->fInflate = false;
    366 
    367                 rc = VbglGRPerform(&pReq->header);
     424                rc = vboxGuestBalloonDeflate(&pDevExt->MemBalloon.paMemObj[i], pReq);
    368425                if (RT_FAILURE(rc))
    369426                {
    370                     Log(("vboxGuestSetBalloonSize(deflate): VbglGRPerform failed, rc=%Rrc!\n", rc));
     427                    Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc));
    371428                    break;
    372429                }
    373 
    374                 rc = RTR0MemObjFree(pDevExt->MemBalloon.paMemObj[i], true);
    375                 if (RT_FAILURE(rc))
    376                 {
    377                     Log(("vboxGuestSetBalloonSize(deflate): RTR0MemObjFree() failed, rc=%Rrc!\n", rc));
    378                     break;
    379                 }
    380                 pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
    381430                pDevExt->MemBalloon.cChunks--;
    382431            }
     
    405454    VMMDevChangeMemBalloon *pReq;
    406455    int rc = VINF_SUCCESS;
    407     uint32_t i, j;
    408     const size_t cbReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
     456    uint32_t i;
    409457    PRTR0MEMOBJ pMemObj = NULL;
    410458
    411     if (   fInflate
    412         && pSession->MemBalloon.cChunks > pSession->MemBalloon.cMaxChunks - 1)
    413     {
    414         AssertMsgFailed(("vboxGuestSetBalloonSize: cannot inflate balloon, already have (max=%d)\n",
    415                          pSession->MemBalloon.cChunks, pSession->MemBalloon.cMaxChunks));
    416         return VERR_INVALID_PARAMETER;
    417     }
    418     else if (   !fInflate
    419              && pSession->MemBalloon.cChunks == 0)
    420     {
    421         AssertMsgFailed(("vboxGuestSetBalloonSize: cannot decrease balloon, already at size 0\n"));
    422         return VERR_INVALID_PARAMETER;
     459    if (fInflate)
     460    {
     461        if (pSession->MemBalloon.cChunks > pDevExt->MemBalloon.cMaxChunks - 1)
     462        {
     463            AssertMsgFailed(("vboxGuestSetBalloonSize: cannot inflate balloon, already have (max=%d)\n",
     464                             pSession->MemBalloon.cChunks, pDevExt->MemBalloon.cMaxChunks));
     465            return VERR_INVALID_PARAMETER;
     466        }
     467
     468        if (!pSession->MemBalloon.paMemObj)
     469        {
     470            pSession->MemBalloon.paMemObj = (RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
     471            if (!pSession->MemBalloon.paMemObj)
     472            {
     473                LogRel(("VBoxGuestSetBalloonSizeFromUser: no memory for paMemObj!\n"));
     474                return VERR_NO_MEMORY;
     475            }
     476            for (i = 0; i < pDevExt->MemBalloon.cMaxChunks; i++)
     477                pSession->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
     478        }
     479    }
     480    else
     481    {
     482        if (pSession->MemBalloon.cChunks == 0)
     483        {
     484            AssertMsgFailed(("vboxGuestSetBalloonSize: cannot decrease balloon, already at size 0\n"));
     485            return VERR_INVALID_PARAMETER;
     486        }
    423487    }
    424488
     
    426490     * Enumerate all memory objects and check if the object is already registered.
    427491     */
    428     for (i = 0; i < pSession->MemBalloon.cMaxChunks; i++)
     492    for (i = 0; i < pDevExt->MemBalloon.cMaxChunks; i++)
    429493    {
    430494        if (   fInflate
    431             && !pSession->MemBalloon.paMemObj[i] == NIL_RTR0MEMOBJ
    432             && !pMemObj)
     495            && !pMemObj
     496            && pSession->MemBalloon.paMemObj[i] == NIL_RTR0MEMOBJ)
    433497            pMemObj = &pSession->MemBalloon.paMemObj[i]; /* found free object pointer */
    434498        if (RTR0MemObjAddressR3(pSession->MemBalloon.paMemObj[i]) == u64ChunkAddr)
     
    448512    }
    449513
    450     rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbReq, VMMDevReq_ChangeMemBalloon);
     514    rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
    451515    if (RT_FAILURE(rc))
    452516        return rc;
     
    456520        if (fInflate)
    457521        {
    458             rc = RTR0MemObjLockUser(pMemObj, u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_PAGES * PAGE_SIZE,
     522            rc = RTR0MemObjLockUser(pMemObj, u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE,
    459523                                    RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
    460524            if (RT_SUCCESS(rc))
    461525            {
    462                 RTR0MEMOBJ MemObj = pDevExt->MemBalloon.paMemObj[i];
    463                 for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++)
    464                 {
    465                     RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(MemObj, j);
    466                     pReq->aPhysPage[j] = phys;
    467                 }
    468 
    469                 pReq->header.size = cbReq;
    470                 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
    471                 pReq->fInflate = true;
    472 
    473                 rc = VbglGRPerform(&pReq->header);
     526                rc = vboxGuestBalloonInflate(pMemObj, pReq);
    474527                if (RT_FAILURE(rc))
    475528                {
    476                     Log(("vboxGuestSetBalloonSize(inflate): VbglGRPerform failed, rc=%Rrc!\n", rc));
     529                    Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc));
    477530                    break;
    478531                }
     
    482535        else
    483536        {
    484             /* deflate */
    485             for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++)
    486             {
    487                 RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(*pMemObj, j);
    488                 pReq->aPhysPage[j] = phys;
    489             }
    490 
    491             pReq->header.size = cbReq;
    492             pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
    493             pReq->fInflate = false;
    494 
    495             rc = VbglGRPerform(&pReq->header);
     537            rc = vboxGuestBalloonDeflate(pMemObj, pReq);
    496538            if (RT_FAILURE(rc))
    497539            {
    498                 Log(("vboxGuestSetBalloonSize(deflate): VbglGRPerform failed, rc=%Rrc!\n", rc));
     540                Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc));
    499541                break;
    500542            }
    501 
    502             rc = RTR0MemObjFree(*pMemObj, true);
    503             if (RT_FAILURE(rc))
    504             {
    505                 Log(("vboxGuestSetBalloonSize(deflate): RTR0MemObjFree() failed, rc=%Rrc!\n", rc));
    506                 break;
    507             }
    508             *pMemObj = NIL_RTR0MEMOBJ;
    509543            pSession->MemBalloon.cChunks--;
    510544        }
     
    517551
    518552/**
     553 * Cleanup the memory balloon of a session.
     554 */
     555static void vboxGuestCloseSessionMemBalloon(PVBOXGUESTSESSION pSession)
     556{
     557    if (pSession->MemBalloon.paMemObj)
     558    {
     559        VMMDevChangeMemBalloon *pReq;
     560        int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
     561        if (RT_SUCCESS(rc))
     562        {
     563            uint32_t i;
     564            for (i = pSession->MemBalloon.cChunks; i-- > 0;)
     565            {
     566                rc = vboxGuestBalloonDeflate(&pSession->MemBalloon.paMemObj[i], pReq);
     567                if (RT_FAILURE(rc))
     568                {
     569                    Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc));
     570                    break;
     571                }
     572                pSession->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
     573                pSession->MemBalloon.cChunks--;
     574            }
     575            VbglGRFree(&pReq->header);
     576        }
     577        RTMemFree(pSession->MemBalloon.paMemObj);
     578        pSession->MemBalloon.paMemObj = NULL;
     579    }
     580}
     581
     582
     583/**
    519584 * Init the variables for memory ballooning
    520585 *
     
    525590    pDevExt->MemBalloon.cChunks = 0;
    526591    pDevExt->MemBalloon.cMaxChunks = 0;
    527 //#ifdef RT_OS_LINUX
    528 //    pDevExt->MemBalloon.fUseKernelAPI = true;
    529 //#else
     592#ifdef RT_OS_LINUX
     593    pDevExt->MemBalloon.fUseKernelAPI = true;
     594#else
    530595    pDevExt->MemBalloon.fUseKernelAPI = false;
    531 //#endif
     596#endif
    532597    pDevExt->MemBalloon.paMemObj = NULL;
    533598}
     
    775840int VBoxGuestCreateUserSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession)
    776841{
    777     unsigned i;
    778842    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)RTMemAllocZ(sizeof(*pSession));
    779843    if (RT_UNLIKELY(!pSession))
     
    856920    pSession->Process = NIL_RTPROCESS;
    857921    pSession->R0Process = NIL_RTR0PROCESS;
     922    vboxGuestCloseSessionMemBalloon(pSession);
    858923    RTMemFree(pSession);
    859924}
     
    10471112    Log(("VBoxGuestCommonIOCtlFast: iFunction=%#x pDevExt=%p pSession=%p\n", iFunction, pDevExt, pSession));
    10481113
     1114    NOREF(iFunction);
     1115    NOREF(pDevExt);
     1116    NOREF(pSession);
    10491117    return VERR_NOT_SUPPORTED;
    10501118}
    10511119
    10521120
    1053 
     1121/**
     1122 * Return the VMM device port.
     1123 *
     1124 * returns IPRT status code.
     1125 * @param   pDevExt         The device extension.
     1126 * @param   pInfo           The request info.
     1127 * @param   pcbDataReturned (out) contains the number of bytes to return.
     1128 */
    10541129static int VBoxGuestCommonIOCtl_GetVMMDevPort(PVBOXGUESTDEVEXT pDevExt, VBoxGuestPortInfo *pInfo, size_t *pcbDataReturned)
    10551130{
     
    17461821 */
    17471822static int VBoxGuestCommonIOCtl_QueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt,
    1748                                                    uint32_t *memBalloonSize, size_t *pcbDataReturned)
     1823                                                   VBoxGuestCheckBalloonInfo *pInfo, size_t *pcbDataReturned)
    17491824{
    17501825    VMMDevGetMemBalloonChangeRequest *pReq;
     
    17641839    }
    17651840
    1766     if (   pReq->u32BalloonSize != 0
    1767         && !pDevExt->MemBalloon.paMemObj)
    1768     {
    1769         pDevExt->MemBalloon.cMaxChunks = pReq->u32PhysMemSize;
    1770         pDevExt->MemBalloon.paMemObj = (RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pReq->u32PhysMemSize);
    1771     }
    1772 
    1773     rc = vboxGuestSetBalloonSizeKernel(pDevExt, pReq->u32BalloonSize);
    1774     /* ignore out of memory failures */
     1841    pDevExt->MemBalloon.cMaxChunks = pReq->cPhysMemChunks;
     1842
     1843    rc = vboxGuestSetBalloonSizeKernel(pDevExt, pReq->cBalloonChunks);
     1844    /* Ignore out of memory failures */
    17751845    if (rc == VERR_NO_MEMORY)
    17761846        rc = VINF_SUCCESS;
    17771847
    1778     /* Balloon size in MB */
    1779     *memBalloonSize = pReq->u32BalloonSize;
     1848    /* Return values */
     1849    pInfo->cBalloonChunks = pReq->cBalloonChunks;
     1850    pInfo->fHandleInR3 = false;
     1851    if (rc == VERR_NO_PHYS_MEMORY)
     1852    {
     1853        pInfo->fHandleInR3 = true;
     1854        rc = VINF_SUCCESS;
     1855    }
     1856
    17801857    if (pcbDataReturned)
    1781         *pcbDataReturned = sizeof(*memBalloonSize);
     1858        *pcbDataReturned = sizeof(VBoxGuestCheckBalloonInfo);
    17821859
    17831860    return rc;
     
    18091886static int VBoxGuestCommonIOCtl_Log(const char *pch, size_t cbData, size_t *pcbDataReturned)
    18101887{
     1888    NOREF(pch);
     1889    NOREF(cbData);
    18111890    Log(("%.*s", cbData, pch));
    18121891    if (pcbDataReturned)
     
    19772056
    19782057            case VBOXGUEST_IOCTL_CHECK_BALLOON:
    1979                 CHECKRET_MIN_SIZE("CHECK_MEMORY_BALLOON", sizeof(uint32_t));
    1980                 rc = VBoxGuestCommonIOCtl_QueryMemoryBalloon(pDevExt, (uint32_t *)pvData, pcbDataReturned);
     2058                CHECKRET_MIN_SIZE("CHECK_MEMORY_BALLOON", sizeof(VBoxGuestCheckBalloonInfo));
     2059                rc = VBoxGuestCommonIOCtl_QueryMemoryBalloon(pDevExt, (VBoxGuestCheckBalloonInfo *)pvData, pcbDataReturned);
    19812060                break;
    19822061
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp

    r26999 r27023  
    237237 * @returns IPRT status code
    238238 * @param   pu32Size    Memory balloon size in MBs (out)
    239  */
    240 VBGLR3DECL(int) VbglR3MemBalloonRefresh(uint32_t *pu32Size)
    241 {
    242     return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CHECK_BALLOON, pu32Size, sizeof(*pu32Size));
    243 }
    244 
    245 
    246 /**
    247  *
     239 * @param   pfHandleInR3 Allocating of memory in R3 required (out)
     240 */
     241VBGLR3DECL(int) VbglR3MemBalloonRefresh(uint32_t *pcChunks, bool *pfHandleInR3)
     242{
     243    VBoxGuestCheckBalloonInfo Info;
     244    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_CHECK_BALLOON, &Info, sizeof(Info));
     245    *pcChunks = Info.cBalloonChunks;
     246    *pfHandleInR3 = Info.fHandleInR3;
     247    return rc;
     248}
     249
     250
     251/**
     252 * Change the memory by granting/reclaiming memory to/from R0.
     253 *
     254 * @returns IPRT status code
     255 * @param   pv          Memory chunk (1MB)
     256 * @param   fInflate    true = inflate balloon (grant memory)
     257 *                      false = deflate balloon (reclaim memory)
    248258 */
    249259VBGLR3DECL(int) VbglR3MemBalloonChange(void *pv, bool fInflate)
    250260{
    251261    VBoxGuestChangeBalloonInfo Info;
    252     Info.u64ChunkAddr = (uint64_t)pv;
     262    Info.u64ChunkAddr = (uint64_t)((uintptr_t)pv);
    253263    Info.fInflate = fInflate;
    254264    return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CHANGE_BALLOON, &Info, sizeof(Info));
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp

    r26999 r27023  
    3636*   Global Variables                                                           *
    3737*******************************************************************************/
    38 static uint32_t g_MemBalloonSize = 0;
     38static uint32_t g_cMemBalloonChunks = 0;
    3939
    4040/** The semaphore we're blocking on. */
    4141static RTSEMEVENTMULTI  g_MemBalloonEvent = NIL_RTSEMEVENTMULTI;
    4242
     43/** The array holding the R3 pointers of the balloon */
    4344static void **g_pavBalloon = NULL;
    4445
    4546
    46 static void VBoxServiceBalloonSetUser(uint32_t OldSize, uint32_t NewSize)
    47 {
    48     if (NewSize == OldSize)
    49         return;
     47/**
     48 * Adapt the R0 memory balloon by granting/reclaiming 1MB chunks to/from R0.
     49 *
     50 * returns IPRT status code.
     51 * @param   cNewChunks     the number of 1MB chunks in the balloon
     52 */
     53static int VBoxServiceBalloonSetUser(uint32_t cNewChunks)
     54{
     55    if (cNewChunks == g_cMemBalloonChunks)
     56        return VINF_SUCCESS;
    5057
    5158    int rc = VINF_SUCCESS;
    52     if (NewSize > OldSize)
     59    if (cNewChunks > g_cMemBalloonChunks)
    5360    {
    5461        /* inflate */
    5562        uint32_t i;
    56         g_pavBalloon = (void**)RTMemRealloc(g_pavBalloon, NewSize * sizeof(void*));
    57         RTPrintf("allocated %d bytes\n", g_pavBalloon, NewSize * sizeof(void*));
    58         for (i = OldSize; i < NewSize; i++)
    59         {
    60             void *pv = RTMemAlloc(VMMDEV_MEMORY_BALLOON_CHUNK_PAGES * PAGE_SIZE);
    61             VBoxServiceVerbose(3, "Alloc %p\n", pv);
     63        g_pavBalloon = (void**)RTMemRealloc(g_pavBalloon, cNewChunks * sizeof(void*));
     64        for (i = g_cMemBalloonChunks; i < cNewChunks; i++)
     65        {
     66            void *pv = RTMemPageAlloc(VMMDEV_MEMORY_BALLOON_CHUNK_SIZE);
    6267            rc = VbglR3MemBalloonChange(pv, /* inflate=*/ true);
    6368            if (RT_SUCCESS(rc))
    6469            {
    65                 VBoxServiceVerbose(3, " => %Rrc\n", rc);
    6670                g_pavBalloon[i] = pv;
    67                 OldSize++;
     71                /* protect against access by dangling pointers */
     72                RTMemProtect(pv, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_NONE);
     73                g_cMemBalloonChunks++;
    6874            }
    6975            else
     
    7581        /* deflate */
    7682        uint32_t i;
    77         for (i = OldSize; i > NewSize; i--)
    78         {
    79             void *pv = g_pavBalloon[i-1];
     83        for (i = g_cMemBalloonChunks; i-- > cNewChunks;)
     84        {
     85            void *pv = g_pavBalloon[i];
    8086            rc = VbglR3MemBalloonChange(pv, /* inflate=*/ false);
    8187            if (RT_SUCCESS(rc))
    8288            {
    83                 VBoxServiceVerbose(3, "Free %p\n", g_pavBalloon[i-1]);
    84                 RTMemFree(g_pavBalloon[i-1]);
    85                 g_pavBalloon[i-1] = NULL;
    86                 OldSize--;
     89                /* unprotect */
     90                RTMemProtect(pv, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
     91                RTMemPageFree(g_pavBalloon[i]);
     92                g_pavBalloon[i] = NULL;
     93                g_cMemBalloonChunks--;
    8794            }
    8895            else
     
    9198    }
    9299
    93     if (RT_FAILURE(rc))
    94         g_MemBalloonSize = OldSize;
     100    return VINF_SUCCESS;
    95101}
    96102
     
    106112static DECLCALLBACK(int) VBoxServiceBalloonOption(const char **ppszShort, int argc, char **argv, int *pi)
    107113{
     114    NOREF(ppszShort);
     115    NOREF(argc);
     116    NOREF(argv);
     117    NOREF(pi);
    108118    return VINF_SUCCESS;
    109119}
     
    118128    AssertRCReturn(rc, rc);
    119129
    120     g_MemBalloonSize = 0;
     130    g_cMemBalloonChunks = 0;
     131    uint32_t cNewChunks = 0;
     132    bool fHandleInR3;
    121133
    122134    /* Check balloon size */
    123     rc = VbglR3MemBalloonRefresh(&g_MemBalloonSize);
     135    rc = VbglR3MemBalloonRefresh(&cNewChunks, &fHandleInR3);
    124136    if (RT_SUCCESS(rc))
    125         VBoxServiceVerbose(3, "VBoxMemBalloonInit: new balloon size %d MB\n", g_MemBalloonSize);
    126     else if (rc == VERR_NO_PHYS_MEMORY)
    127         VBoxServiceBalloonSetUser(0, g_MemBalloonSize);
     137    {
     138        VBoxServiceVerbose(3, "VBoxMemBalloonInit: new balloon size %d MB (%s memory)\n",
     139                           cNewChunks, fHandleInR3 ? "R3" : "R0");
     140        if (fHandleInR3)
     141            rc = VBoxServiceBalloonSetUser(cNewChunks);
     142        else
     143            g_cMemBalloonChunks = cNewChunks;
     144    }
    128145    else
    129         VBoxServiceVerbose(3, "VBoxMemBalloonInit: VbglR3MemBalloonRefresh failed with %d\n", rc);
     146        VBoxServiceVerbose(3, "VBoxMemBalloonInit: VbglR3MemBalloonRefresh failed with %Rrc\n", rc);
    130147
    131148    /* We shouldn't fail here if ballooning isn't available. This can have several reasons,
     
    135152
    136153
    137 uint32_t VBoxServiceBalloonQuerySize()
    138 {
    139     return g_MemBalloonSize;
     154uint32_t VBoxServiceBalloonQueryChunks()
     155{
     156    return g_cMemBalloonChunks;
    140157}
    141158
     
    149166    if (RT_FAILURE(rc))
    150167    {
    151         VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3CtlFilterMask failed with %d\n", rc);
     168        VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3CtlFilterMask failed with %Rrc\n", rc);
    152169        return rc;
    153170    }
     
    171188            &&  (fEvents & VMMDEV_EVENT_BALLOON_CHANGE_REQUEST))
    172189        {
    173             uint32_t OldMemBalloonSize = g_MemBalloonSize;
    174             rc = VbglR3MemBalloonRefresh(&g_MemBalloonSize);
     190            uint32_t cNewChunks;
     191            bool fHandleInR3;
     192            rc = VbglR3MemBalloonRefresh(&cNewChunks, &fHandleInR3);
    175193            if (RT_SUCCESS(rc))
    176                 VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: new balloon size %d MB\n", g_MemBalloonSize);
    177             else if (rc == VERR_NO_PHYS_MEMORY)
    178                 VBoxServiceBalloonSetUser(OldMemBalloonSize, g_MemBalloonSize);
     194            {
     195                VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: new balloon size %d MB (%s memory)\n",
     196                                   cNewChunks, fHandleInR3 ? "R3" : "R0");
     197                if (fHandleInR3)
     198                    rc = VBoxServiceBalloonSetUser(cNewChunks);
     199                else
     200                    g_cMemBalloonChunks = cNewChunks;
     201            }
    179202            else
    180                 VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3MemBalloonRefresh failed with %d\n", rc);
     203                VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3MemBalloonRefresh failed with %Rrc\n", rc);
    181204        }
    182205
     
    203226    rc = VbglR3CtlFilterMask(0, VMMDEV_EVENT_BALLOON_CHANGE_REQUEST);
    204227    if (RT_FAILURE(rc))
    205         VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3CtlFilterMask failed with %d\n", rc);
     228        VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3CtlFilterMask failed with %Rrc\n", rc);
    206229
    207230    RTSemEventMultiDestroy(g_MemBalloonEvent);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp

    r26611 r27023  
    133133static DECLCALLBACK(int) VBoxServiceCpuHotPlugOption(const char **ppszShort, int argc, char **argv, int *pi)
    134134{
     135    NOREF(ppszShort);
     136    NOREF(argc);
     137    NOREF(argv);
     138    NOREF(pi);
    135139    return VINF_SUCCESS;
    136140}
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h

    r26326 r27023  
    168168
    169169#ifdef VBOXSERVICE_MANAGEMENT
    170 extern uint32_t VBoxServiceBalloonQuerySize();
     170extern uint32_t VBoxServiceBalloonQueryChunks();
    171171#endif
    172172
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp

    r26901 r27023  
    7575static DECLCALLBACK(int) VBoxServiceVMStatsOption(const char **ppszShort, int argc, char **argv, int *pi)
    7676{
     77    NOREF(ppszShort);
     78    NOREF(argc);
     79    NOREF(argv);
     80    NOREF(pi);
    7781    return VINF_SUCCESS;
    7882}
     
    169173    req.guestStats.u32PageFileSize      = (uint32_t)(memStatus.ullTotalPageFile / systemInfo.dwPageSize) - req.guestStats.u32PhysMemTotal;
    170174    req.guestStats.u32MemoryLoad        = memStatus.dwMemoryLoad;
    171     req.guestStats.u32PhysMemBalloon    = VBoxServiceBalloonQuerySize() * (_1M/systemInfo.dwPageSize);    /* was in megabytes */
     175    req.guestStats.u32PhysMemBalloon    = VBoxServiceBalloonQueryChunks() * (_1M/systemInfo.dwPageSize);    /* was in megabytes */
    172176    req.guestStats.u32StatCaps          = VBOX_GUEST_STAT_PHYS_MEM_TOTAL | VBOX_GUEST_STAT_PHYS_MEM_AVAIL | VBOX_GUEST_STAT_PAGE_FILE_SIZE | VBOX_GUEST_STAT_MEMORY_LOAD | VBOX_GUEST_STAT_PHYS_MEM_BALLOON;
    173177
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r26350 r27023  
    13591359                /* just pass on the information */
    13601360                Log(("VMMDev: returning memory balloon size =%d\n", pThis->u32MemoryBalloonSize));
    1361                 memBalloonChangeRequest->u32BalloonSize = pThis->u32MemoryBalloonSize;
    1362                 memBalloonChangeRequest->u32PhysMemSize = pThis->cbGuestRAM / (uint64_t)_1M;
     1361                memBalloonChangeRequest->cBalloonChunks = pThis->u32MemoryBalloonSize;
     1362                memBalloonChangeRequest->cPhysMemChunks = pThis->cbGuestRAM / (uint64_t)_1M;
    13631363
    13641364                if (memBalloonChangeRequest->eventAck == VMMDEV_EVENT_BALLOON_CHANGE_REQUEST)
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