VirtualBox

Changeset 36128 in vbox for trunk/src/VBox/Main/src-server


Ignore:
Timestamp:
Mar 2, 2011 5:44:04 AM (14 years ago)
Author:
vboxsync
Message:

Main/Metrics: Hypervisor and guest metrics re-done (#5566)

Location:
trunk/src/VBox/Main/src-server
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/HostImpl.cpp

    r36121 r36128  
    27942794                                                    ramUsageFree);
    27952795    aCollector->registerBaseMetric (ramUsage);
    2796     pm::BaseMetric *ramVmm = new pm::HostRamVmm(hal, objptr,
     2796    pm::BaseMetric *ramVmm = new pm::HostRamVmm(aCollector->getGuestManager(), objptr,
    27972797                                                ramVMMUsed,
    27982798                                                ramVMMFree,
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r36091 r36128  
    227227
    228228Machine::Machine()
    229     : mGuestHAL(NULL),
     229    : mCollectorGuest(NULL),
    230230      mPeer(NULL),
    231231      mParent(NULL)
     
    1006710067
    1006810068
    10069     /* Guest metrics */
    10070     mGuestHAL = new pm::CollectorGuestHAL(this, hal);
     10069    /* Guest metrics collector */
     10070    mCollectorGuest = new pm::CollectorGuest(aMachine, pid);
     10071    aCollector->registerGuest(mCollectorGuest);
     10072    LogAleksey(("{%p} " LOG_FN_FMT ": mCollectorGuest=%p\n",
     10073                this, __PRETTY_FUNCTION__, mCollectorGuest));
    1007110074
    1007210075    /* Create sub metrics */
     
    1008810091
    1008910092    /* Create and register base metrics */
    10090     pm::BaseMetric *guestCpuLoad = new pm::GuestCpuLoad(mGuestHAL, aMachine, guestLoadUser, guestLoadKernel, guestLoadIdle);
     10093    pm::BaseMetric *guestCpuLoad = new pm::GuestCpuLoad(mCollectorGuest, aMachine,
     10094                                                        guestLoadUser, guestLoadKernel, guestLoadIdle);
    1009110095    aCollector->registerBaseMetric(guestCpuLoad);
    1009210096
    10093     pm::BaseMetric *guestCpuMem = new pm::GuestRamUsage(mGuestHAL, aMachine, guestMemTotal, guestMemFree, guestMemBalloon, guestMemShared,
     10097    pm::BaseMetric *guestCpuMem = new pm::GuestRamUsage(mCollectorGuest, aMachine,
     10098                                                        guestMemTotal, guestMemFree,
     10099                                                        guestMemBalloon, guestMemShared,
    1009410100                                                        guestMemCache, guestPagedTotal);
    1009510101    aCollector->registerBaseMetric(guestCpuMem);
     
    1014910155        aCollector->unregisterMetricsFor(aMachine);
    1015010156        aCollector->unregisterBaseMetricsFor(aMachine);
    10151     }
    10152 
    10153     if (mGuestHAL)
    10154     {
    10155         delete mGuestHAL;
    10156         mGuestHAL = NULL;
    1015710157    }
    1015810158}
     
    1046510465    AutoMultiWriteLock3 multilock(mParent, mParent->host(), this COMMA_LOCKVAL_SRC_POS);
    1046610466
     10467    LogAleksey(("{%p} " LOG_FN_FMT ": mCollectorGuest=%p\n",
     10468                this, __PRETTY_FUNCTION__, mCollectorGuest));
     10469    if (mCollectorGuest)
     10470    {
     10471        mParent->performanceCollector()->unregisterGuest(mCollectorGuest);
     10472        delete mCollectorGuest;
     10473        mCollectorGuest = NULL;
     10474    }
    1046710475    // Trigger async cleanup tasks, avoid doing things here which are not
    1046810476    // vital to be done immediately and maybe need more locks. This calls
  • trunk/src/VBox/Main/src-server/Performance.cpp

    r36070 r36128  
    7676}
    7777
    78 int CollectorHAL::enable()
    79 {
    80     return E_NOTIMPL;
    81 }
    82 
    83 int  CollectorHAL::disable()
    84 {
    85     return E_NOTIMPL;
    86 }
    87 
    8878/* Generic implementations */
    8979
     
    121111#ifndef VBOX_COLLECTOR_TEST_CASE
    122112
    123 uint32_t CollectorGuestHAL::cVMsEnabled = 0;
    124 
    125 CollectorGuestHAL::CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL)
    126     : CollectorHAL(), cEnabled(0), mMachine(machine), mConsole(NULL),
    127       mGuest(NULL), mLastTick(0), mHostHAL(hostHAL), mCpuUser(0),
    128       mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0),
    129       mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0)
     113CollectorGuest::CollectorGuest(Machine *machine, RTPROCESS process) :
     114    mEnabled(false), mValid(false), mMachine(machine), mProcess(process),
     115    mCpuUser(0), mCpuKernel(0), mCpuIdle(0),
     116    mMemTotal(0), mMemFree(0), mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0),
     117    mAllocVMM(0), mFreeVMM(0), mBalloonedVMM(0), mSharedVMM(0)
    130118{
    131119    Assert(mMachine);
     
    134122}
    135123
    136 CollectorGuestHAL::~CollectorGuestHAL()
     124CollectorGuest::~CollectorGuest()
    137125{
    138126    /* cannot use ComObjPtr<Machine> in Performance.h, do it manually */
    139127    mMachine->Release();
    140     Assert(!cEnabled);
    141 }
    142 
    143 int CollectorGuestHAL::enable()
    144 {
     128    // Assert(!cEnabled); why?
     129}
     130
     131int CollectorGuest::enable()
     132{
     133    mEnabled = true;
    145134    /* Must make sure that the machine object does not get uninitialized
    146135     * in the middle of enabling this collector. Causes timing-related
     
    154143    HRESULT ret = S_OK;
    155144
    156     if (ASMAtomicIncU32(&cEnabled) == 1)
    157     {
    158         ASMAtomicIncU32(&cVMsEnabled);
    159         ComPtr<IInternalSessionControl> directControl;
    160 
    161         ret = mMachine->getDirectControl(&directControl);
    162         if (ret != S_OK)
    163             return ret;
    164 
    165         /* get the associated console; this is a remote call (!) */
    166         ret = directControl->GetRemoteConsole(mConsole.asOutParam());
    167         if (ret != S_OK)
    168             return ret;
    169 
    170         ret = mConsole->COMGETTER(Guest)(mGuest.asOutParam());
    171         if (ret == S_OK)
    172             mGuest->COMSETTER(StatisticsUpdateInterval)(1 /* 1 sec */);
    173     }
     145    ComPtr<IInternalSessionControl> directControl;
     146
     147    ret = mMachine->getDirectControl(&directControl);
     148    if (ret != S_OK)
     149        return ret;
     150
     151    /* get the associated console; this is a remote call (!) */
     152    ret = directControl->GetRemoteConsole(mConsole.asOutParam());
     153    if (ret != S_OK)
     154        return ret;
     155
     156    ret = mConsole->COMGETTER(Guest)(mGuest.asOutParam());
     157    if (ret == S_OK)
     158    {
     159        ret = mGuest->COMSETTER(StatisticsUpdateInterval)(1 /* 1 sec */);
     160        LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 1 sec (%s)\n",
     161                    this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
     162    }
     163
    174164    return ret;
    175165}
    176166
    177 int CollectorGuestHAL::disable()
    178 {
    179     if (ASMAtomicDecU32(&cEnabled) == 0)
    180     {
    181         if (ASMAtomicDecU32(&cVMsEnabled) == 0)
    182         {
    183             if (mHostHAL)
    184                 mHostHAL->setMemHypervisorStats(0 /* ulMemAllocTotal */, 0 /* ulMemFreeTotal */, 0 /* ulMemBalloonTotal */, 0 /* ulMemSharedTotal */);
    185         }
    186         Assert(mGuest && mConsole);
    187         mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */);
    188     }
     167int CollectorGuest::disable()
     168{
     169    mEnabled = false;
     170    Assert(mGuest && mConsole);
     171    HRESULT ret = mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */);
     172    LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 0 sec (%s)\n",
     173                this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
     174    invalidateStats();
     175
    189176    return S_OK;
    190177}
    191178
    192 int CollectorGuestHAL::preCollect(const CollectorHints& /* hints */, uint64_t iTick)
    193 {
    194     if (    mGuest
    195         &&  iTick != mLastTick)
    196     {
    197         ULONG ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal;
    198 
    199         mGuest->InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle,
    200                                       &mMemTotal, &mMemFree, &mMemBalloon, &mMemShared, &mMemCache,
    201                                       &mPageTotal, &ulMemAllocTotal, &ulMemFreeTotal, &ulMemBalloonTotal, &ulMemSharedTotal);
    202 
    203         if (mHostHAL)
    204             mHostHAL->setMemHypervisorStats(ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal);
    205 
    206         mLastTick = iTick;
    207     }
     179int CollectorGuest::updateStats()
     180{
     181    if (mGuest)
     182    {
     183        HRESULT rc;
     184        rc = mGuest->InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle,
     185                                           &mMemTotal, &mMemFree, &mMemBalloon, &mMemShared, &mMemCache,
     186                                           &mPageTotal, &mAllocVMM, &mFreeVMM, &mBalloonedVMM, &mSharedVMM);
     187        if (SUCCEEDED(rc))
     188        {
     189            mValid = true;
     190        }
     191        LogAleksey(("{%p} " LOG_FN_FMT ": mValid=%s mCpuUser=%u mCpuKernel=%u mCpuIdle=%u\n"
     192                    "mMemTotal=%u mMemFree=%u mMemBalloon=%u mMemShared=%u mMemCache=%u\n"
     193                    "mPageTotal=%u mAllocVMM=%u mFreeVMM=%u mBalloonedVMM=%u mSharedVMM=%u\n",
     194                    this, __PRETTY_FUNCTION__, mValid?"y":"n",
     195                    mCpuUser, mCpuKernel, mCpuIdle,
     196                    mMemTotal, mMemFree, mMemBalloon, mMemShared, mMemCache,
     197                    mPageTotal, mAllocVMM, mFreeVMM, mBalloonedVMM, mSharedVMM));
     198    }
     199
    208200    return S_OK;
    209201}
     202
     203void CollectorGuestManager::preCollect(CollectorHints& hints, uint64_t /* iTick */)
     204{
     205    CollectorGuestList::iterator it;
     206
     207    LogAleksey(("{%p} " LOG_FN_FMT ": provider=%p ramvmm=%s\n",
     208                this, __PRETTY_FUNCTION__, mVMMStatsProvider, hints.isHostRamVmmCollected()?"y":"n"));
     209    for (it = mGuests.begin(); it != mGuests.end(); it++)
     210    {
     211        LogAleksey(("{%p} " LOG_FN_FMT ": it=%p pid=%d gueststats=%s...\n",
     212                    this, __PRETTY_FUNCTION__, *it, (*it)->getProcess(),
     213                    hints.isGuestStatsCollected((*it)->getProcess())?"y":"n"));
     214        if (  (hints.isHostRamVmmCollected() && *it == mVMMStatsProvider)
     215            || hints.isGuestStatsCollected((*it)->getProcess()))
     216        {
     217            /* Guest stats collection needs to be enabled */
     218            if ((*it)->isEnabled())
     219            {
     220                /* Already enabled, collect the data */
     221                (*it)->updateStats();
     222            }
     223            else
     224            {
     225                (*it)->invalidateStats();
     226                (*it)->enable();
     227            }
     228        }
     229        else
     230        {
     231            /* Guest stats collection needs to be disabled */
     232            if ((*it)->isEnabled())
     233                (*it)->disable();
     234        }
     235    }
     236}
     237
     238void CollectorGuestManager::registerGuest(CollectorGuest* pGuest)
     239{
     240    mGuests.push_back(pGuest);
     241    /*
     242     * If no VMM stats provider was elected previously than this is our
     243     * candidate.
     244     */
     245    if (!mVMMStatsProvider)
     246        mVMMStatsProvider = pGuest;
     247    LogAleksey(("{%p} " LOG_FN_FMT ": Registered guest=%p provider=%p\n",
     248                this, __PRETTY_FUNCTION__, pGuest, mVMMStatsProvider));
     249}
     250
     251void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest)
     252{
     253    LogAleksey(("{%p} " LOG_FN_FMT ": About to unregister guest=%p provider=%p\n",
     254                this, __PRETTY_FUNCTION__, pGuest, mVMMStatsProvider));
     255    mGuests.remove(pGuest);
     256    LogAleksey(("{%p} " LOG_FN_FMT ": Number of guests after remove is %d\n",
     257                this, __PRETTY_FUNCTION__, mGuests.size()));
     258    if (pGuest == mVMMStatsProvider)
     259    {
     260        /* This was our VMM stats provider, it is time to re-elect */
     261        if (mGuests.empty())
     262        {
     263            /* Nobody can provide VMM stats */
     264            mVMMStatsProvider = NULL;
     265        }
     266        else
     267        {
     268            /* First let's look for a guest already collecting stats */
     269            CollectorGuestList::iterator it;
     270
     271            for (it = mGuests.begin(); it != mGuests.end(); it++)
     272                if ((*it)->isEnabled())
     273                {
     274                    /* Found one, elect it */
     275                    mVMMStatsProvider = *it;
     276                    LogAleksey(("{%p} " LOG_FN_FMT ": LEAVE new provider=%p\n",
     277                                this, __PRETTY_FUNCTION__, mVMMStatsProvider));
     278                    return;
     279                }
     280
     281            /* Nobody collects stats, take the first one */
     282            mVMMStatsProvider = mGuests.front();
     283        }
     284    }
     285    LogAleksey(("{%p} " LOG_FN_FMT ": LEAVE new provider=%p\n",
     286                this, __PRETTY_FUNCTION__, mVMMStatsProvider));
     287}
     288
    210289
    211290#endif /* !VBOX_COLLECTOR_TEST_CASE */
     
    225304    return false;
    226305}
    227 
    228 /*bool BaseMetric::associatedWith(ComPtr<IUnknown> object)
    229 {
    230     LogFlowThisFunc(("mObject(%p) == object(%p) is %s.\n", mObject, object, mObject == object ? "true" : "false"));
    231     return mObject == object;
    232 }*/
    233306
    234307void HostCpuLoad::init(ULONG period, ULONG length)
     
    345418}
    346419
    347 void HostRamVmm::preCollect(CollectorHints& /* hints */, uint64_t /* iTick */)
    348 {
    349     /*
    350      * This is an ugly ugly hack to force VMM metrics to 0s if no VM is
    351      * running. The reason it should work is that the VMM stats are
    352      * stored in CollectorHAL in preCollect methods of guest base metrics
    353      * which are always added after HostRamVmm. So each pass of collector
    354      * first clears the metrics then gets new values.
    355      */
    356     mHAL->setMemHypervisorStats(0 /* ulMemAllocTotal */, 0 /* ulMemFreeTotal */, 0 /* ulMemBalloonTotal */, 0 /* ulMemSharedTotal */);
     420void HostRamVmm::preCollect(CollectorHints& hints, uint64_t /* iTick */)
     421{
     422    hints.collectHostRamVmm();
    357423}
    358424
    359425void HostRamVmm::collect()
    360426{
    361     ULONG allocVMM, freeVMM, balloonVMM, sharedVMM;
    362 
    363     mHAL->getMemHypervisorStats(&allocVMM, &freeVMM, &balloonVMM, &sharedVMM);
    364     mAllocVMM->put(allocVMM);
    365     mFreeVMM->put(freeVMM);
    366     mBalloonVMM->put(balloonVMM);
    367     mSharedVMM->put(sharedVMM);
     427    CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider();
     428    if (provider)
     429    {
     430        LogAleksey(("{%p} " LOG_FN_FMT ": provider=%p enabled=%s valid=%s...\n",
     431                    this, __PRETTY_FUNCTION__, provider, provider->isEnabled()?"y":"n",
     432                    provider->isValid()?"y":"n"));
     433        if (provider->isValid())
     434        {
     435            /* Provider is ready, get updated stats */
     436            mAllocCurrent     = provider->getAllocVMM();
     437            mFreeCurrent      = provider->getFreeVMM();
     438            mBalloonedCurrent = provider->getBalloonedVMM();
     439            mSharedCurrent    = provider->getSharedVMM();
     440        }
     441    }
     442    else
     443    {
     444        mAllocCurrent     = 0;
     445        mFreeCurrent      = 0;
     446        mBalloonedCurrent = 0;
     447        mSharedCurrent    = 0;
     448    }
     449    LogAleksey(("{%p} " LOG_FN_FMT ": mAllocCurrent=%u mFreeCurrent=%u mBalloonedCurrent=%u mSharedCurrent=%u\n",
     450                this, __PRETTY_FUNCTION__,
     451                mAllocCurrent, mFreeCurrent, mBalloonedCurrent, mSharedCurrent));
     452    mAllocVMM->put(mAllocCurrent);
     453    mFreeVMM->put(mFreeCurrent);
     454    mBalloonVMM->put(mBalloonedCurrent);
     455    mSharedVMM->put(mSharedCurrent);
    368456}
    369457
     
    450538}
    451539
    452 void GuestCpuLoad::preCollect(CollectorHints& hints, uint64_t iTick)
    453 {
    454     mHAL->preCollect(hints, iTick);
     540void GuestCpuLoad::preCollect(CollectorHints& hints, uint64_t /* iTick */)
     541{
     542    hints.collectGuestStats(mCGuest->getProcess());
    455543}
    456544
    457545void GuestCpuLoad::collect()
    458546{
    459     ULONG CpuUser = 0, CpuKernel = 0, CpuIdle = 0;
    460 
    461     mGuestHAL->getGuestCpuLoad(&CpuUser, &CpuKernel, &CpuIdle);
    462     mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * CpuUser) / 100);
    463     mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * CpuKernel) / 100);
    464     mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * CpuIdle) / 100);
     547    if (mCGuest->isValid())
     548    {
     549        mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuUser()) / 100);
     550        mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuKernel()) / 100);
     551        mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuIdle()) / 100);
     552    }
    465553}
    466554
     
    478566}
    479567
    480 void GuestRamUsage::preCollect(CollectorHints& hints,  uint64_t iTick)
    481 {
    482     mHAL->preCollect(hints, iTick);
     568void GuestRamUsage::preCollect(CollectorHints& hints,  uint64_t /* iTick */)
     569{
     570    hints.collectGuestStats(mCGuest->getProcess());
    483571}
    484572
    485573void GuestRamUsage::collect()
    486574{
    487     ULONG ulMemTotal = 0, ulMemFree = 0, ulMemBalloon = 0, ulMemShared = 0, ulMemCache = 0, ulPageTotal = 0;
    488 
    489     mGuestHAL->getGuestMemLoad(&ulMemTotal, &ulMemFree, &ulMemBalloon, &ulMemShared, &ulMemCache, &ulPageTotal);
    490     mTotal->put(ulMemTotal);
    491     mFree->put(ulMemFree);
    492     mBallooned->put(ulMemBalloon);
    493     mShared->put(ulMemShared);
    494     mCache->put(ulMemCache);
    495     mPagedTotal->put(ulPageTotal);
     575    if (mCGuest->isValid())
     576    {
     577        mTotal->put(mCGuest->getMemTotal());
     578        mFree->put(mCGuest->getMemFree());
     579        mBallooned->put(mCGuest->getMemBalloon());
     580        mShared->put(mCGuest->getMemShared());
     581        mCache->put(mCGuest->getMemCache());
     582        mPagedTotal->put(mCGuest->getPageTotal());
     583    }
    496584}
    497585
     
    792880    ElementList::const_iterator it;
    793881
    794     LogAleksey(("Filter::match(%p, %s)\n", static_cast<const IUnknown*> (object), name.c_str()));
     882    //LogAleksey(("Filter::match(%p, %s)\n", static_cast<const IUnknown*> (object), name.c_str()));
    795883    for (it = mElements.begin(); it != mElements.end(); it++)
    796884    {
    797         LogAleksey(("...matching against(%p, %s)\n", static_cast<const IUnknown*> ((*it).first), (*it).second.c_str()));
     885        //LogAleksey(("...matching against(%p, %s)\n", static_cast<const IUnknown*> ((*it).first), (*it).second.c_str()));
    798886        if ((*it).first.isNull() || (*it).first == object)
    799887        {
     
    806894        }
    807895    }
    808     LogAleksey(("...no matches!\n"));
     896    //LogAleksey(("...no matches!\n"));
    809897    return false;
    810898}
  • trunk/src/VBox/Main/src-server/PerformanceImpl.cpp

    r35638 r36128  
    159159
    160160    m.hal = pm::createHAL();
     161    m.gm = new pm::CollectorGuestManager;
    161162
    162163    /* Let the sampler know it gets a valid collector.  */
     
    208209    //m.factory = NULL;
    209210
     211    delete m.gm;
     212    m.gm = NULL;
    210213    delete m.hal;
    211214    m.hal = NULL;
     
    565568}
    566569
     570void PerformanceCollector::registerGuest(pm::CollectorGuest* pGuest)
     571{
     572    AutoCaller autoCaller(this);
     573    if (!SUCCEEDED(autoCaller.rc())) return;
     574
     575    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     576    m.gm->registerGuest(pGuest);
     577}
     578
     579void PerformanceCollector::unregisterGuest(pm::CollectorGuest* pGuest)
     580{
     581    AutoCaller autoCaller(this);
     582    if (!SUCCEEDED(autoCaller.rc())) return;
     583
     584    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     585    m.gm->unregisterGuest(pGuest);
     586}
     587
    567588void PerformanceCollector::suspendSampling()
    568589{
     
    600621}
    601622
     623/*
     624 * Metrics collection is a three stage process:
     625 * 1) Pre-collection (hinting)
     626 *    At this stage we compose the list of all metrics to be collected
     627 *    If any metrics cannot be collected separately or if it is more
     628 *    efficient to collect several metric at once, these metrics should
     629 *    use hints to mark that they will need to be collected.
     630 * 2) Pre-collection (bulk)
     631 *    Using hints set at stage 1 platform-specific HAL
     632 *    instance collects all marked host-related metrics.
     633 *    Hinted guest-related metrics then get collected by CollectorGuestManager.
     634 * 3) Collection
     635 *    Metrics that are collected individually get collected and stored. Values
     636 *    saved in HAL and CollectorGuestManager are extracted and stored to
     637 *    individual metrics.
     638 */
    602639void PerformanceCollector::samplerCallback(uint64_t iTick)
    603640{
     
    618655
    619656    if (toBeCollected.size() == 0)
     657    {
     658        Log4(("{%p} " LOG_FN_FMT ": LEAVE (nothing to collect)\n", this, __PRETTY_FUNCTION__));
    620659        return;
     660    }
    621661
    622662    /* Let know the platform specific code what is being collected */
    623663    m.hal->preCollect(hints, iTick);
     664    /* Collect the data in bulk from all hinted guests */
     665    m.gm->preCollect(hints, iTick);
    624666
    625667    /* Finally, collect the data */
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