Changeset 43529 in vbox for trunk/src/VBox
- Timestamp:
- Oct 3, 2012 3:48:45 PM (12 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp
r41800 r43529 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 848 848 ("Endpoint class was already initialized\n")); 849 849 850 #ifdef VBOX_WITH_STATISTICS 851 CFGMR3QueryBoolDef(pCfgNodeClass, "AdvancedStatistics", &pEndpointClass->fGatherAdvancedStatistics, true); 852 #else 853 CFGMR3QueryBoolDef(pCfgNodeClass, "AdvancedStatistics", &pEndpointClass->fGatherAdvancedStatistics, false); 854 #endif 855 850 856 pUVM->pdm.s.apAsyncCompletionEndpointClass[pEpClassOps->enmClassType] = pEndpointClass; 851 857 LogFlowFunc((": Initialized endpoint class \"%s\" rc=%Rrc\n", pEpClassOps->pcszName, rc)); … … 902 908 903 909 /** 904 * Initialize the async completion manager. 905 * 906 * @returns VBox status code 907 * @param pVM Pointer to the VM. 908 */ 909 int pdmR3AsyncCompletionInit(PVM pVM) 910 { 911 LogFlowFunc((": pVM=%p\n", pVM)); 912 913 VM_ASSERT_EMT(pVM); 914 915 PCFGMNODE pCfgRoot = CFGMR3GetRoot(pVM); 916 PCFGMNODE pCfgAsyncCompletion = CFGMR3GetChild(CFGMR3GetChild(pCfgRoot, "PDM"), "AsyncCompletion"); 917 918 int rc = pdmR3AsyncCompletionEpClassInit(pVM, &g_PDMAsyncCompletionEndpointClassFile, pCfgAsyncCompletion); 919 LogFlowFunc((": pVM=%p rc=%Rrc\n", pVM, rc)); 920 return rc; 921 } 922 923 /** 924 * Terminates the async completion manager. 925 * 926 * @returns VBox status code 927 * @param pVM Pointer to the VM. 928 */ 929 int pdmR3AsyncCompletionTerm(PVM pVM) 930 { 931 LogFlowFunc((": pVM=%p\n", pVM)); 932 PUVM pUVM = pVM->pUVM; 933 934 for (size_t i = 0; i < RT_ELEMENTS(pUVM->pdm.s.apAsyncCompletionEndpointClass); i++) 935 if (pUVM->pdm.s.apAsyncCompletionEndpointClass[i]) 936 pdmR3AsyncCompletionEpClassTerminate(pUVM->pdm.s.apAsyncCompletionEndpointClass[i]); 937 938 return VINF_SUCCESS; 939 } 940 941 /** 942 * Resume worker for the async completion manager. 910 * Records the size of the request in the statistics. 943 911 * 944 912 * @returns nothing. 945 * @param pVM Pointer to the VM. 946 */ 947 void pdmR3AsyncCompletionResume(PVM pVM) 948 { 949 LogFlowFunc((": pVM=%p\n", pVM)); 950 PUVM pUVM = pVM->pUVM; 951 952 /* Log the bandwidth groups and all assigned endpoints. */ 953 for (size_t i = 0; i < RT_ELEMENTS(pUVM->pdm.s.apAsyncCompletionEndpointClass); i++) 954 if (pUVM->pdm.s.apAsyncCompletionEndpointClass[i]) 955 { 956 PPDMASYNCCOMPLETIONEPCLASS pEpClass = pUVM->pdm.s.apAsyncCompletionEndpointClass[i]; 957 PPDMACBWMGR pBwMgr = pEpClass->pBwMgrsHead; 958 PPDMASYNCCOMPLETIONENDPOINT pEp; 959 960 if (pBwMgr) 961 LogRel(("AIOMgr: Bandwidth groups for class '%s'\n", i == PDMASYNCCOMPLETIONEPCLASSTYPE_FILE 962 ? "File" : "<Unknown>")); 963 964 while (pBwMgr) 965 { 966 LogRel(("AIOMgr: Id: %s\n", pBwMgr->pszId)); 967 LogRel(("AIOMgr: Max: %u B/s\n", pBwMgr->cbTransferPerSecMax)); 968 LogRel(("AIOMgr: Start: %u B/s\n", pBwMgr->cbTransferPerSecStart)); 969 LogRel(("AIOMgr: Step: %u B/s\n", pBwMgr->cbTransferPerSecStep)); 970 LogRel(("AIOMgr: Endpoints:\n")); 971 972 pEp = pEpClass->pEndpointsHead; 973 while (pEp) 974 { 975 if (pEp->pBwMgr == pBwMgr) 976 LogRel(("AIOMgr: %s\n", pEp->pszUri)); 977 978 pEp = pEp->pNext; 979 } 980 981 pBwMgr = pBwMgr->pNext; 982 } 983 984 /* Print all endpoints without assigned bandwidth groups. */ 985 pEp = pEpClass->pEndpointsHead; 986 if (pEp) 987 LogRel(("AIOMgr: Endpoints without assigned bandwidth groups:\n")); 988 989 while (pEp) 990 { 991 if (!pEp->pBwMgr) 992 LogRel(("AIOMgr: %s\n", pEp->pszUri)); 993 994 pEp = pEp->pNext; 995 } 996 } 997 } 998 999 /** 1000 * Tries to get a free task from the endpoint or class cache 1001 * allocating the task if it fails. 1002 * 1003 * @returns Pointer to a new and initialized task or NULL 1004 * @param pEndpoint The endpoint the task is for. 1005 * @param pvUser Opaque user data for the task. 1006 */ 1007 static PPDMASYNCCOMPLETIONTASK pdmR3AsyncCompletionGetTask(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, void *pvUser) 1008 { 1009 PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pEndpoint->pEpClass; 1010 PPDMASYNCCOMPLETIONTASK pTask = (PPDMASYNCCOMPLETIONTASK)RTMemCacheAlloc(pEndpointClass->hMemCacheTasks); 1011 if (RT_LIKELY(pTask)) 1012 { 1013 /* Initialize common parts. */ 1014 pTask->pvUser = pvUser; 1015 pTask->pEndpoint = pEndpoint; 1016 /* Clear list pointers for safety. */ 1017 pTask->pPrev = NULL; 1018 pTask->pNext = NULL; 1019 pTask->tsNsStart = RTTimeNanoTS(); 1020 #ifdef VBOX_WITH_STATISTICS 1021 STAM_COUNTER_INC(&pEndpoint->StatIoOpsStarted); 1022 #endif 1023 } 1024 1025 return pTask; 1026 } 1027 1028 /** 1029 * Puts a task in one of the caches. 913 * @param pEndpoint The endpoint to register the request size for. 914 * @param cbReq Size of the request. 915 */ 916 static void pdmR3AsyncCompletionStatisticsRecordSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, size_t cbReq) 917 { 918 if (cbReq < 512) 919 STAM_COUNTER_INC(&pEndpoint->StatReqSizeSmaller512); 920 else if (cbReq < _1K) 921 STAM_COUNTER_INC(&pEndpoint->StatReqSize512To1K); 922 else if (cbReq < _2K) 923 STAM_COUNTER_INC(&pEndpoint->StatReqSize1KTo2K); 924 else if (cbReq < _4K) 925 STAM_COUNTER_INC(&pEndpoint->StatReqSize2KTo4K); 926 else if (cbReq < _8K) 927 STAM_COUNTER_INC(&pEndpoint->StatReqSize4KTo8K); 928 else if (cbReq < _16K) 929 STAM_COUNTER_INC(&pEndpoint->StatReqSize8KTo16K); 930 else if (cbReq < _32K) 931 STAM_COUNTER_INC(&pEndpoint->StatReqSize16KTo32K); 932 else if (cbReq < _64K) 933 STAM_COUNTER_INC(&pEndpoint->StatReqSize32KTo64K); 934 else if (cbReq < _128K) 935 STAM_COUNTER_INC(&pEndpoint->StatReqSize64KTo128K); 936 else if (cbReq < _256K) 937 STAM_COUNTER_INC(&pEndpoint->StatReqSize128KTo256K); 938 else if (cbReq < _512K) 939 STAM_COUNTER_INC(&pEndpoint->StatReqSize256KTo512K); 940 else 941 STAM_COUNTER_INC(&pEndpoint->StatReqSizeOver512K); 942 943 if (cbReq & ((size_t)512 - 1)) 944 STAM_COUNTER_INC(&pEndpoint->StatReqsUnaligned512); 945 else if (cbReq & ((size_t)_4K - 1)) 946 STAM_COUNTER_INC(&pEndpoint->StatReqsUnaligned4K); 947 } 948 949 /** 950 * Records the required processing time of a request. 1030 951 * 1031 952 * @returns nothing. 1032 * @param pEndpoint The endpoint the task belongs to. 1033 * @param pTask The task to cache. 1034 */ 1035 static void pdmR3AsyncCompletionPutTask(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, PPDMASYNCCOMPLETIONTASK pTask) 1036 { 1037 PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pEndpoint->pEpClass; 1038 uint64_t cNsRun = RTTimeNanoTS() - pTask->tsNsStart; 1039 1040 if (RT_UNLIKELY(cNsRun >= RT_NS_10SEC)) 1041 LogRel(("AsyncCompletion: Task %#p completed after %llu seconds\n", pTask, cNsRun / RT_NS_1SEC)); 1042 1043 #ifdef VBOX_WITH_STATISTICS 953 * @param pEndpoint The endpoint. 954 * @param cNsRun The request time in nanoseconds. 955 */ 956 static void pdmR3AsyncCompletionStatisticsRecordCompletionTime(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t cNsRun) 957 { 1044 958 PSTAMCOUNTER pStatCounter; 1045 959 if (cNsRun < RT_NS_1US) … … 1065 979 pEndpoint->cIoOpsCompleted = 0; 1066 980 } 1067 #endif /* VBOX_WITH_STATISTICS */ 981 } 982 983 /** 984 * Registers advanced statistics for the given endpoint. 985 * 986 * @returns VBox status code. 987 * @param pEndpoint The endpoint to register the advanced statistics for. 988 */ 989 static int pdmR3AsyncCompletionStatisticsRegister(PPDMASYNCCOMPLETIONENDPOINT pEndpoint) 990 { 991 int rc = VINF_SUCCESS; 992 PVM pVM = pEndpoint->pEpClass->pVM; 993 994 pEndpoint->tsIntervalStartMs = RTTimeMilliTS(); 995 996 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesNs); i++) 997 { 998 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesNs[i], STAMTYPE_COUNTER, 999 STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 1000 "Nanosecond resolution runtime statistics", 1001 "/PDM/AsyncCompletion/File/%s/TaskRun1Ns-%u-%u", 1002 RTPathFilename(pEndpoint->pszUri), i*100, i*100+100-1); 1003 if (RT_FAILURE(rc)) 1004 break; 1005 } 1006 1007 if (RT_SUCCESS(rc)) 1008 { 1009 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesUs); i++) 1010 { 1011 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesUs[i], STAMTYPE_COUNTER, 1012 STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 1013 "Microsecond resolution runtime statistics", 1014 "/PDM/AsyncCompletion/File/%s/TaskRun2MicroSec-%u-%u", 1015 RTPathFilename(pEndpoint->pszUri), i*100, i*100+100-1); 1016 if (RT_FAILURE(rc)) 1017 break; 1018 } 1019 } 1020 1021 if (RT_SUCCESS(rc)) 1022 { 1023 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++) 1024 { 1025 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesMs[i], STAMTYPE_COUNTER, 1026 STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 1027 "Milliseconds resolution runtime statistics", 1028 "/PDM/AsyncCompletion/File/%s/TaskRun3Ms-%u-%u", 1029 RTPathFilename(pEndpoint->pszUri), i*100, i*100+100-1); 1030 if (RT_FAILURE(rc)) 1031 break; 1032 } 1033 } 1034 1035 if (RT_SUCCESS(rc)) 1036 { 1037 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++) 1038 { 1039 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesSec[i], STAMTYPE_COUNTER, 1040 STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 1041 "Second resolution runtime statistics", 1042 "/PDM/AsyncCompletion/File/%s/TaskRun4Sec-%u-%u", 1043 RTPathFilename(pEndpoint->pszUri), i*10, i*10+10-1); 1044 if (RT_FAILURE(rc)) 1045 break; 1046 } 1047 } 1048 1049 if (RT_SUCCESS(rc)) 1050 { 1051 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunOver100Sec, STAMTYPE_COUNTER, 1052 STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 1053 "Tasks which ran more than 100sec", 1054 "/PDM/AsyncCompletion/File/%s/TaskRunSecGreater100Sec", 1055 RTPathFilename(pEndpoint->pszUri)); 1056 } 1057 1058 if (RT_SUCCESS(rc)) 1059 { 1060 rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsPerSec, STAMTYPE_COUNTER, 1061 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1062 "Processed I/O operations per second", 1063 "/PDM/AsyncCompletion/File/%s/IoOpsPerSec", 1064 RTPathFilename(pEndpoint->pszUri)); 1065 } 1066 1067 if (RT_SUCCESS(rc)) 1068 { 1069 rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsStarted, STAMTYPE_COUNTER, 1070 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1071 "Started I/O operations for this endpoint", 1072 "/PDM/AsyncCompletion/File/%s/IoOpsStarted", 1073 RTPathFilename(pEndpoint->pszUri)); 1074 } 1075 1076 if (RT_SUCCESS(rc)) 1077 { 1078 rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsCompleted, STAMTYPE_COUNTER, 1079 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1080 "Completed I/O operations for this endpoint", 1081 "/PDM/AsyncCompletion/File/%s/IoOpsCompleted", 1082 RTPathFilename(pEndpoint->pszUri)); 1083 } 1084 1085 if (RT_SUCCESS(rc)) 1086 { 1087 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSizeSmaller512, STAMTYPE_COUNTER, 1088 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1089 "Number of requests with a size smaller than 512 bytes", 1090 "/PDM/AsyncCompletion/File/%s/ReqSizeSmaller512", 1091 RTPathFilename(pEndpoint->pszUri)); 1092 } 1093 1094 if (RT_SUCCESS(rc)) 1095 { 1096 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize512To1K, STAMTYPE_COUNTER, 1097 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1098 "Number of requests with a size between 512 bytes and 1KB", 1099 "/PDM/AsyncCompletion/File/%s/ReqSize512To1K", 1100 RTPathFilename(pEndpoint->pszUri)); 1101 } 1102 1103 if (RT_SUCCESS(rc)) 1104 { 1105 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize1KTo2K, STAMTYPE_COUNTER, 1106 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1107 "Number of requests with a size between 1KB and 2KB", 1108 "/PDM/AsyncCompletion/File/%s/ReqSize1KTo2K", 1109 RTPathFilename(pEndpoint->pszUri)); 1110 } 1111 1112 if (RT_SUCCESS(rc)) 1113 { 1114 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize2KTo4K, STAMTYPE_COUNTER, 1115 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1116 "Number of requests with a size between 2KB and 4KB", 1117 "/PDM/AsyncCompletion/File/%s/ReqSize2KTo4K", 1118 RTPathFilename(pEndpoint->pszUri)); 1119 } 1120 1121 if (RT_SUCCESS(rc)) 1122 { 1123 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize4KTo8K, STAMTYPE_COUNTER, 1124 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1125 "Number of requests with a size between 4KB and 8KB", 1126 "/PDM/AsyncCompletion/File/%s/ReqSize4KTo8K", 1127 RTPathFilename(pEndpoint->pszUri)); 1128 } 1129 1130 if (RT_SUCCESS(rc)) 1131 { 1132 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize8KTo16K, STAMTYPE_COUNTER, 1133 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1134 "Number of requests with a size between 8KB and 16KB", 1135 "/PDM/AsyncCompletion/File/%s/ReqSize8KTo16K", 1136 RTPathFilename(pEndpoint->pszUri)); 1137 } 1138 1139 if (RT_SUCCESS(rc)) 1140 { 1141 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize16KTo32K, STAMTYPE_COUNTER, 1142 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1143 "Number of requests with a size between 16KB and 32KB", 1144 "/PDM/AsyncCompletion/File/%s/ReqSize16KTo32K", 1145 RTPathFilename(pEndpoint->pszUri)); 1146 } 1147 1148 if (RT_SUCCESS(rc)) 1149 { 1150 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize32KTo64K, STAMTYPE_COUNTER, 1151 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1152 "Number of requests with a size between 32KB and 64KB", 1153 "/PDM/AsyncCompletion/File/%s/ReqSize32KTo64K", 1154 RTPathFilename(pEndpoint->pszUri)); 1155 } 1156 1157 if (RT_SUCCESS(rc)) 1158 { 1159 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize64KTo128K, STAMTYPE_COUNTER, 1160 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1161 "Number of requests with a size between 64KB and 128KB", 1162 "/PDM/AsyncCompletion/File/%s/ReqSize64KTo128K", 1163 RTPathFilename(pEndpoint->pszUri)); 1164 } 1165 1166 if (RT_SUCCESS(rc)) 1167 { 1168 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize128KTo256K, STAMTYPE_COUNTER, 1169 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1170 "Number of requests with a size between 128KB and 256KB", 1171 "/PDM/AsyncCompletion/File/%s/ReqSize128KTo256K", 1172 RTPathFilename(pEndpoint->pszUri)); 1173 } 1174 1175 if (RT_SUCCESS(rc)) 1176 { 1177 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize256KTo512K, STAMTYPE_COUNTER, 1178 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1179 "Number of requests with a size between 256KB and 512KB", 1180 "/PDM/AsyncCompletion/File/%s/ReqSize256KTo512K", 1181 RTPathFilename(pEndpoint->pszUri)); 1182 } 1183 1184 if (RT_SUCCESS(rc)) 1185 { 1186 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSizeOver512K, STAMTYPE_COUNTER, 1187 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1188 "Number of requests with a size over 512KB", 1189 "/PDM/AsyncCompletion/File/%s/ReqSizeOver512K", 1190 RTPathFilename(pEndpoint->pszUri)); 1191 } 1192 1193 if (RT_SUCCESS(rc)) 1194 { 1195 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqsUnaligned512, STAMTYPE_COUNTER, 1196 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1197 "Number of requests which size is not aligned to 512 bytes", 1198 "/PDM/AsyncCompletion/File/%s/ReqsUnaligned512", 1199 RTPathFilename(pEndpoint->pszUri)); 1200 } 1201 1202 if (RT_SUCCESS(rc)) 1203 { 1204 rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqsUnaligned4K, STAMTYPE_COUNTER, 1205 STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 1206 "Number of requests which size is not aligned to 4KB", 1207 "/PDM/AsyncCompletion/File/%s/ReqsUnaligned4K", 1208 RTPathFilename(pEndpoint->pszUri)); 1209 } 1210 1211 return rc; 1212 } 1213 1214 /** 1215 * Deregisters advanced statistics for one endpoint. 1216 * 1217 * @returns nothing. 1218 * @param pEndpoint The endpoint to deregister the advanced statistics for. 1219 */ 1220 static void pdmR3AsyncCompletionStatisticsDeregister(PPDMASYNCCOMPLETIONENDPOINT pEndpoint) 1221 { 1222 PVM pVM = pEndpoint->pEpClass->pVM; 1223 1224 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesNs); i++) 1225 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesNs[i]); 1226 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesUs); i++) 1227 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesUs[i]); 1228 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++) 1229 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesMs[i]); 1230 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++) 1231 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesSec[i]); 1232 1233 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunOver100Sec); 1234 STAMR3Deregister(pVM, &pEndpoint->StatIoOpsPerSec); 1235 STAMR3Deregister(pVM, &pEndpoint->StatIoOpsStarted); 1236 STAMR3Deregister(pVM, &pEndpoint->StatIoOpsCompleted); 1237 1238 STAMR3Deregister(pVM, &pEndpoint->StatReqSizeSmaller512); 1239 STAMR3Deregister(pVM, &pEndpoint->StatReqSize512To1K); 1240 STAMR3Deregister(pVM, &pEndpoint->StatReqSize1KTo2K); 1241 STAMR3Deregister(pVM, &pEndpoint->StatReqSize2KTo4K); 1242 STAMR3Deregister(pVM, &pEndpoint->StatReqSize4KTo8K); 1243 STAMR3Deregister(pVM, &pEndpoint->StatReqSize8KTo16K); 1244 STAMR3Deregister(pVM, &pEndpoint->StatReqSize16KTo32K); 1245 STAMR3Deregister(pVM, &pEndpoint->StatReqSize32KTo64K); 1246 STAMR3Deregister(pVM, &pEndpoint->StatReqSize64KTo128K); 1247 STAMR3Deregister(pVM, &pEndpoint->StatReqSize128KTo256K); 1248 STAMR3Deregister(pVM, &pEndpoint->StatReqSize256KTo512K); 1249 STAMR3Deregister(pVM, &pEndpoint->StatReqSizeOver512K); 1250 STAMR3Deregister(pVM, &pEndpoint->StatReqsUnaligned512); 1251 STAMR3Deregister(pVM, &pEndpoint->StatReqsUnaligned4K); 1252 } 1253 1254 /** 1255 * Initialize the async completion manager. 1256 * 1257 * @returns VBox status code 1258 * @param pVM Pointer to the VM. 1259 */ 1260 int pdmR3AsyncCompletionInit(PVM pVM) 1261 { 1262 LogFlowFunc((": pVM=%p\n", pVM)); 1263 1264 VM_ASSERT_EMT(pVM); 1265 1266 PCFGMNODE pCfgRoot = CFGMR3GetRoot(pVM); 1267 PCFGMNODE pCfgAsyncCompletion = CFGMR3GetChild(CFGMR3GetChild(pCfgRoot, "PDM"), "AsyncCompletion"); 1268 1269 int rc = pdmR3AsyncCompletionEpClassInit(pVM, &g_PDMAsyncCompletionEndpointClassFile, pCfgAsyncCompletion); 1270 LogFlowFunc((": pVM=%p rc=%Rrc\n", pVM, rc)); 1271 return rc; 1272 } 1273 1274 /** 1275 * Terminates the async completion manager. 1276 * 1277 * @returns VBox status code 1278 * @param pVM Pointer to the VM. 1279 */ 1280 int pdmR3AsyncCompletionTerm(PVM pVM) 1281 { 1282 LogFlowFunc((": pVM=%p\n", pVM)); 1283 PUVM pUVM = pVM->pUVM; 1284 1285 for (size_t i = 0; i < RT_ELEMENTS(pUVM->pdm.s.apAsyncCompletionEndpointClass); i++) 1286 if (pUVM->pdm.s.apAsyncCompletionEndpointClass[i]) 1287 pdmR3AsyncCompletionEpClassTerminate(pUVM->pdm.s.apAsyncCompletionEndpointClass[i]); 1288 1289 return VINF_SUCCESS; 1290 } 1291 1292 /** 1293 * Resume worker for the async completion manager. 1294 * 1295 * @returns nothing. 1296 * @param pVM Pointer to the VM. 1297 */ 1298 void pdmR3AsyncCompletionResume(PVM pVM) 1299 { 1300 LogFlowFunc((": pVM=%p\n", pVM)); 1301 PUVM pUVM = pVM->pUVM; 1302 1303 /* Log the bandwidth groups and all assigned endpoints. */ 1304 for (size_t i = 0; i < RT_ELEMENTS(pUVM->pdm.s.apAsyncCompletionEndpointClass); i++) 1305 if (pUVM->pdm.s.apAsyncCompletionEndpointClass[i]) 1306 { 1307 PPDMASYNCCOMPLETIONEPCLASS pEpClass = pUVM->pdm.s.apAsyncCompletionEndpointClass[i]; 1308 PPDMACBWMGR pBwMgr = pEpClass->pBwMgrsHead; 1309 PPDMASYNCCOMPLETIONENDPOINT pEp; 1310 1311 if (pBwMgr) 1312 LogRel(("AIOMgr: Bandwidth groups for class '%s'\n", i == PDMASYNCCOMPLETIONEPCLASSTYPE_FILE 1313 ? "File" : "<Unknown>")); 1314 1315 while (pBwMgr) 1316 { 1317 LogRel(("AIOMgr: Id: %s\n", pBwMgr->pszId)); 1318 LogRel(("AIOMgr: Max: %u B/s\n", pBwMgr->cbTransferPerSecMax)); 1319 LogRel(("AIOMgr: Start: %u B/s\n", pBwMgr->cbTransferPerSecStart)); 1320 LogRel(("AIOMgr: Step: %u B/s\n", pBwMgr->cbTransferPerSecStep)); 1321 LogRel(("AIOMgr: Endpoints:\n")); 1322 1323 pEp = pEpClass->pEndpointsHead; 1324 while (pEp) 1325 { 1326 if (pEp->pBwMgr == pBwMgr) 1327 LogRel(("AIOMgr: %s\n", pEp->pszUri)); 1328 1329 pEp = pEp->pNext; 1330 } 1331 1332 pBwMgr = pBwMgr->pNext; 1333 } 1334 1335 /* Print all endpoints without assigned bandwidth groups. */ 1336 pEp = pEpClass->pEndpointsHead; 1337 if (pEp) 1338 LogRel(("AIOMgr: Endpoints without assigned bandwidth groups:\n")); 1339 1340 while (pEp) 1341 { 1342 if (!pEp->pBwMgr) 1343 LogRel(("AIOMgr: %s\n", pEp->pszUri)); 1344 1345 pEp = pEp->pNext; 1346 } 1347 } 1348 } 1349 1350 /** 1351 * Tries to get a free task from the endpoint or class cache 1352 * allocating the task if it fails. 1353 * 1354 * @returns Pointer to a new and initialized task or NULL 1355 * @param pEndpoint The endpoint the task is for. 1356 * @param pvUser Opaque user data for the task. 1357 */ 1358 static PPDMASYNCCOMPLETIONTASK pdmR3AsyncCompletionGetTask(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, void *pvUser) 1359 { 1360 PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pEndpoint->pEpClass; 1361 PPDMASYNCCOMPLETIONTASK pTask = (PPDMASYNCCOMPLETIONTASK)RTMemCacheAlloc(pEndpointClass->hMemCacheTasks); 1362 if (RT_LIKELY(pTask)) 1363 { 1364 /* Initialize common parts. */ 1365 pTask->pvUser = pvUser; 1366 pTask->pEndpoint = pEndpoint; 1367 /* Clear list pointers for safety. */ 1368 pTask->pPrev = NULL; 1369 pTask->pNext = NULL; 1370 pTask->tsNsStart = RTTimeNanoTS(); 1371 STAM_COUNTER_INC(&pEndpoint->StatIoOpsStarted); 1372 } 1373 1374 return pTask; 1375 } 1376 1377 /** 1378 * Puts a task in one of the caches. 1379 * 1380 * @returns nothing. 1381 * @param pEndpoint The endpoint the task belongs to. 1382 * @param pTask The task to cache. 1383 */ 1384 static void pdmR3AsyncCompletionPutTask(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, PPDMASYNCCOMPLETIONTASK pTask) 1385 { 1386 PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pEndpoint->pEpClass; 1387 uint64_t cNsRun = RTTimeNanoTS() - pTask->tsNsStart; 1388 1389 if (RT_UNLIKELY(cNsRun >= RT_NS_10SEC)) 1390 LogRel(("AsyncCompletion: Task %#p completed after %llu seconds\n", pTask, cNsRun / RT_NS_1SEC)); 1391 1392 if (pEndpointClass->fGatherAdvancedStatistics) 1393 pdmR3AsyncCompletionStatisticsRecordCompletionTime(pEndpoint, cNsRun); 1068 1394 1069 1395 RTMemCacheFree(pEndpointClass->hMemCacheTasks, pTask); … … 1126 1452 if (RT_SUCCESS(rc)) 1127 1453 { 1128 1129 1454 /* Initialize common parts. */ 1130 1455 pEndpoint->pNext = NULL; … … 1143 1468 if (RT_SUCCESS(rc)) 1144 1469 { 1145 /* Link it into the list of endpoints. */ 1146 rc = RTCritSectEnter(&pEndpointClass->CritSect); 1147 AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc)); 1148 1149 pEndpoint->pNext = pEndpointClass->pEndpointsHead; 1150 if (pEndpointClass->pEndpointsHead) 1151 pEndpointClass->pEndpointsHead->pPrev = pEndpoint; 1152 1153 pEndpointClass->pEndpointsHead = pEndpoint; 1154 pEndpointClass->cEndpoints++; 1155 1156 rc = RTCritSectLeave(&pEndpointClass->CritSect); 1157 AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc)); 1158 1159 /* Reference the template. */ 1160 ASMAtomicIncU32(&pTemplate->cUsed); 1161 1162 #ifdef VBOX_WITH_STATISTICS 1163 /* Init the statistics part */ 1164 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesNs); i++) 1165 { 1166 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesNs[i], STAMTYPE_COUNTER, 1167 STAMVISIBILITY_USED, 1168 STAMUNIT_OCCURENCES, 1169 "Nanosecond resolution runtime statistics", 1170 "/PDM/AsyncCompletion/File/%s/TaskRun1Ns-%u-%u", 1171 RTPathFilename(pEndpoint->pszUri), 1172 i*100, i*100+100-1); 1173 if (RT_FAILURE(rc)) 1174 break; 1175 } 1470 if (pEndpointClass->fGatherAdvancedStatistics) 1471 rc = pdmR3AsyncCompletionStatisticsRegister(pEndpoint); 1176 1472 1177 1473 if (RT_SUCCESS(rc)) 1178 1474 { 1179 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesUs); i++) 1180 { 1181 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesUs[i], STAMTYPE_COUNTER, 1182 STAMVISIBILITY_USED, 1183 STAMUNIT_OCCURENCES, 1184 "Microsecond resolution runtime statistics", 1185 "/PDM/AsyncCompletion/File/%s/TaskRun2MicroSec-%u-%u", 1186 RTPathFilename(pEndpoint->pszUri), 1187 i*100, i*100+100-1); 1188 if (RT_FAILURE(rc)) 1189 break; 1190 } 1475 /* Link it into the list of endpoints. */ 1476 rc = RTCritSectEnter(&pEndpointClass->CritSect); 1477 AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc)); 1478 1479 pEndpoint->pNext = pEndpointClass->pEndpointsHead; 1480 if (pEndpointClass->pEndpointsHead) 1481 pEndpointClass->pEndpointsHead->pPrev = pEndpoint; 1482 1483 pEndpointClass->pEndpointsHead = pEndpoint; 1484 pEndpointClass->cEndpoints++; 1485 1486 rc = RTCritSectLeave(&pEndpointClass->CritSect); 1487 AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc)); 1488 1489 /* Reference the template. */ 1490 ASMAtomicIncU32(&pTemplate->cUsed); 1491 1492 *ppEndpoint = pEndpoint; 1493 LogFlowFunc((": Created endpoint for %s\n", pszFilename)); 1494 return VINF_SUCCESS; 1191 1495 } 1192 1496 1193 if (RT_SUCCESS(rc)) 1194 { 1195 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++) 1196 { 1197 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesMs[i], STAMTYPE_COUNTER, 1198 STAMVISIBILITY_USED, 1199 STAMUNIT_OCCURENCES, 1200 "Milliseconds resolution runtime statistics", 1201 "/PDM/AsyncCompletion/File/%s/TaskRun3Ms-%u-%u", 1202 RTPathFilename(pEndpoint->pszUri), 1203 i*100, i*100+100-1); 1204 if (RT_FAILURE(rc)) 1205 break; 1206 } 1207 } 1208 1209 if (RT_SUCCESS(rc)) 1210 { 1211 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++) 1212 { 1213 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesSec[i], STAMTYPE_COUNTER, 1214 STAMVISIBILITY_USED, 1215 STAMUNIT_OCCURENCES, 1216 "Second resolution runtime statistics", 1217 "/PDM/AsyncCompletion/File/%s/TaskRun4Sec-%u-%u", 1218 RTPathFilename(pEndpoint->pszUri), 1219 i*10, i*10+10-1); 1220 if (RT_FAILURE(rc)) 1221 break; 1222 } 1223 } 1224 1225 if (RT_SUCCESS(rc)) 1226 { 1227 rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunOver100Sec, STAMTYPE_COUNTER, 1228 STAMVISIBILITY_USED, 1229 STAMUNIT_OCCURENCES, 1230 "Tasks which ran more than 100sec", 1231 "/PDM/AsyncCompletion/File/%s/TaskRunSecGreater100Sec", 1232 RTPathFilename(pEndpoint->pszUri)); 1233 } 1234 1235 if (RT_SUCCESS(rc)) 1236 { 1237 rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsPerSec, STAMTYPE_COUNTER, 1238 STAMVISIBILITY_ALWAYS, 1239 STAMUNIT_OCCURENCES, 1240 "Processed I/O operations per second", 1241 "/PDM/AsyncCompletion/File/%s/IoOpsPerSec", 1242 RTPathFilename(pEndpoint->pszUri)); 1243 } 1244 1245 if (RT_SUCCESS(rc)) 1246 { 1247 rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsStarted, STAMTYPE_COUNTER, 1248 STAMVISIBILITY_ALWAYS, 1249 STAMUNIT_OCCURENCES, 1250 "Started I/O operations for this endpoint", 1251 "/PDM/AsyncCompletion/File/%s/IoOpsStarted", 1252 RTPathFilename(pEndpoint->pszUri)); 1253 } 1254 1255 if (RT_SUCCESS(rc)) 1256 { 1257 rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsCompleted, STAMTYPE_COUNTER, 1258 STAMVISIBILITY_ALWAYS, 1259 STAMUNIT_OCCURENCES, 1260 "Completed I/O operations for this endpoint", 1261 "/PDM/AsyncCompletion/File/%s/IoOpsCompleted", 1262 RTPathFilename(pEndpoint->pszUri)); 1263 } 1264 /** @todo why bother maintaing rc when it's just ignored / 1265 logged and not returned? */ 1266 1267 pEndpoint->tsIntervalStartMs = RTTimeMilliTS(); 1268 #endif 1269 1270 *ppEndpoint = pEndpoint; 1271 1272 LogFlowFunc((": Created endpoint for %s: rc=%Rrc\n", pszFilename, rc)); 1273 return VINF_SUCCESS; 1497 if (pEndpointClass->fGatherAdvancedStatistics) 1498 pdmR3AsyncCompletionStatisticsDeregister(pEndpoint); 1274 1499 } 1275 1500 RTStrFree(pEndpoint->pszUri); … … 1295 1520 { 1296 1521 PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pEndpoint->pEpClass; 1522 PVM pVM = pEndpointClass->pVM; 1523 1297 1524 pEndpointClass->pEndpointOps->pfnEpClose(pEndpoint); 1298 1525 … … 1319 1546 AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc)); 1320 1547 1321 #ifdef VBOX_WITH_STATISTICS 1322 /* Deregister the statistics part */ 1323 PVM pVM = pEndpointClass->pVM; 1324 1325 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesNs); i++) 1326 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesNs[i]); 1327 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesUs); i++) 1328 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesUs[i]); 1329 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++) 1330 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesMs[i]); 1331 for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++) 1332 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesSec[i]); 1333 1334 STAMR3Deregister(pVM, &pEndpoint->StatTaskRunOver100Sec); 1335 STAMR3Deregister(pVM, &pEndpoint->StatIoOpsPerSec); 1336 STAMR3Deregister(pVM, &pEndpoint->StatIoOpsStarted); 1337 STAMR3Deregister(pVM, &pEndpoint->StatIoOpsCompleted); 1338 #endif 1548 if (pEndpointClass->fGatherAdvancedStatistics) 1549 pdmR3AsyncCompletionStatisticsDeregister(pEndpoint); 1339 1550 1340 1551 RTStrFree(pEndpoint->pszUri); … … 1364 1575 paSegments, cSegments, cbRead); 1365 1576 if (RT_SUCCESS(rc)) 1577 { 1578 if (pEndpoint->pEpClass->fGatherAdvancedStatistics) 1579 pdmR3AsyncCompletionStatisticsRecordSize(pEndpoint, cbRead); 1580 1366 1581 *ppTask = pTask; 1582 } 1367 1583 else 1368 1584 pdmR3AsyncCompletionPutTask(pEndpoint, pTask); … … 1393 1609 if (RT_SUCCESS(rc)) 1394 1610 { 1611 if (pEndpoint->pEpClass->fGatherAdvancedStatistics) 1612 pdmR3AsyncCompletionStatisticsRecordSize(pEndpoint, cbWrite); 1613 1395 1614 *ppTask = pTask; 1396 1615 } -
trunk/src/VBox/VMM/include/PDMAsyncCompletionInternal.h
r41777 r43529 184 184 /** Task cache. */ 185 185 RTMEMCACHE hMemCacheTasks; 186 /** Flag whether to gather advanced statistics about requests. */ 187 bool fGatherAdvancedStatistics; 186 188 } PDMASYNCCOMPLETIONEPCLASS; 187 189 /** Pointer to the PDM async completion endpoint class data. */ … … 208 210 /** Pointer to the assigned bandwidth manager. */ 209 211 volatile PPDMACBWMGR pBwMgr; 210 #ifdef VBOX_WITH_STATISTICS 212 /** Aligns following statistic counters on a 8 byte boundary. */ 211 213 uint32_t u32Alignment; 214 /** @name Request size statistics. 215 * @{ */ 216 STAMCOUNTER StatReqSizeSmaller512; 217 STAMCOUNTER StatReqSize512To1K; 218 STAMCOUNTER StatReqSize1KTo2K; 219 STAMCOUNTER StatReqSize2KTo4K; 220 STAMCOUNTER StatReqSize4KTo8K; 221 STAMCOUNTER StatReqSize8KTo16K; 222 STAMCOUNTER StatReqSize16KTo32K; 223 STAMCOUNTER StatReqSize32KTo64K; 224 STAMCOUNTER StatReqSize64KTo128K; 225 STAMCOUNTER StatReqSize128KTo256K; 226 STAMCOUNTER StatReqSize256KTo512K; 227 STAMCOUNTER StatReqSizeOver512K; 228 STAMCOUNTER StatReqsUnaligned512; 229 STAMCOUNTER StatReqsUnaligned4K; 230 /** @} */ 231 /** @name Request completion time statistics. 232 * @{ */ 212 233 STAMCOUNTER StatTaskRunTimesNs[10]; 213 234 STAMCOUNTER StatTaskRunTimesUs[10]; … … 220 241 uint64_t tsIntervalStartMs; 221 242 uint64_t cIoOpsCompleted; 222 #endif 243 /** @} */ 223 244 } PDMASYNCCOMPLETIONENDPOINT; 224 #ifdef VBOX_WITH_STATISTICS 245 AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINT, StatReqSizeSmaller512, sizeof(uint64_t)); 225 246 AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINT, StatTaskRunTimesNs, sizeof(uint64_t)); 226 #endif227 247 228 248 /**
Note:
See TracChangeset
for help on using the changeset viewer.