VirtualBox

Changeset 27106 in vbox for trunk


Ignore:
Timestamp:
Mar 5, 2010 3:49:11 PM (15 years ago)
Author:
vboxsync
Message:

common/VBoxGuest: ballooning review.

Location:
trunk/src/VBox/Additions/common/VBoxGuest
Files:
2 edited

Legend:

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

    r27054 r27106  
    4848#endif
    4949
    50 const size_t cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
     50
     51/*******************************************************************************
     52*   Global Variables                                                           *
     53*******************************************************************************/
     54static const size_t cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
     55
    5156
    5257
     
    260265{
    261266    VMMDevReportGuestInfo *pReq;
    262     int rc;
    263     rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_ReportGuestInfo);
     267    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_ReportGuestInfo);
    264268    if (RT_SUCCESS(rc))
    265269    {
     
    298302     * doesn't work for R3-provided memory, therefore ignore the return value. Unprotect
    299303     * done when object is freed. */
    300     rc = RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_NONE);
    301     NOREF(rc);
     304    RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_NONE);
    302305
    303306    pReq->fInflate = true;
     
    313316
    314317/**
    315  * Deflate the balloon by one chunk represented by an R0 memory object.
     318 * Deflate the balloon by one chunk - info the host and free the memory object.
    316319 *
    317320 * @returns IPRT status code.
     
    342345    }
    343346
     347    /* undo previous protec call, ignore rc for reasons stated there. */
     348    RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
     349    /*RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC); - probably not safe... */
     350
    344351    rc = RTR0MemObjFree(*pMemObj, true);
    345352    if (RT_FAILURE(rc))
     353    {
     354        LogRel(("vboxGuestBalloonDeflate: RTR0MemObjFree(%p,true) -> %Rrc; this is *BAD*!\n", *pMemObj, rc));
    346355        return rc;
     356    }
    347357
    348358    *pMemObj = NIL_RTR0MEMOBJ;
     
    355365 *
    356366 * @returns VBox status code.
    357  * @param   pDevExt         The device extension
     367 * @param   pDevExt         The device extension.
    358368 * @param   cBalloonChunks  The new size of the balloon in chunks of 1MB.
    359369 */
     
    369379        if (cBalloonChunks > pDevExt->MemBalloon.cMaxChunks)
    370380        {
    371             AssertMsgFailed(("vboxGuestSetBalloonSize illegal balloon size %d (max=%d)\n",
    372                              cBalloonChunks, pDevExt->MemBalloon.cMaxChunks));
     381            LogRel(("vboxGuestSetBalloonSizeKernel: illegal balloon size %u (max=%u)\n",
     382                    cBalloonChunks, pDevExt->MemBalloon.cMaxChunks));
    373383            return VERR_INVALID_PARAMETER;
    374384        }
     
    380390            && !pDevExt->MemBalloon.paMemObj)
    381391        {
    382             pDevExt->MemBalloon.paMemObj = (RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
     392            pDevExt->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
    383393            if (!pDevExt->MemBalloon.paMemObj)
    384394            {
     
    399409                rc = RTR0MemObjAllocPhysNC(&pDevExt->MemBalloon.paMemObj[i],
    400410                                           VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, NIL_RTHCPHYS);
    401                 if (RT_UNLIKELY(rc == VERR_NOT_SUPPORTED))
    402                 {
    403                     /* not supported -- fall back to the R3-allocated memory */
    404                     pDevExt->MemBalloon.fUseKernelAPI = false;
    405                     Log(("VBoxGuestSetBalloonSizeKernel: PhysNC allocs not supported, falling back to R3 allocs.\n"));
    406                     break;
    407                 }
    408                 if (RT_UNLIKELY(rc == VERR_NO_MEMORY))
    409                 {
    410                     /* cannot allocate more memory => don't try further, just stop here */
    411                     break;
    412                 }
    413411                if (RT_FAILURE(rc))
    414412                {
    415                     /* XXX what else can fail? */
     413                    if (rc == VERR_NOT_SUPPORTED)
     414                    {
     415                        /* not supported -- fall back to the R3-allocated memory */
     416                        pDevExt->MemBalloon.fUseKernelAPI = false;
     417                        Assert(pDevExt->MemBalloon.cChunks == 0);
     418                        Log(("VBoxGuestSetBalloonSizeKernel: PhysNC allocs not supported, falling back to R3 allocs.\n"));
     419                    }
     420                    /* else if (rc == VERR_NO_MEMORY): cannot allocate more memory => don't try further, just stop here */
     421                    /* else: XXX what else can fail?  VERR_MEMOBJ_INIT_FAILED for instance.   just stop. */
    416422                    break;
    417423                }
     
    421427                {
    422428                    Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc));
     429                    RTR0MemObjFree(pDevExt->MemBalloon.paMemObj[i], true);
     430                    pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
    423431                    break;
    424432                }
     
    457465/**
    458466 * Inflate/deflate the balloon by one chunk.
     467 *
     468 * @returns VBox status code.
     469 * @param   pDevExt         The device extension.
     470 * @param   pSession        The session.
     471 * @param   u64ChunkAddr    The address of the chunk to add to / remove from the
     472 *                          balloon.
     473 * @param   fInflate        Inflate if true, deflate if false.
    459474 */
    460475static int vboxGuestSetBalloonSizeFromUser(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
     
    468483    if (fInflate)
    469484    {
    470         if (pSession->MemBalloon.cChunks > pDevExt->MemBalloon.cMaxChunks - 1)
    471         {
    472             AssertMsgFailed(("vboxGuestSetBalloonSize: cannot inflate balloon, already have (max=%d)\n",
    473                              pSession->MemBalloon.cChunks, pDevExt->MemBalloon.cMaxChunks));
     485        if (   pSession->MemBalloon.cChunks > pDevExt->MemBalloon.cMaxChunks - 1
     486            || pDevExt->MemBalloon.cMaxChunks == 0 /* If called without first querying. */)
     487        {
     488            LogRel(("vboxGuestSetBalloonSize: cannot inflate balloon, already have %u chunks (max=%u)\n",
     489                    pSession->MemBalloon.cChunks, pDevExt->MemBalloon.cMaxChunks));
    474490            return VERR_INVALID_PARAMETER;
    475491        }
     
    477493        if (!pSession->MemBalloon.paMemObj)
    478494        {
    479             pSession->MemBalloon.paMemObj = (RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
     495            pSession->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAlloc(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
    480496            if (!pSession->MemBalloon.paMemObj)
    481497            {
     
    517533        if (fInflate)
    518534            return VERR_NO_MEMORY; /* no free object pointer found -- should not happen */
    519         else
    520             return VERR_NOT_FOUND; /* cannot free this memory as it wasn't provided before */
     535        return VERR_NOT_FOUND; /* cannot free this memory as it wasn't provided before */
    521536    }
    522537
     
    525540        return rc;
    526541
    527     do
    528     {
    529         if (fInflate)
    530         {
    531             rc = RTR0MemObjLockUser(pMemObj, u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE,
    532                                     RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
     542    if (fInflate)
     543    {
     544        rc = RTR0MemObjLockUser(pMemObj, u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE,
     545                                RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
     546        if (RT_SUCCESS(rc))
     547        {
     548            rc = vboxGuestBalloonInflate(pMemObj, pReq);
    533549            if (RT_SUCCESS(rc))
     550                pSession->MemBalloon.cChunks++;
     551            else
    534552            {
    535                 rc = vboxGuestBalloonInflate(pMemObj, pReq);
    536                 if (RT_FAILURE(rc))
    537                 {
    538                     Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc));
    539                     break;
    540                 }
    541                 pSession->MemBalloon.cChunks++;
     553                Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc));
     554                RTR0MemObjFree(*pMemObj, true);
     555                *pMemObj = NIL_RTR0MEMOBJ;
    542556            }
    543557        }
     558    }
     559    else
     560    {
     561        rc = vboxGuestBalloonDeflate(pMemObj, pReq);
     562        if (RT_SUCCESS(rc))
     563            pSession->MemBalloon.cChunks--;
    544564        else
    545         {
    546             rc = vboxGuestBalloonDeflate(pMemObj, pReq);
    547             if (RT_FAILURE(rc))
    548             {
    549                 Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc));
    550                 break;
    551             }
    552             pSession->MemBalloon.cChunks--;
    553         }
    554     } while (0);
     565            Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc));
     566    }
    555567
    556568    VbglGRFree(&pReq->header);
     
    599611    pDevExt->MemBalloon.cChunks = 0;
    600612    pDevExt->MemBalloon.cMaxChunks = 0;
    601 #if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
    602613    pDevExt->MemBalloon.fUseKernelAPI = true;
    603 #else
    604     pDevExt->MemBalloon.fUseKernelAPI = false;
    605 #endif
    606614    pDevExt->MemBalloon.paMemObj = NULL;
    607615}
     
    17601768 * @returns VBox status code. Unlike the other HGCM IOCtls this will combine
    17611769 *          the VbglHGCMConnect/Disconnect return code with the Info.result.
     1770 *
     1771 * @param   pDevExt             The device extension.
     1772 * @param   pu32ClientId        The client id.
     1773 * @param   pcbDataReturned     Where to store the amount of returned data. Can
     1774 *                              be NULL.
    17621775 */
    17631776static int VBoxGuestCommonIOCtl_HGCMClipboardReConnect(PVBOXGUESTDEVEXT pDevExt, uint32_t *pu32ClientId, size_t *pcbDataReturned)
     
    18231836
    18241837/**
    1825  * Handle VBOXGUEST_IOCTL_CHECK_BALLOON from R3. Ask the host for the size
    1826  * of the balloon and try to set it accordingly. If this fails, return with
    1827  * VERR_NO_PHYS_MEMORY and userland has to provide the memory.
     1838 * Handle VBOXGUEST_IOCTL_CHECK_BALLOON from R3.
     1839 *
     1840 * Ask the host for the size of the balloon and try to set it accordingly. If
     1841 * this fails, return with VERR_NO_PHYS_MEMORY and userland has to provide the
     1842 * memory.
    18281843 *
    18291844 * @returns VBox status code.
     1845 *
     1846 * @param   pDevExt             The device extension.
     1847 * @param   pInfo               The output buffer.
     1848 * @param   pcbDataReturned     Where to store the amount of returned data. Can
     1849 *                              be NULL.
    18301850 */
    18311851static int VBoxGuestCommonIOCtl_QueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt,
     
    18381858        return rc;
    18391859
     1860/** @todo r=bird: The following needs to be serialized as there is no one
     1861 *        saying mr. evil user cannot start more than one VBoxService. */
     1862
    18401863    /* This is a response to that event. Setting this bit means that we request the value
    18411864     * from the host and change the guest memory balloon according to this value. */
     
    18491872    }
    18501873
     1874    Assert(pDevExt->MemBalloon.cMaxChunks == pReq->cPhysMemChunks || pDevExt->MemBalloon.cMaxChunks == 0);
    18511875    pDevExt->MemBalloon.cMaxChunks = pReq->cPhysMemChunks;
    18521876
     
    18741898
    18751899/**
    1876  *
     1900 * Handle a request for changing the memory balloon.
     1901 *
     1902 * @returns VBox status code.
     1903 *
     1904 * @param   pDevExt             The device extention.
     1905 * @param   pSession            The session.
     1906 * @param   pInfo               The change request structure (input).
     1907 * @param   pcbDataReturned     Where to store the amount of returned data. Can
     1908 *                              be NULL.
    18771909 */
    18781910static int VBoxGuestCommonIOCtl_ChangeMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
    18791911                                                    VBoxGuestChangeBalloonInfo *pInfo, size_t *pcbDataReturned)
    18801912{
     1913/** @todo r=bird: Don't allow this if fUseKernelAPI is true.  */
     1914/** @todo r=bird: This needs to be serialized as there is no one saying mr. evil
     1915 *        user cannot start more than one VBoxService.
     1916 *
     1917 *        Actually, it would be good to drop the VBOXGUESTSESSION::MemBalloon
     1918 *        and instead add a VBOXGUESTDEVEXT::pMemBallonOwner
     1919 *        (PVBOXGUESTSESSION).  Assign balloon ownership on a first come
     1920 *        basis, releasing it when the session quits.  This could be done
     1921 *        regardless of the method use for memory allocation. */
    18811922    int rc = vboxGuestSetBalloonSizeFromUser(pDevExt, pSession, pInfo->u64ChunkAddr, pInfo->fInflate);
    18821923    if (pcbDataReturned)
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h

    r26999 r27106  
    8282typedef struct VBOXGUESTMEMBALLOON
    8383{
    84     /** The current number of chunks in the balloon */
     84    /** The current number of chunks in the balloon. */
    8585    uint32_t                    cChunks;
    8686    /** The maximum number of chunks in the balloon (typically the amount of guest
    87      * memory / chunksize) */
     87     * memory / chunksize). */
    8888    uint32_t                    cMaxChunks;
    8989    /** This is true if we are using RTR0MemObjAllocPhysNC() / RTR0MemObjGetPagePhysAddr()
    90      * and false otherwise */
     90     * and false otherwise. */
    9191    bool                        fUseKernelAPI;
    92     /* The pointer to the array of memory objects holding the chunks of the balloon */
    93     RTR0MEMOBJ                 *paMemObj;
     92    /** The pointer to the array of memory objects holding the chunks of the
     93     *  balloon.  This array is cMaxChunks in size when present. */
     94    PRTR0MEMOBJ                 paMemObj;
    9495} VBOXGUESTMEMBALLOON;
     96/** Pointer to a memory balloon. */
    9597typedef VBOXGUESTMEMBALLOON *PVBOXGUESTMEMBALLOON;
    9698
     
    140142    uint32_t                    u32ClipboardClientId;
    141143
    142     /* Memory balloon information for RTR0MemObjAllocPhysNC(). */
     144    /** Memory balloon information for RTR0MemObjAllocPhysNC(). */
    143145    VBOXGUESTMEMBALLOON         MemBalloon;
    144146
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