Changeset 5211 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Oct 9, 2007 6:16:08 PM (17 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/STAM.cpp
r5207 r5211 83 83 84 84 85 /** 86 * Init record for a ring-0 statistic sample. 87 */ 88 typedef 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 85 103 /******************************************************************************* 86 104 * Internal Functions * … … 96 114 static int stamR3PrintOne(PSTAMDESC pDesc, void *pvArg); 97 115 static int stamR3EnumOne(PSTAMDESC pDesc, void *pvArg); 98 static int stamR3Enum(PVM pVM, const char *pszPat, int (pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg); 116 static int stamR3Enum(PVM pVM, const char *pszPat, bool fUpdateRing0, int (pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg); 117 static void stamR3Ring0StatsRegister(PVM pVM); 118 static void stamR3Ring0StatsUpdate(PVM pVM, const char *pszPat); 119 static void stamR3Ring0StatsUpdateMulti(PVM pVM, const char * const *papszExpressions, unsigned cExpressions); 99 120 100 121 #ifdef VBOX_WITH_DEBUGGER … … 126 147 127 148 149 /** 150 * The GVMM init records. 151 */ 152 static 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 128 181 129 182 /** … … 151 204 if (VBOX_FAILURE(rc)) 152 205 return rc; 206 207 /* 208 * Register the ring-0 statistics (GVMM/GMM). 209 */ 210 stamR3Ring0StatsRegister(pVM); 153 211 154 212 #ifdef VBOX_WITH_DEBUGGER … … 502 560 { 503 561 STAM_LOCK_WR(pVM); 504 stamR3Enum(pVM, pszPat, stamR3ResetOne, pVM);562 stamR3Enum(pVM, pszPat, false /* fUpdateRing0 */, stamR3ResetOne, pVM); 505 563 STAM_UNLOCK_WR(pVM); 506 564 return VINF_SUCCESS; … … 613 671 stamR3SnapshotPrintf(&State, "<Statistics>\n"); 614 672 STAM_LOCK_RD(pVM); 615 int rc = stamR3Enum(pVM, pszPat, stamR3SnapshotOne, &State);673 int rc = stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3SnapshotOne, &State); 616 674 STAM_UNLOCK_RD(pVM); 617 675 stamR3SnapshotPrintf(&State, "</Statistics>\n"); … … 869 927 870 928 STAM_LOCK_RD(pVM); 871 stamR3Enum(pVM, pszPat, stamR3PrintOne, &Args);929 stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3PrintOne, &Args); 872 930 STAM_UNLOCK_RD(pVM); 873 931 return VINF_SUCCESS; … … 908 966 909 967 STAM_LOCK_RD(pVM); 910 stamR3Enum(pVM, pszPat, stamR3PrintOne, &Args);968 stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3PrintOne, &Args); 911 969 STAM_UNLOCK_RD(pVM); 912 913 970 return VINF_SUCCESS; 914 971 } … … 948 1005 949 1006 STAM_LOCK_RD(pVM); 950 stamR3Enum(pVM, pszPat, stamR3PrintOne, &Args);1007 stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3PrintOne, &Args); 951 1008 STAM_UNLOCK_RD(pVM); 952 1009 return VINF_SUCCESS; … … 1104 1161 1105 1162 STAM_LOCK_RD(pVM); 1106 int rc = stamR3Enum(pVM, pszPat, stamR3EnumOne, &Args);1163 int rc = stamR3Enum(pVM, pszPat, true /* fUpdateRing0 */, stamR3EnumOne, &Args); 1107 1164 STAM_UNLOCK_RD(pVM); 1108 1165 return rc; … … 1151 1208 switch (chPat) 1152 1209 { 1153 case '\0': 1154 return !*pszName; 1210 default: 1211 if (*pszName != chPat) 1212 return false; 1213 break; 1155 1214 1156 1215 case '*': … … 1178 1237 break; 1179 1238 1180 default: 1181 if (*pszName != chPat) 1182 return false; 1183 break; 1239 case '\0': 1240 return !*pszName; 1184 1241 } 1185 1242 pszName++; … … 1196 1253 * @param papszExpressions The array of pattern expressions. 1197 1254 * @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. 1200 1256 * @param pszName The name to match. 1201 1257 */ … … 1203 1259 unsigned *piExpression, const char *pszName) 1204 1260 { 1205 for (unsigned i = *piExpression; i < cExpressions; i++)1261 for (unsigned i = piExpression ? *piExpression : 0; i < cExpressions; i++) 1206 1262 { 1207 1263 const char *pszPat = papszExpressions[i]; … … 1209 1265 { 1210 1266 /* later: 1211 if ( i > *piExpression)1267 if (piExpression && i > *piExpression) 1212 1268 { 1213 1269 check if we can skip some expressions … … 1228 1284 * 1229 1285 * @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 */ 1294 static int stamR3Enum(PVM pVM, const char *pszPat, bool fUpdateRing0, int (*pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg) 1238 1295 { 1239 1296 int rc = VINF_SUCCESS; … … 1244 1301 if (!pszPat || !*pszPat || !strcmp(pszPat, "*")) 1245 1302 { 1303 if (fUpdateRing0) 1304 stamR3Ring0StatsUpdate(pVM, "*"); 1305 1246 1306 PSTAMDESC pCur = pVM->stam.s.pHead; 1247 1307 while (pCur) … … 1261 1321 else if (!strchr(pszPat, '|')) 1262 1322 { 1323 if (fUpdateRing0) 1324 stamR3Ring0StatsUpdate(pVM, pszPat); 1325 1263 1326 for (PSTAMDESC pCur = pVM->stam.s.pHead; pCur; pCur = pCur->pNext) 1264 1327 if (stamR3Match(pszPat, pCur->pszName)) … … 1312 1375 * Perform the enumeration. 1313 1376 */ 1377 if (fUpdateRing0) 1378 stamR3Ring0StatsUpdateMulti(pVM, papszExpressions, cExpressions); 1379 1314 1380 unsigned iExpression = 0; 1315 1381 for (PSTAMDESC pCur = pVM->stam.s.pHead; pCur; pCur = pCur->pNext) … … 1326 1392 1327 1393 return rc; 1394 } 1395 1396 1397 /** 1398 * Registers the ring-0 statistics. 1399 * 1400 * @param pVM Pointer to the shared VM structure. 1401 */ 1402 static 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 */ 1418 static 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 */ 1433 static 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 } 1328 1456 } 1329 1457 … … 1393 1521 1394 1522 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); 1396 1524 STAM_UNLOCK_RD(pVM); 1397 1525 -
trunk/src/VBox/VMM/STAMInternal.h
r4776 r5211 22 22 #include <VBox/types.h> 23 23 #include <VBox/stam.h> 24 #include <VBox/gvmm.h> 24 25 #include <iprt/semaphore.h> 25 26 … … 115 116 /** RW Lock for the list. */ 116 117 RTSEMRW RWSem; 118 119 /** The copy of the GVMM statistics. */ 120 GVMMSTATS GVMMStats; 117 121 }; 118 122 -
trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
r5167 r5211 168 168 GVMMR0DECL(int) GVMMR0Init(void) 169 169 { 170 SUPR0Printf("GVMMR0Init:\n");170 LogFlow(("GVMMR0Init:\n")); 171 171 172 172 /* … … 203 203 204 204 g_pGVMM = pGVMM; 205 SUPR0Printf("GVMMR0Init: pGVMM=%p\n", pGVMM);205 LogFlow(("GVMMR0Init: pGVMM=%p\n", pGVMM)); 206 206 return VINF_SUCCESS; 207 207 } … … 224 224 GVMMR0DECL(void) GVMMR0Term(void) 225 225 { 226 SUPR0Printf("GVMMR0Term:\n");226 LogFlow(("GVMMR0Term:\n")); 227 227 228 228 PGVMM pGVMM = g_pGVMM; … … 256 256 * 257 257 * @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 */ 260 GVMMR0DECL(int) GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq) 261 { 264 262 /* 265 263 * Validate the request. … … 421 419 422 420 *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)); 424 422 return VINF_SUCCESS; 425 423 } … … 858 856 RTSemFastMutexRelease(pGVMM->UsedLock); 859 857 RTSemFastMutexRelease(pGVMM->CreateDestroyLock); 860 SUPR0Printf("gvmmR0HandleObjDestructor: returns\n");858 LogFlow(("gvmmR0HandleObjDestructor: returns\n")); 861 859 } 862 860 … … 1211 1209 if (RT_FAILURE(rc)) 1212 1210 return rc; 1211 pGVM->gvmm.s.StatsSched.cHaltCalls++; 1213 1212 1214 1213 Assert(!pGVM->gvmm.s.u64HaltExpire); … … 1226 1225 Assert(ASMGetFlags() & X86_EFL_IF); 1227 1226 const uint64_t u64Now = RTTimeNanoTS(); /* (GIP time) */ 1228 gvmmR0SchedDoWakeUps(pGVMM, u64Now);1227 pGVM->gvmm.s.StatsSched.cHaltWakeUps += gvmmR0SchedDoWakeUps(pGVMM, u64Now); 1229 1228 1230 1229 /* … … 1235 1234 || (u64ExpireGipTime - u64Now > 750000 /* 0.750 ms */))) /** @todo make this configurable */ 1236 1235 { 1236 pGVM->gvmm.s.StatsSched.cHaltBlocking++; 1237 1237 ASMAtomicXchgU64(&pGVM->gvmm.s.u64HaltExpire, u64ExpireGipTime); 1238 1238 RTSemFastMutexRelease(pGVMM->UsedLock); … … 1242 1242 ASMAtomicXchgU64(&pGVM->gvmm.s.u64HaltExpire, 0); 1243 1243 if (rc == VERR_TIMEOUT) 1244 { 1245 pGVM->gvmm.s.StatsSched.cHaltTimeouts++; 1244 1246 rc = VINF_SUCCESS; 1247 } 1245 1248 } 1246 1249 else 1250 { 1251 pGVM->gvmm.s.StatsSched.cHaltNotBlocking++; 1247 1252 RTSemFastMutexRelease(pGVMM->UsedLock); 1253 } 1248 1254 1249 1255 return rc; … … 1269 1275 if (RT_SUCCESS(rc)) 1270 1276 { 1277 pGVM->gvmm.s.StatsSched.cWakeUpCalls++; 1278 1271 1279 /* 1272 1280 * Signal the semaphore regardless of whether it's current blocked on it. … … 1277 1285 * the it is flagged as halted in the VMM. 1278 1286 */ 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 } 1283 1297 1284 1298 int rc2 = RTSemEventSignal(pGVM->gvmm.s.HaltEvent); … … 1290 1304 Assert(ASMGetFlags() & X86_EFL_IF); 1291 1305 const uint64_t u64Now = RTTimeNanoTS(); /* (GIP time) */ 1292 gvmmR0SchedDoWakeUps(pGVMM, u64Now); 1306 pGVM->gvmm.s.StatsSched.cWakeUpWakeUps += gvmmR0SchedDoWakeUps(pGVMM, u64Now); 1307 1293 1308 1294 1309 rc2 = RTSemFastMutexRelease(pGVMM->UsedLock); … … 1327 1342 rc = RTSemFastMutexRequest(pGVMM->UsedLock); 1328 1343 AssertRC(rc); 1344 pGVM->gvmm.s.StatsSched.cPollCalls++; 1329 1345 1330 1346 Assert(ASMGetFlags() & X86_EFL_IF); … … 1332 1348 1333 1349 if (!fYield) 1334 gvmmR0SchedDoWakeUps(pGVMM, u64Now);1350 pGVM->gvmm.s.StatsSched.cPollWakeUps += gvmmR0SchedDoWakeUps(pGVMM, u64Now); 1335 1351 else 1336 1352 { … … 1346 1362 } 1347 1363 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 */ 1375 GVMMR0DECL(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 */ 1455 GVMMR0DECL(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 43 43 /** The APIC ID of the CPU that EMT was scheduled on the last time we checked. */ 44 44 uint8_t iCpuEmt; 45 46 /** The scheduler statistics. */ 47 GVMMSTATSSCHED StatsSched; 45 48 } GVMMPERVM; 46 49 /** Pointer to the GVMM per VM data. */ -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r5167 r5211 687 687 return VERR_INVALID_PARAMETER; 688 688 SUPR0Printf("-> GVMMR0CreateVMReq\n"); 689 return GVMMR0CreateVMReq( pReqHdr);689 return GVMMR0CreateVMReq((PGVMMCREATEVMREQ)pReqHdr); 690 690 691 691 case VMMR0_DO_GVMM_DESTROY_VM: … … 708 708 return VERR_INVALID_PARAMETER; 709 709 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); 710 715 711 716 /* … … 759 764 */ 760 765 case VMMR0_DO_GMM_INITIAL_RESERVATION: 766 if (u64Arg) 767 return VERR_INVALID_PARAMETER; 761 768 return GMMR0InitialReservationReq(pVM, (PGMMINITIALRESERVATIONREQ)pReqHdr); 762 769 case VMMR0_DO_GMM_UPDATE_RESERVATION: 770 if (u64Arg) 771 return VERR_INVALID_PARAMETER; 763 772 return GMMR0UpdateReservationReq(pVM, (PGMMUPDATERESERVATIONREQ)pReqHdr); 764 773 765 774 case VMMR0_DO_GMM_ALLOCATE_PAGES: 775 if (u64Arg) 776 return VERR_INVALID_PARAMETER; 766 777 return GMMR0AllocatePagesReq(pVM, (PGMMALLOCATEPAGESREQ)pReqHdr); 767 778 case VMMR0_DO_GMM_FREE_PAGES: 779 if (u64Arg) 780 return VERR_INVALID_PARAMETER; 768 781 return GMMR0FreePagesReq(pVM, (PGMMFREEPAGESREQ)pReqHdr); 769 782 case VMMR0_DO_GMM_BALLOONED_PAGES: 783 if (u64Arg) 784 return VERR_INVALID_PARAMETER; 770 785 return GMMR0BalloonedPagesReq(pVM, (PGMMBALLOONEDPAGESREQ)pReqHdr); 771 786 case VMMR0_DO_GMM_DEFLATED_BALLOON: 787 if (pReqHdr) 788 return VERR_INVALID_PARAMETER; 772 789 return GMMR0DeflatedBalloon(pVM, (uint32_t)u64Arg); 773 790 774 791 case VMMR0_DO_GMM_MAP_UNMAP_CHUNK: 792 if (u64Arg) 793 return VERR_INVALID_PARAMETER; 775 794 return GMMR0MapUnmapChunkReq(pVM, (PGMMMAPUNMAPCHUNKREQ)pReqHdr); 776 795 case VMMR0_DO_GMM_SEED_CHUNK: 796 if (pReqHdr) 797 return VERR_INVALID_PARAMETER; 777 798 return GMMR0SeedChunk(pVM, (RTR3PTR)u64Arg); 778 799
Note:
See TracChangeset
for help on using the changeset viewer.