VirtualBox

Changeset 92555 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Nov 22, 2021 6:51:43 PM (3 years ago)
Author:
vboxsync
Message:

VMM/NEM-linux: Fixed the flushing of stateful exits for larger MMIO operations. bugref:9044

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-linux.cpp

    r92543 r92555  
    535535                        STAMR3RegisterF(pVM, &pNemCpu->StatExportPendingInterrupt, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of times an interrupt was pending when exporting to KVM", "/NEM/CPU%u/ExportPendingInterrupt", idCpu);
    536536                        STAMR3RegisterF(pVM, &pNemCpu->StatFlushExitOnReturn,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of times a KVM_EXIT_IO or KVM_EXIT_MMIO was flushed before returning to EM", "/NEM/CPU%u/FlushExitOnReturn", idCpu);
     537                        STAMR3RegisterF(pVM, &pNemCpu->StatFlushExitOnReturn1Loop, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of times a KVM_EXIT_IO or KVM_EXIT_MMIO was flushed before returning to EM", "/NEM/CPU%u/FlushExitOnReturn-01-loop", idCpu);
     538                        STAMR3RegisterF(pVM, &pNemCpu->StatFlushExitOnReturn2Loops, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of times a KVM_EXIT_IO or KVM_EXIT_MMIO was flushed before returning to EM", "/NEM/CPU%u/FlushExitOnReturn-02-loops", idCpu);
     539                        STAMR3RegisterF(pVM, &pNemCpu->StatFlushExitOnReturn3Loops, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of times a KVM_EXIT_IO or KVM_EXIT_MMIO was flushed before returning to EM", "/NEM/CPU%u/FlushExitOnReturn-03-loops", idCpu);
     540                        STAMR3RegisterF(pVM, &pNemCpu->StatFlushExitOnReturn4PlusLoops, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of times a KVM_EXIT_IO or KVM_EXIT_MMIO was flushed before returning to EM", "/NEM/CPU%u/FlushExitOnReturn-04-to-7-loops", idCpu);
    537541                        STAMR3RegisterF(pVM, &pNemCpu->StatQueryCpuTick,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of TSC queries",                  "/NEM/CPU%u/QueryCpuTick", idCpu);
    538542                        STAMR3RegisterF(pVM, &pNemCpu->StatExitTotal,           STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "All exits",                  "/NEM/CPU%u/Exit", idCpu);
     
    25592563     * If the last exit was stateful, commit the state we provided before
    25602564     * returning to the EM loop so we have a consistent state and can safely
    2561      * be rescheduled and whatnot.  (There is no 'ing way to reset the kernel
    2562      * side completion callback for these stateful i/o exits.)
    2563      */
    2564     if (fStatefulExit)
    2565     {
    2566         pRun->immediate_exit = 1;
    2567         int rcLnx = ioctl(pVCpu->nem.s.fdVCpu, KVM_RUN, 0UL);
     2565     * be rescheduled and whatnot.  This may require us to make multiple runs
     2566     * for larger MMIO and I/O operations. Sigh^3.
     2567     *
     2568     * Note! There is no 'ing way to reset the kernel side completion callback
     2569     *       for these stateful i/o exits.  Very annoying interface.
     2570     */
     2571    /** @todo check how this works with string I/O and string MMIO. */
     2572    if (fStatefulExit && RT_SUCCESS(rcStrict))
     2573    {
     2574        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatFlushExitOnReturn);
     2575        uint32_t const uOrgExit = pRun->exit_reason;
     2576        for (uint32_t i = 0; ; i++)
     2577        {
     2578            pRun->immediate_exit = 1;
     2579            int rcLnx = ioctl(pVCpu->nem.s.fdVCpu, KVM_RUN, 0UL);
     2580            Log(("NEM/%u: Flushed stateful exit -> %d/%d exit_reason=%d\n", pVCpu->idCpu, rcLnx, errno, pRun->exit_reason));
     2581            if (rcLnx == -1 && errno == EINTR)
     2582            {
     2583                switch (i)
     2584                {
     2585                    case 0: STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatFlushExitOnReturn1Loop); break;
     2586                    case 1: STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatFlushExitOnReturn2Loops); break;
     2587                    case 2: STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatFlushExitOnReturn3Loops); break;
     2588                    default: STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatFlushExitOnReturn4PlusLoops); break;
     2589                }
     2590                break;
     2591            }
     2592            AssertLogRelMsgBreakStmt(rcLnx == 0 && pRun->exit_reason == uOrgExit,
     2593                                     ("rcLnx=%d errno=%d exit_reason=%d uOrgExit=%d\n", rcLnx, errno, pRun->exit_reason, uOrgExit),
     2594                                     rcStrict = VERR_NEM_IPE_6);
     2595            VBOXSTRICTRC rcStrict2 = nemHCLnxHandleExit(pVM, pVCpu, pRun, &fStatefulExit);
     2596            if (rcStrict2 == VINF_SUCCESS || rcStrict2 == rcStrict)
     2597            { /* likely */ }
     2598            else if (RT_FAILURE(rcStrict2))
     2599            {
     2600                rcStrict = rcStrict2;
     2601                break;
     2602            }
     2603            else
     2604            {
     2605                AssertLogRelMsgBreakStmt(rcStrict == VINF_SUCCESS,
     2606                                         ("rcStrict=%Rrc rcStrict2=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict), VBOXSTRICTRC_VAL(rcStrict2)),
     2607                                         rcStrict = VERR_NEM_IPE_7);
     2608                rcStrict = rcStrict2;
     2609            }
     2610        }
    25682611        pRun->immediate_exit = 0;
    2569         Log(("NEM/%u: Flushed stateful exit -> %d/%d exit_reason=%d\n", pVCpu->idCpu, rcLnx, errno, pRun->exit_reason)); RT_NOREF(rcLnx);
    2570         STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatFlushExitOnReturn);
    25712612    }
    25722613
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