VirtualBox

Changeset 43529 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Oct 3, 2012 3:48:45 PM (12 years ago)
Author:
vboxsync
Message:

AsyncCompletion: More statistics and include them in a release build (configurable through CFGM, default is disabled)

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp

    r41800 r43529  
    55
    66/*
    7  * Copyright (C) 2006-2011 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    848848                                  ("Endpoint class was already initialized\n"));
    849849
     850#ifdef VBOX_WITH_STATISTICS
     851                        CFGMR3QueryBoolDef(pCfgNodeClass, "AdvancedStatistics", &pEndpointClass->fGatherAdvancedStatistics, true);
     852#else
     853                        CFGMR3QueryBoolDef(pCfgNodeClass, "AdvancedStatistics", &pEndpointClass->fGatherAdvancedStatistics, false);
     854#endif
     855
    850856                        pUVM->pdm.s.apAsyncCompletionEndpointClass[pEpClassOps->enmClassType] = pEndpointClass;
    851857                        LogFlowFunc((": Initialized endpoint class \"%s\" rc=%Rrc\n", pEpClassOps->pcszName, rc));
     
    902908
    903909/**
    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.
    943911 *
    944912 * @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 */
     916static 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.
    1030951 *
    1031952 * @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 */
     956static void pdmR3AsyncCompletionStatisticsRecordCompletionTime(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t cNsRun)
     957{
    1044958    PSTAMCOUNTER pStatCounter;
    1045959    if (cNsRun < RT_NS_1US)
     
    1065979        pEndpoint->cIoOpsCompleted = 0;
    1066980    }
    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 */
     989static 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 */
     1220static 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 */
     1260int 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 */
     1280int 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 */
     1298void 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 */
     1358static 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 */
     1384static 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);
    10681394
    10691395    RTMemCacheFree(pEndpointClass->hMemCacheTasks, pTask);
     
    11261452    if (RT_SUCCESS(rc))
    11271453    {
    1128 
    11291454        /* Initialize common parts. */
    11301455        pEndpoint->pNext             = NULL;
     
    11431468            if (RT_SUCCESS(rc))
    11441469            {
    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);
    11761472
    11771473                if (RT_SUCCESS(rc))
    11781474                {
    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;
    11911495                }
    11921496
    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);
    12741499            }
    12751500            RTStrFree(pEndpoint->pszUri);
     
    12951520    {
    12961521        PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pEndpoint->pEpClass;
     1522        PVM pVM = pEndpointClass->pVM;
     1523
    12971524        pEndpointClass->pEndpointOps->pfnEpClose(pEndpoint);
    12981525
     
    13191546        AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc));
    13201547
    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);
    13391550
    13401551        RTStrFree(pEndpoint->pszUri);
     
    13641575                                                          paSegments, cSegments, cbRead);
    13651576    if (RT_SUCCESS(rc))
     1577    {
     1578        if (pEndpoint->pEpClass->fGatherAdvancedStatistics)
     1579            pdmR3AsyncCompletionStatisticsRecordSize(pEndpoint, cbRead);
     1580
    13661581        *ppTask = pTask;
     1582    }
    13671583    else
    13681584        pdmR3AsyncCompletionPutTask(pEndpoint, pTask);
     
    13931609    if (RT_SUCCESS(rc))
    13941610    {
     1611        if (pEndpoint->pEpClass->fGatherAdvancedStatistics)
     1612            pdmR3AsyncCompletionStatisticsRecordSize(pEndpoint, cbWrite);
     1613
    13951614        *ppTask = pTask;
    13961615    }
  • trunk/src/VBox/VMM/include/PDMAsyncCompletionInternal.h

    r41777 r43529  
    184184    /** Task cache. */
    185185    RTMEMCACHE                                  hMemCacheTasks;
     186    /** Flag whether to gather advanced statistics about requests. */
     187    bool                                        fGatherAdvancedStatistics;
    186188} PDMASYNCCOMPLETIONEPCLASS;
    187189/** Pointer to the PDM async completion endpoint class data. */
     
    208210    /** Pointer to the assigned bandwidth manager. */
    209211    volatile PPDMACBWMGR                        pBwMgr;
    210 #ifdef VBOX_WITH_STATISTICS
     212    /** Aligns following statistic counters on a 8 byte boundary. */
    211213    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     * @{ */
    212233    STAMCOUNTER                                 StatTaskRunTimesNs[10];
    213234    STAMCOUNTER                                 StatTaskRunTimesUs[10];
     
    220241    uint64_t                                    tsIntervalStartMs;
    221242    uint64_t                                    cIoOpsCompleted;
    222 #endif
     243    /** @} */
    223244} PDMASYNCCOMPLETIONENDPOINT;
    224 #ifdef VBOX_WITH_STATISTICS
     245AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINT, StatReqSizeSmaller512, sizeof(uint64_t));
    225246AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINT, StatTaskRunTimesNs, sizeof(uint64_t));
    226 #endif
    227247
    228248/**
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