diff options
Diffstat (limited to 'src/VBox/Main/src-server/Performance.cpp')
-rw-r--r-- | src/VBox/Main/src-server/Performance.cpp | 257 |
1 files changed, 203 insertions, 54 deletions
diff --git a/src/VBox/Main/src-server/Performance.cpp b/src/VBox/Main/src-server/Performance.cpp index 465bfa1c..41ace847 100644 --- a/src/VBox/Main/src-server/Performance.cpp +++ b/src/VBox/Main/src-server/Performance.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -24,8 +24,12 @@ #ifndef VBOX_COLLECTOR_TEST_CASE #include "VirtualBoxImpl.h" #include "MachineImpl.h" +#include "MediumImpl.h" +#include "AutoCaller.h" #endif #include "Performance.h" +#include "HostNetworkInterfaceImpl.h" +#include "netif.h" #include <VBox/com/array.h> #include <VBox/com/ptr.h> @@ -45,47 +49,57 @@ using namespace pm; int CollectorHAL::getHostCpuLoad(ULONG * /* user */, ULONG * /* kernel */, ULONG * /* idle */) { - return E_NOTIMPL; + return VERR_NOT_IMPLEMENTED; } int CollectorHAL::getProcessCpuLoad(RTPROCESS /* process */, ULONG * /* user */, ULONG * /* kernel */) { - return E_NOTIMPL; + return VERR_NOT_IMPLEMENTED; } int CollectorHAL::getRawHostCpuLoad(uint64_t * /* user */, uint64_t * /* kernel */, uint64_t * /* idle */) { - return E_NOTIMPL; + return VERR_NOT_IMPLEMENTED; } int CollectorHAL::getRawHostNetworkLoad(const char * /* name */, uint64_t * /* rx */, uint64_t * /* tx */) { - return E_NOTIMPL; + return VERR_NOT_IMPLEMENTED; } int CollectorHAL::getRawHostDiskLoad(const char * /* name */, uint64_t * /* disk_ms */, uint64_t * /* total_ms */) { - return E_NOTIMPL; + return VERR_NOT_IMPLEMENTED; } int CollectorHAL::getRawProcessCpuLoad(RTPROCESS /* process */, uint64_t * /* user */, uint64_t * /* kernel */, uint64_t * /* total */) { - return E_NOTIMPL; + return VERR_NOT_IMPLEMENTED; } int CollectorHAL::getHostMemoryUsage(ULONG * /* total */, ULONG * /* used */, ULONG * /* available */) { - return E_NOTIMPL; + return VERR_NOT_IMPLEMENTED; } int CollectorHAL::getHostFilesystemUsage(const char * /* name */, ULONG * /* total */, ULONG * /* used */, ULONG * /* available */) { - return E_NOTIMPL; + return VERR_NOT_IMPLEMENTED; +} + +int CollectorHAL::getHostDiskSize(const char * /* name */, uint64_t * /* size */) +{ + return VERR_NOT_IMPLEMENTED; } int CollectorHAL::getProcessMemoryUsage(RTPROCESS /* process */, ULONG * /* used */) { - return E_NOTIMPL; + return VERR_NOT_IMPLEMENTED; +} + +int CollectorHAL::getDiskListByFs(const char * /* name */, DiskList& /* listUsage */, DiskList& /* listLoad */) +{ + return VERR_NOT_IMPLEMENTED; } /* Generic implementations */ @@ -169,7 +183,7 @@ CollectorGuestRequest* CollectorGuestQueue::pop() return NULL; } -int CGRQEnable::execute() +HRESULT CGRQEnable::execute() { Assert(mCGuest); return mCGuest->enableInternal(mMask); @@ -184,7 +198,7 @@ void CGRQEnable::debugPrint(void *aObject, const char *aFunction, const char *aT aObject, aFunction, mMask, aText)); } -int CGRQDisable::execute() +HRESULT CGRQDisable::execute() { Assert(mCGuest); return mCGuest->disableInternal(mMask); @@ -199,7 +213,7 @@ void CGRQDisable::debugPrint(void *aObject, const char *aFunction, const char *a aObject, aFunction, mMask, aText)); } -int CGRQAbort::execute() +HRESULT CGRQAbort::execute() { return E_ABORT; } @@ -217,7 +231,7 @@ CollectorGuest::CollectorGuest(Machine *machine, RTPROCESS process) : mUnregistered(false), mEnabled(false), mValid(false), mMachine(machine), mProcess(process), mCpuUser(0), mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0), mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0), - mAllocVMM(0), mFreeVMM(0), mBalloonedVMM(0), mSharedVMM(0) + mAllocVMM(0), mFreeVMM(0), mBalloonedVMM(0), mSharedVMM(0), mVmNetRx(0), mVmNetTx(0) { Assert(mMachine); /* cannot use ComObjPtr<Machine> in Performance.h, do it manually */ @@ -267,7 +281,7 @@ int CollectorGuest::disable(ULONG mask) return enqueueRequest(new CGRQDisable(mask)); } -int CollectorGuest::enableInternal(ULONG mask) +HRESULT CollectorGuest::enableInternal(ULONG mask) { HRESULT ret = S_OK; @@ -306,7 +320,7 @@ int CollectorGuest::enableInternal(ULONG mask) this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed")); } } - if ((mask & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM) + if ((mask & VMSTATS_VMM_RAM) == VMSTATS_VMM_RAM) enableVMMStats(true); mEnabled |= mask; @@ -318,7 +332,7 @@ int CollectorGuest::disableInternal(ULONG mask) if (!(mEnabled & mask)) return E_UNEXPECTED; - if ((mask & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM) + if ((mask & VMSTATS_VMM_RAM) == VMSTATS_VMM_RAM) enableVMMStats(false); mEnabled &= ~mask; if (!mEnabled) @@ -328,7 +342,7 @@ int CollectorGuest::disableInternal(ULONG mask) NOREF(ret); LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 0 sec (%s)\n", this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed")); - invalidate(GUESTSTATS_ALL); + invalidate(VMSTATS_ALL); } return S_OK; @@ -353,15 +367,16 @@ void CollectorGuest::updateStats(ULONG aValidStats, ULONG aCpuUser, ULONG aMemBalloon, ULONG aMemShared, ULONG aMemCache, ULONG aPageTotal, ULONG aAllocVMM, ULONG aFreeVMM, - ULONG aBalloonedVMM, ULONG aSharedVMM) + ULONG aBalloonedVMM, ULONG aSharedVMM, + ULONG aVmNetRx, ULONG aVmNetTx) { - if ((aValidStats & GUESTSTATS_CPULOAD) == GUESTSTATS_CPULOAD) + if ((aValidStats & VMSTATS_GUEST_CPULOAD) == VMSTATS_GUEST_CPULOAD) { mCpuUser = aCpuUser; mCpuKernel = aCpuKernel, mCpuIdle = aCpuIdle; } - if ((aValidStats & GUESTSTATS_RAMUSAGE) == GUESTSTATS_RAMUSAGE) + if ((aValidStats & VMSTATS_GUEST_RAMUSAGE) == VMSTATS_GUEST_RAMUSAGE) { mMemTotal = aMemTotal; mMemFree = aMemFree; @@ -370,13 +385,18 @@ void CollectorGuest::updateStats(ULONG aValidStats, ULONG aCpuUser, mMemCache = aMemCache; mPageTotal = aPageTotal; } - if ((aValidStats & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM) + if ((aValidStats & VMSTATS_VMM_RAM) == VMSTATS_VMM_RAM) { mAllocVMM = aAllocVMM; mFreeVMM = aFreeVMM; mBalloonedVMM = aBalloonedVMM; mSharedVMM = aSharedVMM; } + if ((aValidStats & VMSTATS_NET_RATE) == VMSTATS_NET_RATE) + { + mVmNetRx = aVmNetRx; + mVmNetTx = aVmNetTx; + } mValid = aValidStats; } @@ -446,7 +466,7 @@ void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest) { /* Found the guest already collecting stats, elect it */ mVMMStatsProvider = *it; - rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(GUESTSTATS_VMMRAM)); + rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(VMSTATS_VMM_RAM)); if (FAILED(rc)) { /* This is not a good candidate -- try to find another */ @@ -466,8 +486,8 @@ void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest) continue; mVMMStatsProvider = *it; - //mVMMStatsProvider->enable(GUESTSTATS_VMMRAM); - rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(GUESTSTATS_VMMRAM)); + //mVMMStatsProvider->enable(VMSTATS_VMM_RAM); + rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(VMSTATS_VMM_RAM)); if (SUCCEEDED(rc)) break; /* This was not a good candidate -- try to find another */ @@ -508,7 +528,7 @@ int CollectorGuestManager::enqueueRequest(CollectorGuestRequest *aRequest) */ if (aRequest->getGuest() && aRequest->getGuest() == mGuestBeingCalled) { - /* + /* * Before we can declare a guest blocked we need to wait for a while * and then check again as it may never had a chance to process * the previous request. Half a second is an eternity for processes @@ -619,6 +639,12 @@ void HostCpuLoad::collect() } } +void HostCpuLoadRaw::init(ULONG period, ULONG length) +{ + HostCpuLoad::init(period, length); + mHAL->getRawHostCpuLoad(&mUserPrev, &mKernelPrev, &mIdlePrev); +} + void HostCpuLoadRaw::preCollect(CollectorHints& hints, uint64_t /* iTick */) { hints.collectHostCpuLoad(); @@ -659,13 +685,50 @@ void HostCpuLoadRaw::collect() } } +#ifndef VBOX_COLLECTOR_TEST_CASE +static bool getLinkSpeed(const char *szShortName, uint32_t *pSpeed) +{ + NETIFSTATUS enmState = NETIF_S_UNKNOWN; + int rc = NetIfGetState(szShortName, &enmState); + if (RT_FAILURE(rc)) + return false; + if (enmState != NETIF_S_UP) + *pSpeed = 0; + else + { + rc = NetIfGetLinkSpeed(szShortName, pSpeed); + if (RT_FAILURE(rc)) + return false; + } + return true; +} + +void HostNetworkSpeed::init(ULONG period, ULONG length) +{ + mPeriod = period; + mLength = length; + mLinkSpeed->init(length); + /* + * Retrieve the link speed now as it may be wrong if the metric was + * registered at boot (see @bugref{6613}). + */ + getLinkSpeed(mShortName.c_str(), &mSpeed); +} + void HostNetworkLoadRaw::init(ULONG period, ULONG length) { mPeriod = period; mLength = length; mRx->init(mLength); mTx->init(mLength); - int rc = mHAL->getRawHostNetworkLoad(mShortName.c_str(), &mRxPrev, &mTxPrev); + /* + * Retrieve the link speed now as it may be wrong if the metric was + * registered at boot (see @bugref{6613}). + */ + uint32_t uSpeedMbit = 65535; + if (getLinkSpeed(mShortName.c_str(), &uSpeedMbit)) + mSpeed = (uint64_t)uSpeedMbit * (1000000/8); /* Convert to bytes/sec */ + /*int rc =*/ mHAL->getRawHostNetworkLoad(mShortName.c_str(), &mRxPrev, &mTxPrev); //AssertRC(rc); } @@ -686,25 +749,23 @@ void HostNetworkLoadRaw::preCollect(CollectorHints& /* hints */, uint64_t /* iTi void HostNetworkLoadRaw::collect() { - uint64_t rx, tx; + uint64_t rx = mRxPrev; + uint64_t tx = mTxPrev; + if (RT_UNLIKELY(mSpeed * getPeriod() == 0)) + { + LogFlowThisFunc(("Check cable for %s! speed=%llu period=%d.\n", mShortName.c_str(), mSpeed, getPeriod())); + /* We do not collect host network metrics for unplugged interfaces! */ + return; + } mRc = mHAL->getRawHostNetworkLoad(mShortName.c_str(), &rx, &tx); if (RT_SUCCESS(mRc)) { uint64_t rxDiff = rx - mRxPrev; uint64_t txDiff = tx - mTxPrev; - if (RT_UNLIKELY(mSpeed * getPeriod() == 0)) - { - LogFlowThisFunc(("Check cable for %s! speed=%llu period=%d.\n", mShortName.c_str(), mSpeed, getPeriod())); - mRx->put(0); - mTx->put(0); - } - else - { - mRx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * rxDiff / (mSpeed * getPeriod()))); - mTx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * txDiff / (mSpeed * getPeriod()))); - } + mRx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * rxDiff / (mSpeed * getPeriod()))); + mTx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * txDiff / (mSpeed * getPeriod()))); mRxPrev = rx; mTxPrev = tx; @@ -713,6 +774,7 @@ void HostNetworkLoadRaw::collect() LogFlowThisFunc(("Failed to collect data: %Rrc (%d)." " Will update the list of interfaces...\n", mRc,mRc)); } +#endif /* !VBOX_COLLECTOR_TEST_CASE */ void HostDiskLoadRaw::init(ULONG period, ULONG length) { @@ -815,7 +877,6 @@ void HostRamUsage::collect() mTotal->put(total); mUsed->put(used); mAvailable->put(available); - } } @@ -841,10 +902,28 @@ void HostFilesystemUsage::collect() mTotal->put(total); mUsed->put(used); mAvailable->put(available); - } } +void HostDiskUsage::init(ULONG period, ULONG length) +{ + mPeriod = period; + mLength = length; + mTotal->init(mLength); +} + +void HostDiskUsage::preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) +{ +} + +void HostDiskUsage::collect() +{ + uint64_t total; + int rc = mHAL->getHostDiskSize(mDiskName.c_str(), &total); + if (RT_SUCCESS(rc)) + mTotal->put((ULONG)(total / _1M)); +} + #ifndef VBOX_COLLECTOR_TEST_CASE void HostRamVmm::init(ULONG period, ULONG length) { @@ -861,7 +940,7 @@ int HostRamVmm::enable() int rc = S_OK; CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider(); if (provider) - rc = provider->enable(GUESTSTATS_VMMRAM); + rc = provider->enable(VMSTATS_VMM_RAM); BaseMetric::enable(); return rc; } @@ -872,7 +951,7 @@ int HostRamVmm::disable() BaseMetric::disable(); CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider(); if (provider) - rc = provider->disable(GUESTSTATS_VMMRAM); + rc = provider->disable(VMSTATS_VMM_RAM); return rc; } @@ -888,15 +967,15 @@ void HostRamVmm::collect() { LogAleksey(("{%p} " LOG_FN_FMT ": provider=%p enabled=%s valid=%s...\n", this, __PRETTY_FUNCTION__, provider, provider->isEnabled()?"y":"n", - provider->isValid(GUESTSTATS_VMMRAM)?"y":"n")); - if (provider->isValid(GUESTSTATS_VMMRAM)) + provider->isValid(VMSTATS_VMM_RAM)?"y":"n")); + if (provider->isValid(VMSTATS_VMM_RAM)) { /* Provider is ready, get updated stats */ mAllocCurrent = provider->getAllocVMM(); mFreeCurrent = provider->getFreeVMM(); mBalloonedCurrent = provider->getBalloonedVMM(); mSharedCurrent = provider->getSharedVMM(); - provider->invalidate(GUESTSTATS_VMMRAM); + provider->invalidate(VMSTATS_VMM_RAM); } /* * Note that if there are no new values from the provider we will use @@ -994,6 +1073,76 @@ void MachineRamUsage::collect() #ifndef VBOX_COLLECTOR_TEST_CASE +void MachineDiskUsage::init(ULONG period, ULONG length) +{ + mPeriod = period; + mLength = length; + mUsed->init(mLength); +} + +void MachineDiskUsage::preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) +{ +} + +void MachineDiskUsage::collect() +{ + ULONG used = 0; + + for (MediaList::iterator it = mDisks.begin(); it != mDisks.end(); ++it) + { + ComObjPtr<Medium> pMedium = *it; + + /* just in case */ + AssertStmt(!pMedium.isNull(), continue); + + AutoCaller localAutoCaller(pMedium); + if (FAILED(localAutoCaller.rc())) continue; + + AutoReadLock local_alock(pMedium COMMA_LOCKVAL_SRC_POS); + + used += (ULONG)(pMedium->getSize() / _1M); + } + + mUsed->put(used); +} + +void MachineNetRate::init(ULONG period, ULONG length) +{ + mPeriod = period; + mLength = length; + + mRx->init(mLength); + mTx->init(mLength); +} + +void MachineNetRate::collect() +{ + if (mCGuest->isValid(VMSTATS_NET_RATE)) + { + mRx->put(mCGuest->getVmNetRx()); + mTx->put(mCGuest->getVmNetTx()); + mCGuest->invalidate(VMSTATS_NET_RATE); + } +} + +int MachineNetRate::enable() +{ + int rc = mCGuest->enable(VMSTATS_NET_RATE); + BaseMetric::enable(); + return rc; +} + +int MachineNetRate::disable() +{ + BaseMetric::disable(); + return mCGuest->disable(VMSTATS_NET_RATE); +} + +void MachineNetRate::preCollect(CollectorHints& hints, uint64_t /* iTick */) +{ + hints.collectGuestStats(mCGuest->getProcess()); +} + void GuestCpuLoad::init(ULONG period, ULONG length) { mPeriod = period; @@ -1011,18 +1160,18 @@ void GuestCpuLoad::preCollect(CollectorHints& hints, uint64_t /* iTick */) void GuestCpuLoad::collect() { - if (mCGuest->isValid(GUESTSTATS_CPULOAD)) + if (mCGuest->isValid(VMSTATS_GUEST_CPULOAD)) { mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuUser()) / 100); mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuKernel()) / 100); mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuIdle()) / 100); - mCGuest->invalidate(GUESTSTATS_CPULOAD); + mCGuest->invalidate(VMSTATS_GUEST_CPULOAD); } } int GuestCpuLoad::enable() { - int rc = mCGuest->enable(GUESTSTATS_CPULOAD); + int rc = mCGuest->enable(VMSTATS_GUEST_CPULOAD); BaseMetric::enable(); return rc; } @@ -1030,7 +1179,7 @@ int GuestCpuLoad::enable() int GuestCpuLoad::disable() { BaseMetric::disable(); - return mCGuest->disable(GUESTSTATS_CPULOAD); + return mCGuest->disable(VMSTATS_GUEST_CPULOAD); } void GuestRamUsage::init(ULONG period, ULONG length) @@ -1048,7 +1197,7 @@ void GuestRamUsage::init(ULONG period, ULONG length) void GuestRamUsage::collect() { - if (mCGuest->isValid(GUESTSTATS_RAMUSAGE)) + if (mCGuest->isValid(VMSTATS_GUEST_RAMUSAGE)) { mTotal->put(mCGuest->getMemTotal()); mFree->put(mCGuest->getMemFree()); @@ -1056,13 +1205,13 @@ void GuestRamUsage::collect() mShared->put(mCGuest->getMemShared()); mCache->put(mCGuest->getMemCache()); mPagedTotal->put(mCGuest->getPageTotal()); - mCGuest->invalidate(GUESTSTATS_RAMUSAGE); + mCGuest->invalidate(VMSTATS_GUEST_RAMUSAGE); } } int GuestRamUsage::enable() { - int rc = mCGuest->enable(GUESTSTATS_RAMUSAGE); + int rc = mCGuest->enable(VMSTATS_GUEST_RAMUSAGE); BaseMetric::enable(); return rc; } @@ -1070,7 +1219,7 @@ int GuestRamUsage::enable() int GuestRamUsage::disable() { BaseMetric::disable(); - return mCGuest->disable(GUESTSTATS_RAMUSAGE); + return mCGuest->disable(VMSTATS_GUEST_RAMUSAGE); } void GuestRamUsage::preCollect(CollectorHints& hints, uint64_t /* iTick */) |