VirtualBox

Changeset 71293 in vbox


Ignore:
Timestamp:
Mar 9, 2018 9:11:20 PM (7 years ago)
Author:
vboxsync
Message:

NEM: Some stats; doc updates. bugref:9044

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/vm.h

    r71129 r71293  
    178178        struct NEMCPU       s;
    179179#endif
    180         uint8_t             padding[256];       /* multiple of 64 */
     180        uint8_t             padding[512];       /* multiple of 64 */
    181181    } nem;
    182182
     
    267267
    268268    /** Align the following members on page boundary. */
    269     uint8_t                 abAlignment2[1848];
     269    uint8_t                 abAlignment2[1592];
    270270
    271271    /** PGM part. */
  • trunk/include/VBox/vmm/vm.mac

    r71075 r71293  
    6464    .hm                     resb 5824
    6565    .em                     resb 1408
    66     .nem                    resb 256
     66    .nem                    resb 512
    6767    .trpm                   resb 128
    6868    .tm                     resb 384
  • trunk/include/iprt/nt/hyperv.h

    r71184 r71293  
    198198    HvCallUncommitGpaPages,             /**< Happens when VidDestroyGpaRangeCheckSecure/WHvUnmapGpaRange is called. */
    199199    /* 0xc0..0xcb are unknown */
     200    HvCallVpRunloopRelated = 0xc2,      /**< Fast */
    200201    HvCallQueryVtlProtectionMaskRange = 0xcc,
    201202    HvCallModifyVtlProtectionMaskRange,
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r71224 r71293  
    839839                {
    840840                    Log8(("nemHCWinCancelRunVirtualProcessor: Switched %u to canceled state\n", pVCpu->idCpu));
     841                    STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatCancelChangedState);
    841842                    return VINF_SUCCESS;
    842843                }
     
    854855                    Assert(rcNt == STATUS_SUCCESS);
    855856                    if (NT_SUCCESS(rcNt))
     857                    {
     858                        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatCancelAlertedThread);
    856859                        return VINF_SUCCESS;
     860                    }
    857861                    AssertLogRelMsgFailedReturn(("NtAlertThread failed: %#x\n", rcNt), RTErrConvertFromNtStatus(rcNt));
    858862                }
     
    14541458            case HvMessageTypeUnmappedGpa:
    14551459                Assert(pMsg->Header.PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment));
     1460                STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitMemUnmapped);
    14561461                return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx, pGVCpu);
    14571462
    14581463            case HvMessageTypeGpaIntercept:
    14591464                Assert(pMsg->Header.PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment));
     1465                STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitMemIntercept);
    14601466                return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx, pGVCpu);
    14611467
    14621468            case HvMessageTypeX64IoPortIntercept:
    14631469                Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64IoPortIntercept));
     1470                STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitPortIo);
    14641471                return nemHCWinHandleMessageIoPort(pVM, pVCpu, &pMsg->X64IoPortIntercept, pCtx, pGVCpu);
    14651472
    14661473            case HvMessageTypeX64Halt:
     1474                STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitHalt);
    14671475                return VINF_EM_HALT;
    14681476
     
    15361544    {
    15371545        Log8(("nemHCWinStopCpu: Stopping CPU succeeded (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
     1546        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatStopCpuSuccess);
    15381547        return rcStrict;
    15391548    }
     
    15431552    {
    15441553        Log8(("nemHCWinStopCpu: Stopping CPU succeeded (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
     1554        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatStopCpuSuccess);
    15451555        return rcStrict;
    15461556    }
     
    15601570# endif
    15611571    Log8(("nemHCWinStopCpu: Stopping CPU pending...\n"));
     1572    STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatStopCpuPending);
    15621573
    15631574    /*
     
    16521663
    16531664    /*
     1665     * Try switch to NEM runloop state.
     1666     */
     1667    if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED))
     1668    { /* likely */ }
     1669    else
     1670    {
     1671        VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);
     1672        LogFlow(("NEM/%u: returning immediately because canceled\n", pVCpu->idCpu));
     1673        return VINF_SUCCESS;
     1674    }
     1675
     1676    /*
    16541677     * The run loop.
    16551678     *
     
    17041727            }
    17051728
    1706             if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED))
     1729            if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED_EXEC_NEM))
    17071730            {
    17081731# ifdef IN_RING0
     
    17141737                                                        sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
    17151738                                                        NULL, 0);
    1716                 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
     1739                VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
    17171740                if (rcNt == STATUS_SUCCESS)
    17181741# else
    17191742                BOOL fRet = VidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    17201743                                                           pVCpu->nem.s.fHandleAndGetFlags, cMillies);
    1721                 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
     1744                VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
    17221745                if (fRet)
    17231746# endif
     
    17331756                    {
    17341757                        LogFlow(("NEM/%u: breaking: nemHCWinHandleMessage -> %Rrc\n", pVCpu->idCpu, VBOXSTRICTRC_VAL(rcStrict) ));
     1758                        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnStatus);
    17351759                        break;
    17361760                    }
     
    17501774                                          , ("VidMessageSlotHandleAndGetNext failed for CPU #%u: %#x (%u)\n", pVCpu->idCpu, rcNt, rcNt),
    17511775                                          VERR_INTERNAL_ERROR_3);
    1752                     pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE; /* exits are likely */
     1776                    pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE;
     1777                    STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatGetMsgTimeout);
    17531778                }
    17541779
     
    17641789                LogFlow(("NEM/%u: breaking: pending FF (%#x / %#x)\n",
    17651790                         pVCpu->idCpu, pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions));
     1791                STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnFFPost);
    17661792            }
    17671793            else
     1794            {
    17681795                LogFlow(("NEM/%u: breaking: canceled %d (pre exec)\n", pVCpu->idCpu, VMCPU_GET_STATE(pVCpu) ));
     1796                STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnCancel);
     1797            }
    17691798        }
    17701799        else
     1800        {
    17711801            LogFlow(("NEM/%u: breaking: pending FF (pre exec)\n", pVCpu->idCpu));
     1802            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnFFPre);
     1803        }
    17721804        break;
    17731805    } /* the run loop */
     
    17841816    }
    17851817
    1786     VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);
     1818    if (!VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM))
     1819        VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED);
    17871820
    17881821    if (pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | (CPUMCTX_EXTRN_NEM_WIN_MASK & ~CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT)))
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r71020 r71293  
    430430        EM_REG_PROFILE(&pVCpu->em.s.StatIEMThenREM,         "/PROF/CPU%d/EM/IEMThenRem",        "Profiling IEM-then-REM instruction execution (by IEM).");
    431431        EM_REG_PROFILE(&pVCpu->em.s.StatNEMEntry,           "/PROF/CPU%d/EM/NEMEnter",          "Profiling NEM entry overhead.");
     432#endif /* VBOX_WITH_STATISTICS */
    432433        EM_REG_PROFILE(&pVCpu->em.s.StatNEMExec,            "/PROF/CPU%d/EM/NEMExec",           "Profiling NEM execution.");
    433434        EM_REG_COUNTER(&pVCpu->em.s.StatNEMExecuteCalled,   "/PROF/CPU%d/EM/NEMExecuteCalled",  "Number of times enmR3NEMExecute is called.");
     435#ifdef VBOX_WITH_STATISTICS
    434436        EM_REG_PROFILE(&pVCpu->em.s.StatREMEmu,             "/PROF/CPU%d/EM/REMEmuSingle",      "Profiling single instruction REM execution.");
    435437        EM_REG_PROFILE(&pVCpu->em.s.StatREMExec,            "/PROF/CPU%d/EM/REMExec",           "Profiling REM execution.");
     
    438440        EM_REG_PROFILE(&pVCpu->em.s.StatRAWExec,            "/PROF/CPU%d/EM/RAWExec",           "Profiling Raw Mode execution.");
    439441        EM_REG_PROFILE(&pVCpu->em.s.StatRAWTail,            "/PROF/CPU%d/EM/RAWTail",           "Profiling Raw Mode tail overhead.");
    440 
    441442#endif /* VBOX_WITH_STATISTICS */
    442443
  • trunk/src/VBox/VMM/VMMR3/EMR3Nem.cpp

    r71031 r71293  
    361361    *pfFFDone = false;
    362362
    363     STAM_COUNTER_INC(&pVCpu->em.s.StatNEMExecuteCalled);
     363    STAM_REL_COUNTER_INC(&pVCpu->em.s.StatNEMExecuteCalled);
    364364
    365365    /*
     
    421421         * Execute the code.
    422422         */
    423         STAM_PROFILE_ADV_STOP(&pVCpu->em.s.StatNEMEntry, a);
    424 
    425423        if (RT_LIKELY(emR3IsExecutionAllowed(pVM, pVCpu)))
    426424        {
    427             STAM_PROFILE_START(&pVCpu->em.s.StatNEMExec, x);
     425            STAM_PROFILE_ADV_STOP(&pVCpu->em.s.StatNEMEntry, a);
     426            STAM_REL_PROFILE_START(&pVCpu->em.s.StatNEMExec, x);
    428427            rcStrict = NEMR3RunGC(pVM, pVCpu);
    429             STAM_PROFILE_STOP(&pVCpu->em.s.StatNEMExec, x);
     428            STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatNEMExec, x);
    430429        }
    431430        else
    432431        {
    433432            /* Give up this time slice; virtual time continues */
     433            STAM_PROFILE_ADV_STOP(&pVCpu->em.s.StatNEMEntry, a);
    434434            STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatCapped, u);
    435435            RTThreadSleep(5);
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r71289 r71293  
    11001100                        VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API);
    11011101                        Log(("NEM: Marked active!\n"));
     1102
     1103                        /* Register release statistics */
     1104                        for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
     1105                        {
     1106                            PNEMCPU pNemCpu = &pVM->aCpus[iCpu].nem.s;
     1107                            STAMR3RegisterF(pVM, &pNemCpu->StatExitPortIo,          STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of port I/O exits",               "/NEM/CPU%u/ExitPortIo", iCpu);
     1108                            STAMR3RegisterF(pVM, &pNemCpu->StatExitMemUnmapped,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of unmapped memory exits",        "/NEM/CPU%u/ExitMemUnmapped", iCpu);
     1109                            STAMR3RegisterF(pVM, &pNemCpu->StatExitMemIntercept,    STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of intercepted memory exits",     "/NEM/CPU%u/ExitMemIntercept", iCpu);
     1110                            STAMR3RegisterF(pVM, &pNemCpu->StatExitHalt,            STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of HLT exits",                    "/NEM/CPU%u/ExitHalt", iCpu);
     1111                            STAMR3RegisterF(pVM, &pNemCpu->StatGetMsgTimeout,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of get message timeouts/alerts",  "/NEM/CPU%u/GetMsgTimeout", iCpu);
     1112                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuSuccess,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of successful CPU stops",         "/NEM/CPU%u/StopCpuSuccess", iCpu);
     1113                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuPending,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of pending CPU stops",            "/NEM/CPU%u/StopCpuPending", iCpu);
     1114                            STAMR3RegisterF(pVM, &pNemCpu->StatCancelChangedState,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel changed state",         "/NEM/CPU%u/CancelChangedState", iCpu);
     1115                            STAMR3RegisterF(pVM, &pNemCpu->StatCancelAlertedThread, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel alerted EMT",           "/NEM/CPU%u/CancelAlertedEMT", iCpu);
     1116                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnFFPre,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of pre execution FF breaks",      "/NEM/CPU%u/BreakOnFFPre", iCpu);
     1117                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnFFPost,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of post execution FF breaks",     "/NEM/CPU%u/BreakOnFFPost", iCpu);
     1118                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnCancel,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel execution breaks",      "/NEM/CPU%u/BreakOnCancel", iCpu);
     1119                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnStatus,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of status code breaks",           "/NEM/CPU%u/BreakOnStatus", iCpu);
     1120                        }
    11021121                    }
    11031122                }
     
    12751294int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
    12761295{
     1296    //BOOL fRet = SetThreadPriority(GetCurrentThread(), 0);
     1297    //AssertLogRel(fRet);
     1298
    12771299    NOREF(pVM); NOREF(enmWhat);
    12781300    return VINF_SUCCESS;
     
    22352257 * The CPU creation function boils down to a VidMessageSlotMap call that sets up
    22362258 * and maps a message buffer into ring-3 for async communication with hyper-V
    2237  * and/or the VID.SYS thread actually running the CPU.  When for instance a
    2238  * VMEXIT is encountered, hyper-V sends a message that the
    2239  * WHvRunVirtualProcessor API retrieves (and later acknowledges) via
    2240  * VidMessageSlotHandleAndGetNext.  It should be noteded that
     2259 * and/or the VID.SYS thread actually running the CPU thru
     2260 * WinHvRunVpDispatchLoop().  When for instance a VMEXIT is encountered, hyper-V
     2261 * sends a message that the WHvRunVirtualProcessor API retrieves (and later
     2262 * acknowledges) via VidMessageSlotHandleAndGetNext.  It should be noteded that
    22412263 * WHvDeleteVirtualProcessor doesn't do much as there seems to be no partner
    22422264 * function VidMessagesSlotMap that reverses what it did.
     
    22572279 * VMEXIT message.  Hyper-V / VID.SYS will return information about the message
    22582280 * in the message buffer mapping, and WHvRunVirtualProcessor will convert that
    2259  * into it's own WHV_RUN_VP_EXIT_CONTEXT format.
     2281 * finto it's own WHV_RUN_VP_EXIT_CONTEXT format.
    22602282 *
    22612283 * Other threads can interrupt the execution by using WHvCancelVirtualProcessor,
     
    22882310 *   and 5% for MMIO.
    22892311 *
     2312 *   While the tests we've done are using tight tight loops only doing port I/O
     2313 *   and MMIO, the problem is clearly visible when running regular guest OSes.
     2314 *   Anything that hammers the VGA device would be suffering, for example:
     2315 *
     2316 *       - Windows 2000 boot screen animation overloads us with MMIO exits
     2317 *         and won't even boot because all the time is spent in interrupt
     2318 *         handlers and redrawin the screen.
     2319 *
     2320 *       - DSL 4.4 and its bootmenu logo is slower than molasses in january.
     2321 *
     2322 *   We have not found a workaround for this yet.
     2323 *
     2324 *   Something that might improve the issue a little is to detect blocks with
     2325 *   excessive MMIO and port I/O exits and emulate instructions to cover
     2326 *   multiple exits before letting Hyper-V have a go at the guest execution
     2327 *   again.  This will only improve the situation under some circumstances,
     2328 *   since emulating instructions without recompilation can be expensive, so
     2329 *   there will only be real gains if the exitting instructions are tightly
     2330 *   packed.
     2331 *
    22902332 *
    22912333 * - The WHvCancelVirtualProcessor API schedules a dummy usermode APC callback
     
    24172459 *
    24182460 *
    2419  * - Why does WINHVR.SYS (or VID.SYS) only query/set 32 registers at the time
    2420  *   thru the HvCallGetVpRegisters and HvCallSetVpRegisters hypercalls?
     2461 * - Why does VID.SYS only query/set 32 registers at the time thru the
     2462 *   HvCallGetVpRegisters and HvCallSetVpRegisters hypercalls?
    24212463 *
    24222464 *   We've not trouble getting/setting all the registers defined by
    2423  *   WHV_REGISTER_NAME in one hypercall (around 80)...
     2465 *   WHV_REGISTER_NAME in one hypercall (around 80).  Some kind of stack
     2466 *   buffering or similar?
    24242467 *
    24252468 *
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r71224 r71293  
    211211# endif
    212212    } uIoCtlBuf;
     213
     214    /** @name Statistics
     215     * @{ */
     216    STAMCOUNTER                 StatExitPortIo;
     217    STAMCOUNTER                 StatExitMemUnmapped;
     218    STAMCOUNTER                 StatExitMemIntercept;
     219    STAMCOUNTER                 StatExitHalt;
     220    STAMCOUNTER                 StatGetMsgTimeout;
     221    STAMCOUNTER                 StatStopCpuSuccess;
     222    STAMCOUNTER                 StatStopCpuPending;
     223    STAMCOUNTER                 StatCancelChangedState;
     224    STAMCOUNTER                 StatCancelAlertedThread;
     225    STAMCOUNTER                 StatBreakOnCancel;
     226    STAMCOUNTER                 StatBreakOnFFPre;
     227    STAMCOUNTER                 StatBreakOnFFPost;
     228    STAMCOUNTER                 StatBreakOnStatus;
     229    /** @} */
    213230#endif
    214231} NEMCPU;
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