VirtualBox

Changeset 75537 in vbox


Ignore:
Timestamp:
Nov 17, 2018 1:26:43 AM (6 years ago)
Author:
vboxsync
Message:

VMMDev/HGCM: Use an allocation cache for HGCM command structures with 6 or fewer parameters (also connect and disconnect). Moved the connection location out of the union just like the parameters, as it's 132 bytes big. bugref:9172

Location:
trunk/src/VBox/Devices/VMMDev
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r75532 r75537  
    29462946            {
    29472947                Assert(iCpu != NIL_VMCPUID);
    2948                 STAM_REL_COUNTER_INC(&pThis->StatHgcmReqBufAllocs);
     2948                STAM_REL_COUNTER_INC(&pThis->StatReqBufAllocs);
    29492949                pRequestHeaderFree = pRequestHeader = (VMMDevRequestHeader *)RTMemAlloc(RT_MAX(requestHeader.size, 512));
    29502950            }
     
    41234123
    41244124#ifdef VBOX_WITH_HGCM
     4125    /*
     4126     * Everything HGCM.
     4127     */
    41254128    vmmdevHGCMDestroy(pThis);
    4126     RTCritSectDelete(&pThis->critsectHGCMCmdList);
     4129#endif
     4130
     4131    /*
     4132     * Free the request buffers.
     4133     */
    41274134    for (uint32_t iCpu = 0; iCpu < RT_ELEMENTS(pThis->apReqBufs); iCpu++)
    41284135    {
     
    41304137        RTMemPageFree(pThis->apReqBufs[iCpu], _4K);
    41314138    }
    4132 #endif
    41334139
    41344140#ifndef VBOX_WITHOUT_TESTING_FEATURES
     
    44644470
    44654471#ifdef VBOX_WITH_HGCM
    4466     RTListInit(&pThis->listHGCMCmd);
    4467     rc = RTCritSectInit(&pThis->critsectHGCMCmdList);
     4472    rc = vmmdevHGCMInit(pThis);
    44684473    AssertRCReturn(rc, rc);
    4469     pThis->u32HGCMEnabled = 0;
    4470 #endif /* VBOX_WITH_HGCM */
     4474#endif
    44714475
    44724476    /*
     
    44764480    pThis->mouseCapabilities |= VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR;
    44774481
     4482    /*
     4483     * Statistics.
     4484     */
    44784485    PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatMemBalloonChunks, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Memory balloon size", "/Devices/VMMDev/BalloonChunks");
    44794486#ifdef VBOX_WITH_HGCM
     
    44844491    PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatHgcmCmdTotal,      STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
    44854492                           "Profiling whole HGCM call.",                    "/HGCM/MsgTotal");
    4486     PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatHgcmReqBufAllocs,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     4493    PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatHgcmLargeCmdAllocs,STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     4494                           "Times the allocation cache could not be used.", "/HGCM/LargeCmdAllocs");
     4495#endif
     4496    PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatReqBufAllocs,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    44874497                           "Times a larger request buffer was required.",   "/HGCM/LargeReqBufAllocs");
    4488 #endif
    44894498
    44904499    /*
  • trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp

    r75532 r75537  
    133133    bool                fRestored;
    134134
     135    /** Set if allocated from the memory cache, clear if heap. */
     136    bool                fMemCache;
     137
    135138    /** GC physical address of the guest request. */
    136139    RTGCPHYS            GCPhys;
     
    157160        {
    158161            uint32_t            u32ClientID;
    159             HGCMServiceLocation loc;
     162            HGCMServiceLocation *pLoc;  /**< Allocated after this structure. */
    160163        } connect;
    161164
     
    191194
    192195
     196/**
     197 * Version for the memory cache.
     198 */
     199typedef struct VBOXHGCMCMDCACHED
     200{
     201    VBOXHGCMCMD         Core;           /**< 112 */
     202    VBOXHGCMGUESTPARM   aGuestParms[6]; /**< 40 * 6 = 240 */
     203    VBOXHGCMSVCPARM     aHostParms[6];  /**< 24 * 6 = 144 */
     204} VBOXHGCMCMDCACHED;                    /**< 112+240+144 = 496 */
     205AssertCompile(sizeof(VBOXHGCMCMD) <= 112);
     206AssertCompile(sizeof(VBOXHGCMGUESTPARM) <= 40);
     207AssertCompile(sizeof(VBOXHGCMSVCPARM) <= 24);
     208AssertCompile(sizeof(VBOXHGCMCMDCACHED) <= 512);
     209AssertCompile(sizeof(VBOXHGCMCMDCACHED) > sizeof(VBOXHGCMCMD) + sizeof(HGCMServiceLocation));
     210
     211
    193212static int vmmdevHGCMCmdListLock(PVMMDEV pThis)
    194213{
     
    212231 * @param   cParms          Number of HGCM parameters for VBOXHGCMCMDTYPE_CALL command.
    213232 */
    214 static PVBOXHGCMCMD vmmdevHGCMCmdAlloc(VBOXHGCMCMDTYPE enmCmdType, RTGCPHYS GCPhys, uint32_t cbRequest, uint32_t cParms)
    215 {
     233static PVBOXHGCMCMD vmmdevHGCMCmdAlloc(PVMMDEV pThis, VBOXHGCMCMDTYPE enmCmdType, RTGCPHYS GCPhys, uint32_t cbRequest, uint32_t cParms)
     234{
     235#if 1
     236    /*
     237     * Try use the cache.
     238     */
     239    VBOXHGCMCMDCACHED *pCmdCached;
     240    AssertCompile(sizeof(*pCmdCached) >= sizeof(VBOXHGCMCMD) + sizeof(HGCMServiceLocation));
     241    if (cParms <= RT_ELEMENTS(pCmdCached->aGuestParms))
     242    {
     243        int rc = RTMemCacheAllocEx(pThis->hHgcmCmdCache, (void **)&pCmdCached);
     244        if (RT_SUCCESS(rc))
     245        {
     246            RT_ZERO(*pCmdCached);
     247            pCmdCached->Core.fMemCache  = true;
     248            pCmdCached->Core.GCPhys     = GCPhys;
     249            pCmdCached->Core.cbRequest  = cbRequest;
     250            pCmdCached->Core.enmCmdType = enmCmdType;
     251            if (enmCmdType == VBOXHGCMCMDTYPE_CALL)
     252            {
     253                pCmdCached->Core.u.call.cParms       = cParms;
     254                pCmdCached->Core.u.call.paGuestParms = pCmdCached->aGuestParms;
     255                pCmdCached->Core.u.call.paHostParms  = pCmdCached->aHostParms;
     256            }
     257            else if (enmCmdType == VBOXHGCMCMDTYPE_CONNECT)
     258                pCmdCached->Core.u.connect.pLoc = (HGCMServiceLocation *)(&pCmdCached->Core + 1);
     259
     260            return &pCmdCached->Core;
     261        }
     262        return NULL;
     263    }
     264    STAM_REL_COUNTER_INC(&pThis->StatHgcmLargeCmdAllocs);
     265
     266#else
     267    RT_NOREF(pThis);
     268#endif
     269
    216270    /* Size of required memory buffer. */
    217     const uint32_t cbCmd =   sizeof(struct VBOXHGCMCMD)
    218                            + cParms * sizeof(VBOXHGCMGUESTPARM)
    219                            + cParms * sizeof(VBOXHGCMSVCPARM);
     271    const uint32_t cbCmd = sizeof(VBOXHGCMCMD) + cParms * (sizeof(VBOXHGCMGUESTPARM) + sizeof(VBOXHGCMSVCPARM))
     272                         + (enmCmdType == VBOXHGCMCMDTYPE_CONNECT ? sizeof(HGCMServiceLocation) : 0);
    220273
    221274    PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ(cbCmd);
     
    237290            }
    238291        }
     292        else if (enmCmdType == VBOXHGCMCMDTYPE_CONNECT)
     293            pCmd->u.connect.pLoc = (HGCMServiceLocation *)(pCmd + 1);
    239294    }
    240295    return pCmd;
     
    276331        }
    277332
    278         RTMemFree(pCmd);
     333#if 1
     334        if (pCmd->fMemCache)
     335            RTMemCacheFree(pThis->hHgcmCmdCache, pCmd);
     336        else
     337#endif
     338            RTMemFree(pCmd);
    279339    }
    280340}
     
    358418    pCmd->enmRequestType        = pHGCMConnect->header.header.requestType;
    359419    pCmd->u.connect.u32ClientID = pHGCMConnect->u32ClientID;
    360     pCmd->u.connect.loc         = pHGCMConnect->loc;
     420    *pCmd->u.connect.pLoc       = pHGCMConnect->loc;
    361421}
    362422
     
    371431    int rc = VINF_SUCCESS;
    372432
    373     PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(VBOXHGCMCMDTYPE_CONNECT, GCPhys, pHGCMConnect->header.header.size, 0);
     433    PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(pThis, VBOXHGCMCMDTYPE_CONNECT, GCPhys, pHGCMConnect->header.header.size, 0);
    374434    if (pCmd)
    375435    {
     
    377437
    378438        /* Only allow the guest to use existing services! */
    379         ASSERT_GUEST(pCmd->u.connect.loc.type == VMMDevHGCMLoc_LocalHost_Existing);
    380         pCmd->u.connect.loc.type = VMMDevHGCMLoc_LocalHost_Existing;
     439        ASSERT_GUEST(pHGCMConnect->loc.type == VMMDevHGCMLoc_LocalHost_Existing);
     440        pCmd->u.connect.pLoc->type = VMMDevHGCMLoc_LocalHost_Existing;
    381441
    382442        vmmdevHGCMAddCommand(pThis, pCmd);
    383         rc = pThis->pHGCMDrv->pfnConnect(pThis->pHGCMDrv, pCmd, &pCmd->u.connect.loc, &pCmd->u.connect.u32ClientID);
     443        rc = pThis->pHGCMDrv->pfnConnect(pThis->pHGCMDrv, pCmd, pCmd->u.connect.pLoc, &pCmd->u.connect.u32ClientID);
    384444        if (RT_FAILURE(rc))
    385445            vmmdevHGCMRemoveCommand(pThis, pCmd);
     
    414474    int rc = VINF_SUCCESS;
    415475
    416     PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(VBOXHGCMCMDTYPE_DISCONNECT, GCPhys, pHGCMDisconnect->header.header.size, 0);
     476    PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(pThis, VBOXHGCMCMDTYPE_DISCONNECT, GCPhys, pHGCMDisconnect->header.header.size, 0);
    417477    if (pCmd)
    418478    {
     
    640700 * @param   pcbHGCMParmStruct Where to store size of used HGCM parameter structure.
    641701 */
    642 static int vmmdevHGCMCallAlloc(const VMMDevHGCMCall *pHGCMCall, uint32_t cbHGCMCall, RTGCPHYS GCPhys,
     702static int vmmdevHGCMCallAlloc(PVMMDEV pThis, const VMMDevHGCMCall *pHGCMCall, uint32_t cbHGCMCall, RTGCPHYS GCPhys,
    643703                               VMMDevRequestType enmRequestType, PVBOXHGCMCMD *ppCmd, uint32_t *pcbHGCMParmStruct)
    644704{
     
    660720    RT_UNTRUSTED_VALIDATED_FENCE();
    661721
    662     PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(VBOXHGCMCMDTYPE_CALL, GCPhys, cbHGCMCall, cParms);
     722    PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(pThis, VBOXHGCMCMDTYPE_CALL, GCPhys, cbHGCMCall, cParms);
    663723    if (pCmd == NULL)
    664724        return VERR_NO_MEMORY;
     
    919979    PVBOXHGCMCMD pCmd;
    920980    uint32_t cbHGCMParmStruct;
    921     int rc = vmmdevHGCMCallAlloc(pHGCMCall, cbHGCMCall, GCPhys, enmRequestType, &pCmd, &cbHGCMParmStruct);
     981    int rc = vmmdevHGCMCallAlloc(pThis, pHGCMCall, cbHGCMCall, GCPhys, enmRequestType, &pCmd, &cbHGCMParmStruct);
    922982    if (RT_SUCCESS(rc))
    923983    {
     
    14491509            {
    14501510                SSMR3PutU32(pSSM, pCmd->u.connect.u32ClientID);
    1451                 SSMR3PutMem(pSSM, &pCmd->u.connect.loc, sizeof(pCmd->u.connect.loc));
     1511                SSMR3PutMem(pSSM, pCmd->u.connect.pLoc, sizeof(*pCmd->u.connect.pLoc));
    14521512            }
    14531513            else if (pCmd->enmCmdType == VBOXHGCMCMDTYPE_DISCONNECT)
     
    15241584            AssertRCReturn(rc, rc);
    15251585
    1526             PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(enmCmdType, GCPhys, cbRequest, cParms);
     1586            PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(pThis, enmCmdType, GCPhys, cbRequest, cParms);
    15271587            AssertReturn(pCmd, VERR_NO_MEMORY);
    15281588
     
    15891649            {
    15901650                SSMR3GetU32(pSSM, &pCmd->u.connect.u32ClientID);
    1591                 rc = SSMR3GetMem(pSSM, &pCmd->u.connect.loc, sizeof(pCmd->u.connect.loc));
     1651                rc = SSMR3GetMem(pSSM, pCmd->u.connect.pLoc, sizeof(*pCmd->u.connect.pLoc));
    15921652                AssertRCReturn(rc, rc);
    15931653            }
     
    16461706            AssertRCReturn(rc, rc);
    16471707
    1648             PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(enmCmdType, GCPhys, cbRequest, cLinAddrs);
     1708            PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(pThis, enmCmdType, GCPhys, cbRequest, cLinAddrs);
    16491709            AssertReturn(pCmd, VERR_NO_MEMORY);
    16501710
     
    17041764            LogFlowFunc(("Restoring %RGp size %x bytes\n", GCPhys, cbRequest));
    17051765
    1706             PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(VBOXHGCMCMDTYPE_LOADSTATE, GCPhys, cbRequest, 0);
     1766            PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(pThis, VBOXHGCMCMDTYPE_LOADSTATE, GCPhys, cbRequest, 0);
    17071767            AssertReturn(pCmd, VERR_NO_MEMORY);
    17081768
     
    17401800    }
    17411801
    1742     PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(VBOXHGCMCMDTYPE_CONNECT, pLoadedCmd->GCPhys, cbReq, 0);
     1802    PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(pThis, VBOXHGCMCMDTYPE_CONNECT, pLoadedCmd->GCPhys, cbReq, 0);
    17431803    AssertReturn(pCmd, VERR_NO_MEMORY);
    17441804
     
    17841844    }
    17851845
    1786     PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(VBOXHGCMCMDTYPE_DISCONNECT, pLoadedCmd->GCPhys, cbReq, 0);
     1846    PVBOXHGCMCMD pCmd = vmmdevHGCMCmdAlloc(pThis, VBOXHGCMCMDTYPE_DISCONNECT, pLoadedCmd->GCPhys, cbReq, 0);
    17871847    AssertReturn(pCmd, VERR_NO_MEMORY);
    17881848
     
    18281888    PVBOXHGCMCMD pCmd;
    18291889    uint32_t cbHGCMParmStruct;
    1830     rc = vmmdevHGCMCallAlloc(pReq, cbReq, pLoadedCmd->GCPhys, enmRequestType, &pCmd, &cbHGCMParmStruct);
     1890    rc = vmmdevHGCMCallAlloc(pThis, pReq, cbReq, pLoadedCmd->GCPhys, enmRequestType, &pCmd, &cbHGCMParmStruct);
    18311891    if (RT_FAILURE(rc))
    18321892        return rc;
     
    20142074                    {
    20152075                        vmmdevHGCMAddCommand(pThis, pCmd);
    2016                         rcCmd = pThis->pHGCMDrv->pfnConnect(pThis->pHGCMDrv, pCmd, &pCmd->u.connect.loc, &pCmd->u.connect.u32ClientID);
     2076                        rcCmd = pThis->pHGCMDrv->pfnConnect(pThis->pHGCMDrv, pCmd, pCmd->u.connect.pLoc,
     2077                                                            &pCmd->u.connect.u32ClientID);
    20172078                        if (RT_FAILURE(rcCmd))
    20182079                            vmmdevHGCMRemoveCommand(pThis, pCmd);
     
    20922153}
    20932154
    2094 /** Deallocate HGCM commands.
     2155
     2156/**
     2157 * Counterpart to vmmdevHGCMInit().
    20952158 *
    20962159 * @param   pThis           The VMMDev instance data.
     
    20992162{
    21002163    LogFlowFunc(("\n"));
     2164
     2165    RTCritSectDelete(&pThis->critsectHGCMCmdList);
    21012166
    21022167    PVBOXHGCMCMD pCmd, pNext;
     
    21062171        vmmdevHGCMCmdFree(pThis, pCmd);
    21072172    }
    2108 }
     2173
     2174    AssertCompile((uintptr_t)NIL_RTMEMCACHE == 0);
     2175    if (pThis->hHgcmCmdCache != NIL_RTMEMCACHE)
     2176    {
     2177        RTMemCacheDestroy(pThis->hHgcmCmdCache);
     2178        pThis->hHgcmCmdCache = NIL_RTMEMCACHE;
     2179    }
     2180}
     2181
     2182
     2183/**
     2184 * Initializes the HGCM specific state.
     2185 *
     2186 * Keeps VBOXHGCMCMDCACHED and friends local.
     2187 *
     2188 * @returns VBox status code.
     2189 * @param   pThis           The VMMDev instance data.
     2190 */
     2191int vmmdevHGCMInit(PVMMDEV pThis)
     2192{
     2193    RTListInit(&pThis->listHGCMCmd);
     2194
     2195    int rc = RTCritSectInit(&pThis->critsectHGCMCmdList);
     2196    AssertLogRelRCReturn(rc, rc);
     2197
     2198    rc = RTMemCacheCreate(&pThis->hHgcmCmdCache, sizeof(VBOXHGCMCMDCACHED), 64, _1M, NULL, NULL, NULL, 0);
     2199    AssertLogRelRCReturn(rc, rc);
     2200
     2201    pThis->u32HGCMEnabled = 0;
     2202
     2203    return VINF_SUCCESS;
     2204}
     2205
  • trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.h

    r75532 r75537  
    3737
    3838void vmmdevHGCMDestroy(PVMMDEV pThis);
     39int  vmmdevHGCMInit(PVMMDEV pThis);
    3940RT_C_DECLS_END
    4041
  • trunk/src/VBox/Devices/VMMDev/VMMDevState.h

    r75532 r75537  
    2929
    3030#include <iprt/list.h>
     31#include <iprt/memcache.h>
     32
    3133
    3234#define VMMDEV_WITH_ALT_TIMESYNC
     
    283285    /** Saved state version of restored commands. */
    284286    uint32_t u32SSMVersion;
    285 # if HC_ARCH_BITS == 32
    286     /** Alignment padding. */
    287     uint32_t u32Alignment7;
    288 # endif
     287    RTMEMCACHE  hHgcmCmdCache;
    289288    STAMPROFILE StatHgcmCmdArrival;
    290289    STAMPROFILE StatHgcmCmdCompletion;
    291290    STAMPROFILE StatHgcmCmdTotal;
    292     STAMCOUNTER StatHgcmReqBufAllocs;
     291    STAMCOUNTER StatHgcmLargeCmdAllocs;
    293292#endif /* VBOX_WITH_HGCM */
     293    STAMCOUNTER StatReqBufAllocs;
    294294
    295295    /** Per CPU request 4K sized buffers, allocated as needed. */
     
    406406void VMMDevCtlSetGuestFilterMask(VMMDEV *pVMMDevState, uint32_t u32OrMask, uint32_t u32NotMask);
    407407
     408
    408409/** The saved state version. */
    409410#define VMMDEV_SAVED_STATE_VERSION                              VMMDEV_SAVED_STATE_VERSION_HGCM_PARAMS
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