VirtualBox

Changeset 5211 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Oct 9, 2007 6:16:08 PM (17 years ago)
Author:
vboxsync
Message:

GVMM statistics.

Location:
trunk/src/VBox/VMM
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/STAM.cpp

    r5207 r5211  
    8383
    8484
     85/**
     86 * Init record for a ring-0 statistic sample.
     87 */
     88typedef struct STAMINITR0SAMPLE
     89{
     90    /** The VM structure offset of the variable. */
     91    unsigned        offVar;
     92    /** The type. */
     93    STAMTYPE        enmType;
     94    /** The unit. */
     95    STAMUNIT        enmUnit;
     96    /** The name. */
     97    const char     *pszName;
     98    /** The description. */
     99    const char     *pszDesc;
     100} STAMINITR0SAMPLE;
     101
     102
    85103/*******************************************************************************
    86104*   Internal Functions                                                         *
     
    96114static int stamR3PrintOne(PSTAMDESC pDesc, void *pvArg);
    97115static int stamR3EnumOne(PSTAMDESC pDesc, void *pvArg);
    98 static int stamR3Enum(PVM pVM, const char *pszPat, int (pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg);
     116static int stamR3Enum(PVM pVM, const char *pszPat, bool fUpdateRing0, int (pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg);
     117static void stamR3Ring0StatsRegister(PVM pVM);
     118static void stamR3Ring0StatsUpdate(PVM pVM, const char *pszPat);
     119static void stamR3Ring0StatsUpdateMulti(PVM pVM, const char * const *papszExpressions, unsigned cExpressions);
    99120
    100121#ifdef VBOX_WITH_DEBUGGER
     
    126147
    127148
     149/**
     150 * The GVMM init records.
     151 */
     152static const STAMINITR0SAMPLE g_aGVMMStats[] =
     153{
     154    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltCalls),        STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/HaltCalls", "The number of calls to GVMMR0SchedHalt." },
     155    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltBlocking),     STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/HaltBlocking", "The number of times we did go to sleep in GVMMR0SchedHalt." },
     156    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltTimeouts),     STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/HaltTimeouts", "The number of times we timed out in GVMMR0SchedHalt." },
     157    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltNotBlocking),  STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/HaltNotBlocking", "The number of times we didn't go to sleep in GVMMR0SchedHalt." },
     158    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltWakeUps),      STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/HaltWakeUps", "The number of wake ups done during GVMMR0SchedHalt." },
     159    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cWakeUpCalls),      STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/WakeUpCalls", "The number of calls to GVMMR0WakeUp." },
     160    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cWakeUpNotHalted),  STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/WakeUpNotHalted", "The number of times the EMT thread wasn't actually halted when GVMMR0WakeUp was called." },
     161    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cWakeUpWakeUps),    STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/WakeUpWakeUps", "The number of wake ups done during GVMMR0WakeUp (not counting the explicit one)." },
     162    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cPollCalls),        STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/PollCalls", "The number of calls to GVMMR0SchedPoll." },
     163    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cPollHalts),        STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/PollHalts", "The number of times the EMT has halted in a GVMMR0SchedPoll call." },
     164    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cPollWakeUps),      STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/VM/PollWakeUps", "The number of wake ups done during GVMMR0SchedPoll." },
     165
     166    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltCalls),       STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/HaltCalls", "The number of calls to GVMMR0SchedHalt." },
     167    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltBlocking),    STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/HaltBlocking", "The number of times we did go to sleep in GVMMR0SchedHalt." },
     168    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltTimeouts),    STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/HaltTimeouts", "The number of times we timed out in GVMMR0SchedHalt." },
     169    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltNotBlocking), STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/HaltNotBlocking", "The number of times we didn't go to sleep in GVMMR0SchedHalt." },
     170    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltWakeUps),     STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/HaltWakeUps", "The number of wake ups done during GVMMR0SchedHalt." },
     171    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cWakeUpCalls),     STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/WakeUpCalls", "The number of calls to GVMMR0WakeUp." },
     172    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cWakeUpNotHalted), STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/WakeUpNotHalted", "The number of times the EMT thread wasn't actually halted when GVMMR0WakeUp was called." },
     173    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cWakeUpWakeUps),   STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/WakeUpWakeUps", "The number of wake ups done during GVMMR0WakeUp (not counting the explicit one)." },
     174    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cPollCalls),       STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/PollCalls", "The number of calls to GVMMR0SchedPoll." },
     175    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cPollHalts),       STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/PollHalts", "The number of times the EMT has halted in a GVMMR0SchedPoll call." },
     176    { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cPollWakeUps),     STAMTYPE_U64, STAMUNIT_CALLS, "/GVMM/Sum/PollWakeUps", "The number of wake ups done during GVMMR0SchedPoll." },
     177
     178    { RT_UOFFSETOF(VM, stam.s.GVMMStats.cVMs),                      STAMTYPE_U32, STAMUNIT_CALLS, "/GVMM/VMs", "The number of VMs accessible to the caller." },
     179};
     180
    128181
    129182/**
     
    151204    if (VBOX_FAILURE(rc))
    152205        return rc;
     206
     207    /*
     208     * Register the ring-0 statistics (GVMM/GMM).
     209     */
     210    stamR3Ring0StatsRegister(pVM);
    153211
    154212#ifdef VBOX_WITH_DEBUGGER
     
    502560{
    503561    STAM_LOCK_WR(pVM);
    504     stamR3Enum(pVM, pszPat, stamR3ResetOne, pVM);
     562    stamR3Enum(pVM, pszPat, false /* fUpdateRing0 */, stamR3ResetOne, pVM);
    505563    STAM_UNLOCK_WR(pVM);
    506564    return VINF_SUCCESS;
     
    613671    stamR3SnapshotPrintf(&State, "<Statistics>\n");
    614672    STAM_LOCK_RD(pVM);
    615     int rc = stamR3Enum(pVM, pszPat, stamR3SnapshotOne, &State);
     673    int rc = stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3SnapshotOne, &State);
    616674    STAM_UNLOCK_RD(pVM);
    617675    stamR3SnapshotPrintf(&State, "</Statistics>\n");
     
    869927
    870928    STAM_LOCK_RD(pVM);
    871     stamR3Enum(pVM, pszPat, stamR3PrintOne, &Args);
     929    stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
    872930    STAM_UNLOCK_RD(pVM);
    873931    return VINF_SUCCESS;
     
    908966
    909967    STAM_LOCK_RD(pVM);
    910     stamR3Enum(pVM, pszPat, stamR3PrintOne, &Args);
     968    stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
    911969    STAM_UNLOCK_RD(pVM);
    912 
    913970    return VINF_SUCCESS;
    914971}
     
    9481005
    9491006    STAM_LOCK_RD(pVM);
    950     stamR3Enum(pVM, pszPat, stamR3PrintOne, &Args);
     1007    stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
    9511008    STAM_UNLOCK_RD(pVM);
    9521009    return VINF_SUCCESS;
     
    11041161
    11051162    STAM_LOCK_RD(pVM);
    1106     int rc = stamR3Enum(pVM, pszPat, stamR3EnumOne, &Args);
     1163    int rc = stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3EnumOne, &Args);
    11071164    STAM_UNLOCK_RD(pVM);
    11081165    return rc;
     
    11511208        switch (chPat)
    11521209        {
    1153             case '\0':
    1154                 return !*pszName;
     1210            default:
     1211                if (*pszName != chPat)
     1212                    return false;
     1213                break;
    11551214
    11561215            case '*':
     
    11781237                break;
    11791238
    1180             default:
    1181                 if (*pszName != chPat)
    1182                     return false;
    1183                 break;
     1239            case '\0':
     1240                return !*pszName;
    11841241        }
    11851242        pszName++;
     
    11961253 * @param   papszExpressions    The array of pattern expressions.
    11971254 * @param   cExpressions        The number of array entries.
    1198  * @param   piExpression        Where to read/store the current skip index.
    1199  *                              This is for future use.
     1255 * @param   piExpression        Where to read/store the current skip index. Optional.
    12001256 * @param   pszName             The name to match.
    12011257 */
     
    12031259                             unsigned *piExpression, const char *pszName)
    12041260{
    1205     for (unsigned i = *piExpression; i < cExpressions; i++)
     1261    for (unsigned i = piExpression ? *piExpression : 0; i < cExpressions; i++)
    12061262    {
    12071263        const char *pszPat = papszExpressions[i];
     
    12091265        {
    12101266            /* later:
    1211             if (i > *piExpression)
     1267            if (piExpression && i > *piExpression)
    12121268            {
    12131269                check if we can skip some expressions
     
    12281284 *
    12291285 * @returns The rc from the callback.
    1230  * @param   pVM         VM handle
    1231  * @param   pszPat      Pattern.
    1232  * @param   pfnCallback Callback function which shall be called for matching nodes.
    1233  *                      If it returns anything but VINF_SUCCESS the enumeration is
    1234  *                      terminated and the status code returned to the caller.
    1235  * @param   pvArg       User parameter for the callback.
    1236  */
    1237 static int stamR3Enum(PVM pVM, const char *pszPat, int (*pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg)
     1286 * @param   pVM             VM handle
     1287 * @param   pszPat          Pattern.
     1288 * @param   fUpdateRing0    Update the ring-0 .
     1289 * @param   pfnCallback     Callback function which shall be called for matching nodes.
     1290 *                          If it returns anything but VINF_SUCCESS the enumeration is
     1291 *                          terminated and the status code returned to the caller.
     1292 * @param   pvArg           User parameter for the callback.
     1293 */
     1294static int stamR3Enum(PVM pVM, const char *pszPat, bool fUpdateRing0, int (*pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg)
    12381295{
    12391296    int rc = VINF_SUCCESS;
     
    12441301    if (!pszPat || !*pszPat || !strcmp(pszPat, "*"))
    12451302    {
     1303        if (fUpdateRing0)
     1304            stamR3Ring0StatsUpdate(pVM, "*");
     1305
    12461306        PSTAMDESC   pCur = pVM->stam.s.pHead;
    12471307        while (pCur)
     
    12611321    else if (!strchr(pszPat, '|'))
    12621322    {
     1323        if (fUpdateRing0)
     1324            stamR3Ring0StatsUpdate(pVM, pszPat);
     1325
    12631326        for (PSTAMDESC pCur = pVM->stam.s.pHead; pCur; pCur = pCur->pNext)
    12641327            if (stamR3Match(pszPat, pCur->pszName))
     
    13121375         * Perform the enumeration.
    13131376         */
     1377        if (fUpdateRing0)
     1378            stamR3Ring0StatsUpdateMulti(pVM, papszExpressions, cExpressions);
     1379
    13141380        unsigned iExpression = 0;
    13151381        for (PSTAMDESC pCur = pVM->stam.s.pHead; pCur; pCur = pCur->pNext)
     
    13261392
    13271393    return rc;
     1394}
     1395
     1396
     1397/**
     1398 * Registers the ring-0 statistics.
     1399 *
     1400 * @param   pVM         Pointer to the shared VM structure.
     1401 */
     1402static void stamR3Ring0StatsRegister(PVM pVM)
     1403{
     1404    /* GVMM */
     1405    for (unsigned i = 0; i < RT_ELEMENTS(g_aGVMMStats); i++)
     1406        stamR3Register(pVM, (uint8_t *)pVM + g_aGVMMStats[i].offVar, NULL, NULL,
     1407                       g_aGVMMStats[i].enmType, STAMVISIBILITY_ALWAYS, g_aGVMMStats[i].pszName,
     1408                       g_aGVMMStats[i].enmUnit, g_aGVMMStats[i].pszDesc);
     1409}
     1410
     1411
     1412/**
     1413 * Updates the ring-0 statistics (the copy).
     1414 *
     1415 * @param   pVM         Pointer to the shared VM structure.
     1416 * @param   pszPat      The pattern.
     1417 */
     1418static void stamR3Ring0StatsUpdate(PVM pVM, const char *pszPat)
     1419{
     1420    stamR3Ring0StatsUpdateMulti(pVM, &pszPat, 1);
     1421}
     1422
     1423
     1424/**
     1425 * Updates the ring-0 statistics.
     1426 *
     1427 * The ring-0 statistics aren't directly addressable from ring-3 and
     1428 * must be copied when needed.
     1429 *
     1430 * @param   pVM         Pointer to the shared VM structure.
     1431 * @param   pszPat      The pattern (for knowing when to skip).
     1432 */
     1433static void stamR3Ring0StatsUpdateMulti(PVM pVM, const char * const *papszExpressions, unsigned cExpressions)
     1434{
     1435    if (!pVM->pSession)
     1436        return;
     1437
     1438    /* GVMM */
     1439    bool fUpdate = false;
     1440    for (unsigned i = 0; i < RT_ELEMENTS(g_aGVMMStats); i++)
     1441        if (stamR3MultiMatch(papszExpressions, cExpressions, NULL, g_aGVMMStats[i].pszName))
     1442        {
     1443            fUpdate = true;
     1444            break;
     1445        }
     1446    if (fUpdate)
     1447    {
     1448        GVMMQUERYSTATISTICSSREQ Req;
     1449        Req.Hdr.cbReq = sizeof(Req);
     1450        Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     1451        Req.pSession = pVM->pSession;
     1452        int rc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_GVMM_QUERY_STATISTICS, 0, &Req.Hdr);
     1453        if (RT_SUCCESS(rc))
     1454            pVM->stam.s.GVMMStats = Req.Stats;
     1455    }
    13281456}
    13291457
     
    13931521
    13941522    STAM_LOCK_RD(pVM);
    1395     int rc = stamR3Enum(pVM, cArgs ? paArgs[0].u.pszString : NULL, stamR3PrintOne, &Args);
     1523    int rc = stamR3Enum(pVM, cArgs ? paArgs[0].u.pszString : NULL, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
    13961524    STAM_UNLOCK_RD(pVM);
    13971525
  • trunk/src/VBox/VMM/STAMInternal.h

    r4776 r5211  
    2222#include <VBox/types.h>
    2323#include <VBox/stam.h>
     24#include <VBox/gvmm.h>
    2425#include <iprt/semaphore.h>
    2526
     
    115116    /** RW Lock for the list. */
    116117    RTSEMRW                 RWSem;
     118
     119    /** The copy of the GVMM statistics. */
     120    GVMMSTATS               GVMMStats;
    117121};
    118122
  • trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp

    r5167 r5211  
    168168GVMMR0DECL(int) GVMMR0Init(void)
    169169{
    170     SUPR0Printf("GVMMR0Init:\n");
     170    LogFlow(("GVMMR0Init:\n"));
    171171
    172172    /*
     
    203203
    204204            g_pGVMM = pGVMM;
    205             SUPR0Printf("GVMMR0Init: pGVMM=%p\n", pGVMM);
     205            LogFlow(("GVMMR0Init: pGVMM=%p\n", pGVMM));
    206206            return VINF_SUCCESS;
    207207        }
     
    224224GVMMR0DECL(void) GVMMR0Term(void)
    225225{
    226     SUPR0Printf("GVMMR0Term:\n");
     226    LogFlow(("GVMMR0Term:\n"));
    227227
    228228    PGVMM pGVMM = g_pGVMM;
     
    256256 *
    257257 * @returns VBox status code.
    258  * @param   pReqHdr     The request buffer.
    259  */
    260 GVMMR0DECL(int) GVMMR0CreateVMReq(PSUPVMMR0REQHDR pReqHdr)
    261 {
    262     PGVMMCREATEVMREQ pReq = (PGVMMCREATEVMREQ)pReqHdr;
    263 
     258 * @param   pReq        The request buffer.
     259 */
     260GVMMR0DECL(int) GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq)
     261{
    264262    /*
    265263     * Validate the request.
     
    421419
    422420                                        *ppVM = pVM;
    423                                         SUPR0Printf("GVMMR0CreateVM: pVM=%p pVMR3=%p pGVM=%p hGVM=%d\n", pVM, pVM->pVMR3, pGVM, iHandle);
     421                                        Log(("GVMMR0CreateVM: pVM=%p pVMR3=%p pGVM=%p hGVM=%d\n", pVM, pVM->pVMR3, pGVM, iHandle));
    424422                                        return VINF_SUCCESS;
    425423                                    }
     
    858856    RTSemFastMutexRelease(pGVMM->UsedLock);
    859857    RTSemFastMutexRelease(pGVMM->CreateDestroyLock);
    860     SUPR0Printf("gvmmR0HandleObjDestructor: returns\n");
     858    LogFlow(("gvmmR0HandleObjDestructor: returns\n"));
    861859}
    862860
     
    12111209    if (RT_FAILURE(rc))
    12121210        return rc;
     1211    pGVM->gvmm.s.StatsSched.cHaltCalls++;
    12131212
    12141213    Assert(!pGVM->gvmm.s.u64HaltExpire);
     
    12261225    Assert(ASMGetFlags() & X86_EFL_IF);
    12271226    const uint64_t u64Now = RTTimeNanoTS(); /* (GIP time) */
    1228     gvmmR0SchedDoWakeUps(pGVMM, u64Now);
     1227    pGVM->gvmm.s.StatsSched.cHaltWakeUps += gvmmR0SchedDoWakeUps(pGVMM, u64Now);
    12291228
    12301229    /*
     
    12351234             || (u64ExpireGipTime - u64Now > 750000 /* 0.750 ms */))) /** @todo make this configurable */
    12361235    {
     1236        pGVM->gvmm.s.StatsSched.cHaltBlocking++;
    12371237        ASMAtomicXchgU64(&pGVM->gvmm.s.u64HaltExpire, u64ExpireGipTime);
    12381238        RTSemFastMutexRelease(pGVMM->UsedLock);
     
    12421242        ASMAtomicXchgU64(&pGVM->gvmm.s.u64HaltExpire, 0);
    12431243        if (rc == VERR_TIMEOUT)
     1244        {
     1245            pGVM->gvmm.s.StatsSched.cHaltTimeouts++;
    12441246            rc = VINF_SUCCESS;
     1247        }
    12451248    }
    12461249    else
     1250    {
     1251        pGVM->gvmm.s.StatsSched.cHaltNotBlocking++;
    12471252        RTSemFastMutexRelease(pGVMM->UsedLock);
     1253    }
    12481254
    12491255    return rc;
     
    12691275    if (RT_SUCCESS(rc))
    12701276    {
     1277        pGVM->gvmm.s.StatsSched.cWakeUpCalls++;
     1278
    12711279        /*
    12721280         * Signal the semaphore regardless of whether it's current blocked on it.
     
    12771285         * the it is flagged as halted in the VMM.
    12781286         */
    1279         rc = pGVM->gvmm.s.u64HaltExpire
    1280            ? VINF_SUCCESS
    1281            : VINF_GVM_NOT_BLOCKED;
    1282         ASMAtomicXchgU64(&pGVM->gvmm.s.u64HaltExpire, 0);
     1287        if (pGVM->gvmm.s.u64HaltExpire)
     1288        {
     1289            rc = VINF_SUCCESS;
     1290            ASMAtomicXchgU64(&pGVM->gvmm.s.u64HaltExpire, 0);
     1291        }
     1292        else
     1293        {
     1294            rc = VINF_GVM_NOT_BLOCKED;
     1295            pGVM->gvmm.s.StatsSched.cWakeUpNotHalted++;
     1296        }
    12831297
    12841298        int rc2 = RTSemEventSignal(pGVM->gvmm.s.HaltEvent);
     
    12901304        Assert(ASMGetFlags() & X86_EFL_IF);
    12911305        const uint64_t u64Now = RTTimeNanoTS(); /* (GIP time) */
    1292         gvmmR0SchedDoWakeUps(pGVMM, u64Now);
     1306        pGVM->gvmm.s.StatsSched.cWakeUpWakeUps += gvmmR0SchedDoWakeUps(pGVMM, u64Now);
     1307
    12931308
    12941309        rc2 = RTSemFastMutexRelease(pGVMM->UsedLock);
     
    13271342        rc = RTSemFastMutexRequest(pGVMM->UsedLock);
    13281343        AssertRC(rc);
     1344        pGVM->gvmm.s.StatsSched.cPollCalls++;
    13291345
    13301346        Assert(ASMGetFlags() & X86_EFL_IF);
     
    13321348
    13331349        if (!fYield)
    1334             gvmmR0SchedDoWakeUps(pGVMM, u64Now);
     1350            pGVM->gvmm.s.StatsSched.cPollWakeUps += gvmmR0SchedDoWakeUps(pGVMM, u64Now);
    13351351        else
    13361352        {
     
    13461362}
    13471363
     1364
     1365
     1366/**
     1367 * Retrieves the GVMM statistics visible to the caller.
     1368 *
     1369 * @returns VBox status code.
     1370 *
     1371 * @param   pStats      Where to put the statistics.
     1372 * @param   pSession    The current session.
     1373 * @param   pVM         The VM to obtain statistics for. Optional.
     1374 */
     1375GVMMR0DECL(int) GVMMR0QueryStatistics(PGVMMSTATS pStats, PSUPDRVSESSION pSession, PVM pVM)
     1376{
     1377    LogFlow(("GVMMR0QueryStatistics: pStats=%p pSession=%p pVM=%p\n", pStats, pSession, pVM));
     1378
     1379    /*
     1380     * Validate input.
     1381     */
     1382    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     1383    AssertPtrReturn(pStats, VERR_INVALID_POINTER);
     1384    pStats->cVMs = 0; /* (crash before taking the sem...) */
     1385
     1386    /*
     1387     * Take the lock and get the VM statistics.
     1388     */
     1389    PGVMM pGVMM;
     1390    if (pVM)
     1391    {
     1392        PGVM pGVM;
     1393        int rc = gvmmR0ByVM(pVM, &pGVM, &pGVMM, true /*fTakeUsedLock*/);
     1394        if (RT_FAILURE(rc))
     1395            return rc;
     1396        pStats->SchedVM = pGVM->gvmm.s.StatsSched;
     1397    }
     1398    else
     1399    {
     1400        GVMM_GET_VALID_INSTANCE(pGVMM, VERR_INTERNAL_ERROR);
     1401        memset(&pStats->SchedVM, 0, sizeof(pStats->SchedVM));
     1402
     1403        int rc = RTSemFastMutexRequest(pGVMM->UsedLock);
     1404        AssertRCReturn(rc, rc);
     1405    }
     1406
     1407    /*
     1408     * Enumerate the VMs and add the ones visibile to the statistics.
     1409     */
     1410    pStats->cVMs = 0;
     1411    memset(&pStats->SchedSum, 0, sizeof(pStats->SchedSum));
     1412
     1413    for (unsigned i = pGVMM->iUsedHead;
     1414         i != NIL_GVM_HANDLE && i < RT_ELEMENTS(pGVMM->aHandles);
     1415         i = pGVMM->aHandles[i].iNext)
     1416    {
     1417        PGVM pGVM = pGVMM->aHandles[i].pGVM;
     1418        void *pvObj = pGVMM->aHandles[i].pvObj;
     1419        if (    VALID_PTR(pvObj)
     1420            &&  VALID_PTR(pGVM)
     1421            &&  pGVM->u32Magic == GVM_MAGIC
     1422            &&  RT_SUCCESS(SUPR0ObjVerifyAccess(pvObj, pSession, NULL)))
     1423        {
     1424            pStats->cVMs++;
     1425
     1426            pStats->SchedSum.cHaltCalls        += pGVM->gvmm.s.StatsSched.cHaltCalls;
     1427            pStats->SchedSum.cHaltBlocking     += pGVM->gvmm.s.StatsSched.cHaltBlocking;
     1428            pStats->SchedSum.cHaltTimeouts     += pGVM->gvmm.s.StatsSched.cHaltTimeouts;
     1429            pStats->SchedSum.cHaltNotBlocking  += pGVM->gvmm.s.StatsSched.cHaltNotBlocking;
     1430            pStats->SchedSum.cHaltWakeUps      += pGVM->gvmm.s.StatsSched.cHaltWakeUps;
     1431
     1432            pStats->SchedSum.cWakeUpCalls      += pGVM->gvmm.s.StatsSched.cWakeUpCalls;
     1433            pStats->SchedSum.cWakeUpNotHalted  += pGVM->gvmm.s.StatsSched.cWakeUpNotHalted;
     1434            pStats->SchedSum.cWakeUpWakeUps    += pGVM->gvmm.s.StatsSched.cWakeUpWakeUps;
     1435
     1436            pStats->SchedSum.cPollCalls        += pGVM->gvmm.s.StatsSched.cPollCalls;
     1437            pStats->SchedSum.cPollHalts        += pGVM->gvmm.s.StatsSched.cPollHalts;
     1438            pStats->SchedSum.cPollWakeUps      += pGVM->gvmm.s.StatsSched.cPollWakeUps;
     1439        }
     1440    }
     1441
     1442    RTSemFastMutexRelease(pGVMM->UsedLock);
     1443
     1444    return VINF_SUCCESS;
     1445}
     1446
     1447
     1448/**
     1449 * VMMR0 request wrapper for GVMMR0QueryStatistics.
     1450 *
     1451 * @returns see GVMMR0QueryStatistics.
     1452 * @param   pVM             Pointer to the shared VM structure. Optional.
     1453 * @param   pReq            The request packet.
     1454 */
     1455GVMMR0DECL(int) GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq)
     1456{
     1457    /*
     1458     * Validate input and pass it on.
     1459     */
     1460    AssertPtrReturn(pReq, VERR_INVALID_POINTER);
     1461    AssertMsgReturn(pReq->Hdr.cbReq == sizeof(*pReq), ("%#x != %#x\n", pReq->Hdr.cbReq, sizeof(*pReq)), VERR_INVALID_PARAMETER);
     1462
     1463    return GVMMR0QueryStatistics(&pReq->Stats, pReq->pSession, pVM);
     1464}
     1465
  • trunk/src/VBox/VMM/VMMR0/GVMMR0Internal.h

    r5167 r5211  
    4343    /** The APIC ID of the CPU that EMT was scheduled on the last time we checked. */
    4444    uint8_t             iCpuEmt;
     45
     46    /** The scheduler statistics. */
     47    GVMMSTATSSCHED      StatsSched;
    4548} GVMMPERVM;
    4649/** Pointer to the GVMM per VM data. */
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r5167 r5211  
    687687                return VERR_INVALID_PARAMETER;
    688688            SUPR0Printf("-> GVMMR0CreateVMReq\n");
    689             return GVMMR0CreateVMReq(pReqHdr);
     689            return GVMMR0CreateVMReq((PGVMMCREATEVMREQ)pReqHdr);
    690690
    691691        case VMMR0_DO_GVMM_DESTROY_VM:
     
    708708                return VERR_INVALID_PARAMETER;
    709709            return GVMMR0SchedPoll(pVM, (bool)u64Arg);
     710
     711        case VMMR0_DO_GVMM_QUERY_STATISTICS:
     712            if (u64Arg)
     713                return VERR_INVALID_PARAMETER;
     714            return GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr);
    710715
    711716        /*
     
    759764         */
    760765        case VMMR0_DO_GMM_INITIAL_RESERVATION:
     766            if (u64Arg)
     767                return VERR_INVALID_PARAMETER;
    761768            return GMMR0InitialReservationReq(pVM, (PGMMINITIALRESERVATIONREQ)pReqHdr);
    762769        case VMMR0_DO_GMM_UPDATE_RESERVATION:
     770            if (u64Arg)
     771                return VERR_INVALID_PARAMETER;
    763772            return GMMR0UpdateReservationReq(pVM, (PGMMUPDATERESERVATIONREQ)pReqHdr);
    764773
    765774        case VMMR0_DO_GMM_ALLOCATE_PAGES:
     775            if (u64Arg)
     776                return VERR_INVALID_PARAMETER;
    766777            return GMMR0AllocatePagesReq(pVM, (PGMMALLOCATEPAGESREQ)pReqHdr);
    767778        case VMMR0_DO_GMM_FREE_PAGES:
     779            if (u64Arg)
     780                return VERR_INVALID_PARAMETER;
    768781            return GMMR0FreePagesReq(pVM, (PGMMFREEPAGESREQ)pReqHdr);
    769782        case VMMR0_DO_GMM_BALLOONED_PAGES:
     783            if (u64Arg)
     784                return VERR_INVALID_PARAMETER;
    770785            return GMMR0BalloonedPagesReq(pVM, (PGMMBALLOONEDPAGESREQ)pReqHdr);
    771786        case VMMR0_DO_GMM_DEFLATED_BALLOON:
     787            if (pReqHdr)
     788                return VERR_INVALID_PARAMETER;
    772789            return GMMR0DeflatedBalloon(pVM, (uint32_t)u64Arg);
    773790
    774791        case VMMR0_DO_GMM_MAP_UNMAP_CHUNK:
     792            if (u64Arg)
     793                return VERR_INVALID_PARAMETER;
    775794            return GMMR0MapUnmapChunkReq(pVM, (PGMMMAPUNMAPCHUNKREQ)pReqHdr);
    776795        case VMMR0_DO_GMM_SEED_CHUNK:
     796            if (pReqHdr)
     797                return VERR_INVALID_PARAMETER;
    777798            return GMMR0SeedChunk(pVM, (RTR3PTR)u64Arg);
    778799
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