VirtualBox

Changeset 32796 in vbox


Ignore:
Timestamp:
Sep 28, 2010 2:54:41 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
66245
Message:

GVMMR0,TM,STAM: Periodic preemption timer fixes, adjustments and statistics. (still disabled)

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/gvmm.h

    r32489 r32796  
    3131#include <VBox/types.h>
    3232#include <VBox/sup.h>
     33#include <iprt/cpuset.h> /* RTCPUSET_MAX_CPUS */
    3334
    3435RT_C_DECLS_BEGIN
     
    105106
    106107/**
     108 * Per host cpu statistics.
     109 */
     110typedef struct GVMMSTATSHOSTCPU
     111{
     112    /** The CPU ID. */
     113    RTCPUID         idCpu;
     114    /** The CPU's set index. */
     115    uint32_t        idxCpuSet;
     116    /** The desired PPT frequency. */
     117    uint32_t        uDesiredHz;
     118    /** The current PPT timer frequency.  */
     119    uint32_t        uTimerHz;
     120    /** The number of times the PPT was changed. */
     121    uint32_t        cChanges;
     122    /** The number of times the PPT was started. */
     123    uint32_t        cStarts;
     124} GVMMSTATSHOSTCPU;
     125/** Pointer to the GVMM per host CPU statistics. */
     126typedef GVMMSTATSHOSTCPU *PGVMMSTATSHOSTCPU;
     127
     128/**
    107129 * The GMM statistics.
    108130 */
     
    110132{
    111133    /** The VM statistics if a VM was specified. */
    112     GVMMSTATSSCHED  SchedVM;
     134    GVMMSTATSSCHED      SchedVM;
    113135    /** The sum statistics of all VMs accessible to the caller. */
    114     GVMMSTATSSCHED  SchedSum;
     136    GVMMSTATSSCHED      SchedSum;
    115137    /** The number of VMs accessible to the caller. */
    116     uint32_t        cVMs;
     138    uint32_t            cVMs;
    117139    /** The number of emulation threads in those VMs. */
    118     uint32_t        cEMTs;
     140    uint32_t            cEMTs;
     141    /** Padding.  */
     142    uint32_t            u32Padding;
     143    /** The number of valid entries in aHostCpus. */
     144    uint32_t            cHostCpus;
     145    /** Per host CPU statistics. */
     146    GVMMSTATSHOSTCPU    aHostCpus[RTCPUSET_MAX_CPUS];
    119147} GVMMSTATS;
    120148/** Pointer to the GVMM statistics. */
  • trunk/include/VBox/stam.h

    r30684 r32796  
    216216    /** Percentage. */
    217217    STAMUNIT_PCT,
     218    /** Hertz. */
     219    STAMUNIT_HZ,
    218220    /** The end (exclusive). */
    219221    STAMUNIT_END
  • trunk/include/VBox/uvm.h

    r32190 r32796  
    125125        struct STAMUSERPERVM    s;
    126126#endif
    127         uint8_t                 padding[256];
     127        uint8_t                 padding[4096];
    128128    } stam;
    129129
  • trunk/include/VBox/vm.h

    r32137 r32796  
    166166        struct TMCPU        s;
    167167#endif
    168         uint8_t             padding[256];       /* multiple of 64 */
     168        uint8_t             padding[384];       /* multiple of 64 */
    169169    } tm;
    170170
     
    207207
    208208    /** Align the following members on page boundrary. */
    209     uint8_t                 abAlignment2[192];
     209    uint8_t                 abAlignment2[64];
    210210
    211211    /** PGM part. */
  • trunk/src/VBox/VMM/STAM.cpp

    r28800 r32796  
    179179
    180180/**
    181  * The GVMM mapping records.
     181 * The GVMM mapping records - sans the host cpus.
    182182 */
    183183static const STAMR0SAMPLE g_aGVMMStats[] =
     
    213213    { RT_UOFFSETOF(GVMMSTATS, cVMs),                      STAMTYPE_U32,       STAMUNIT_CALLS, "/GVMM/VMs", "The number of VMs accessible to the caller." },
    214214    { RT_UOFFSETOF(GVMMSTATS, cEMTs),                     STAMTYPE_U32,       STAMUNIT_CALLS, "/GVMM/EMTs", "The number of emulation threads." },
     215    { RT_UOFFSETOF(GVMMSTATS, cHostCpus),                 STAMTYPE_U32,       STAMUNIT_CALLS, "/GVMM/HostCPUs", "The number of host CPUs." },
    215216};
    216217
     
    783784                fGVMMMatched = true;
    784785            }
     786        if (!fGVMMMatched)
     787        {
     788            /** @todo match cpu leaves some rainy day.  */
     789        }
    785790
    786791        /* GMM */
     
    943948     */
    944949    stamR3SnapshotPrintf(&State, "<Statistics>\n");
    945     STAM_LOCK_RD(pUVM);
    946950    int rc = stamR3EnumU(pUVM, pszPat, true /* fUpdateRing0 */, stamR3SnapshotOne, &State);
    947     STAM_UNLOCK_RD(pUVM);
    948951    stamR3SnapshotPrintf(&State, "</Statistics>\n");
    949952
     
    12621265    Args.pfnPrintf = stamR3EnumLogPrintf;
    12631266
    1264     STAM_LOCK_RD(pUVM);
    12651267    stamR3EnumU(pUVM, pszPat, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
    1266     STAM_UNLOCK_RD(pUVM);
    12671268    return VINF_SUCCESS;
    12681269}
     
    13151316    Args.pfnPrintf = stamR3EnumRelLogPrintf;
    13161317
    1317     STAM_LOCK_RD(pUVM);
    13181318    stamR3EnumU(pUVM, pszPat, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
    1319     STAM_UNLOCK_RD(pUVM);
    13201319    return VINF_SUCCESS;
    13211320}
     
    13681367    Args.pfnPrintf = stamR3EnumPrintf;
    13691368
    1370     STAM_LOCK_RD(pUVM);
    13711369    stamR3EnumU(pUVM, pszPat, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
    1372     STAM_UNLOCK_RD(pUVM);
    13731370    return VINF_SUCCESS;
    13741371}
     
    15381535    Args.pvUser  = pvUser;
    15391536
    1540     STAM_LOCK_RD(pUVM);
    1541     int rc = stamR3EnumU(pUVM, pszPat, true /* fUpdateRing0 */, stamR3EnumOne, &Args);
    1542     STAM_UNLOCK_RD(pUVM);
    1543     return rc;
     1537    return stamR3EnumU(pUVM, pszPat, true /* fUpdateRing0 */, stamR3EnumOne, &Args);
    15441538}
    15451539
     
    16691663 * is specified.
    16701664 *
    1671  * The call must own at least a read lock to the STAM data.
     1665 * The call may lock STAM for writing before calling this function, however do
     1666 * not lock it for reading as this function may need to write lock STAM.
    16721667 *
    16731668 * @returns The rc from the callback.
    1674  * @param   pUVM        Pointer to the user mode VM structure.
     1669 * @param   pUVM            Pointer to the user mode VM structure.
    16751670 * @param   pszPat          Pattern.
    16761671 * @param   fUpdateRing0    Update the ring-0 .
     
    16801675 * @param   pvArg           User parameter for the callback.
    16811676 */
    1682 static int stamR3EnumU(PUVM pUVM, const char *pszPat, bool fUpdateRing0, int (*pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg)
     1677static int stamR3EnumU(PUVM pUVM, const char *pszPat, bool fUpdateRing0,
     1678                       int (*pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg)
    16831679{
    16841680    int rc = VINF_SUCCESS;
     
    16921688            stamR3Ring0StatsUpdateU(pUVM, "*");
    16931689
    1694         PSTAMDESC   pCur = pUVM->stam.s.pHead;
     1690        STAM_LOCK_RD(pUVM);
     1691        PSTAMDESC pCur = pUVM->stam.s.pHead;
    16951692        while (pCur)
    16961693        {
     
    17021699            pCur = pCur->pNext;
    17031700        }
     1701        STAM_UNLOCK_RD(pUVM);
    17041702    }
    17051703
     
    17121710            stamR3Ring0StatsUpdateU(pUVM, pszPat);
    17131711
     1712        STAM_LOCK_RD(pUVM);
    17141713        /** @todo This needs to be optimized since the GUI is using this path for the VM info dialog.
    17151714         * Note that it's doing exact matching. Organizing the samples in a tree would speed up thing
     
    17221721                    break;
    17231722            }
     1723        STAM_UNLOCK_RD(pUVM);
    17241724    }
    17251725
     
    17441744            stamR3Ring0StatsUpdateMultiU(pUVM, papszExpressions, cExpressions);
    17451745
     1746        STAM_LOCK_RD(pUVM);
    17461747        unsigned iExpression = 0;
    17471748        for (PSTAMDESC pCur = pUVM->stam.s.pHead; pCur; pCur = pCur->pNext)
     
    17521753                    break;
    17531754            }
     1755        STAM_UNLOCK_RD(pUVM);
    17541756
    17551757        RTMemTmpFree(papszExpressions);
     
    17731775                        g_aGVMMStats[i].enmType, STAMVISIBILITY_ALWAYS, g_aGVMMStats[i].pszName,
    17741776                        g_aGVMMStats[i].enmUnit, g_aGVMMStats[i].pszDesc);
     1777    pUVM->stam.s.cRegisteredHostCpus = 0;
    17751778}
    17761779
     
    17911794 * Updates the ring-0 statistics.
    17921795 *
    1793  * The ring-0 statistics aren't directly addressable from ring-3 and
    1794  * must be copied when needed.
     1796 * The ring-0 statistics aren't directly addressable from ring-3 and must be
     1797 * copied when needed.
    17951798 *
    17961799 * @param   pUVM        Pointer to the user mode VM structure.
     
    18111814            break;
    18121815        }
     1816    if (!fUpdate)
     1817    {
     1818        /** @todo check the cpu leaves - rainy day.   */
     1819    }
    18131820    if (fUpdate)
    18141821    {
     
    18191826        int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, NIL_VMCPUID, VMMR0_DO_GVMM_QUERY_STATISTICS, 0, &Req.Hdr);
    18201827        if (RT_SUCCESS(rc))
     1828        {
    18211829            pUVM->stam.s.GVMMStats = Req.Stats;
     1830
     1831            /*
     1832             * Check if the number of host CPUs has changed (it will the first
     1833             * time around and normally never again).
     1834             */
     1835            if (RT_UNLIKELY(pUVM->stam.s.GVMMStats.cHostCpus > pUVM->stam.s.cRegisteredHostCpus))
     1836            {
     1837                STAM_LOCK_WR(pUVM);
     1838                if (RT_UNLIKELY(pUVM->stam.s.GVMMStats.cHostCpus > pUVM->stam.s.cRegisteredHostCpus))
     1839                {
     1840                    uint32_t cCpus = pUVM->stam.s.GVMMStats.cHostCpus;
     1841                    for (uint32_t iCpu  = pUVM->stam.s.cRegisteredHostCpus; iCpu < cCpus; iCpu++)
     1842                    {
     1843                        char   szName[120];
     1844                        size_t cchBase = RTStrPrintf(szName, sizeof(szName), "/GVMM/HostCpus/%u", iCpu);
     1845                        stamR3RegisterU(pUVM, &pUVM->stam.s.GVMMStats.aHostCpus[iCpu].idCpu, NULL, NULL,
     1846                                        STAMTYPE_U32, STAMVISIBILITY_ALWAYS, szName, STAMUNIT_NONE, "Host CPU ID");
     1847                        strcpy(&szName[cchBase], "/idxCpuSet");
     1848                        stamR3RegisterU(pUVM, &pUVM->stam.s.GVMMStats.aHostCpus[iCpu].idxCpuSet, NULL, NULL,
     1849                                        STAMTYPE_U32, STAMVISIBILITY_ALWAYS, szName, STAMUNIT_NONE, "CPU Set index");
     1850                        strcpy(&szName[cchBase], "/DesiredHz");
     1851                        stamR3RegisterU(pUVM, &pUVM->stam.s.GVMMStats.aHostCpus[iCpu].uDesiredHz, NULL, NULL,
     1852                                        STAMTYPE_U32, STAMVISIBILITY_ALWAYS, szName, STAMUNIT_HZ, "The desired frequency");
     1853                        strcpy(&szName[cchBase], "/CurTimerHz");
     1854                        stamR3RegisterU(pUVM, &pUVM->stam.s.GVMMStats.aHostCpus[iCpu].uTimerHz, NULL, NULL,
     1855                                        STAMTYPE_U32, STAMVISIBILITY_ALWAYS, szName, STAMUNIT_HZ, "The current timer frequency");
     1856                        strcpy(&szName[cchBase], "/PPTChanges");
     1857                        stamR3RegisterU(pUVM, &pUVM->stam.s.GVMMStats.aHostCpus[iCpu].cChanges, NULL, NULL,
     1858                                        STAMTYPE_U32, STAMVISIBILITY_ALWAYS, szName, STAMUNIT_OCCURENCES, "RTTimerChangeInterval calls");
     1859                        strcpy(&szName[cchBase], "/PPTStarts");
     1860                        stamR3RegisterU(pUVM, &pUVM->stam.s.GVMMStats.aHostCpus[iCpu].cStarts, NULL, NULL,
     1861                                        STAMTYPE_U32, STAMVISIBILITY_ALWAYS, szName, STAMUNIT_OCCURENCES, "RTTimerStart calls");
     1862                    }
     1863                    pUVM->stam.s.cRegisteredHostCpus = cCpus;
     1864                }
     1865                STAM_UNLOCK_WR(pUVM);
     1866            }
     1867        }
    18221868    }
    18231869}
     
    18511897        case STAMUNIT_NS_PER_OCCURENCE:     return "ns/time";
    18521898        case STAMUNIT_PCT:                  return "%";
     1899        case STAMUNIT_HZ:                   return "Hz";
    18531900
    18541901        default:
     
    18891936    Args.pfnPrintf = stamR3EnumDbgfPrintf;
    18901937
    1891     STAM_LOCK_RD(pUVM);
    1892     int rc = stamR3EnumU(pUVM, cArgs ? paArgs[0].u.pszString : NULL, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
    1893     STAM_UNLOCK_RD(pUVM);
    1894 
    1895     return rc;
     1938    return stamR3EnumU(pUVM, cArgs ? paArgs[0].u.pszString : NULL, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
    18961939}
    18971940
  • trunk/src/VBox/VMM/STAMInternal.h

    r28800 r32796  
    103103    /** The copy of the GVMM statistics. */
    104104    GVMMSTATS               GVMMStats;
     105    /** The number of registered host CPU leaves. */
     106    uint32_t                cRegisteredHostCpus;
    105107} STAMUSERPERVM;
    106108/** Pointer to the STAM data kept in the UVM. */
  • trunk/src/VBox/VMM/TM.cpp

    r32504 r32796  
    505505
    506506    /*
     507     * Gather the Host Hz configuration values.
     508     */
     509    rc = CFGMR3QueryU32Def(pCfgHandle, "HostHzMax", &pVM->tm.s.cHostHzMax, 20000);
     510    if (RT_FAILURE(rc))
     511        return VMSetError(pVM, rc, RT_SRC_POS,
     512                          N_("Configuration error: Failed to querying uint32_t value \"HostHzMax\""));
     513
     514    rc = CFGMR3QueryU32Def(pCfgHandle, "HostHzFudgeFactorTimerCpu", &pVM->tm.s.cPctHostHzFudgeFactorTimerCpu, 111);
     515    if (RT_FAILURE(rc))
     516        return VMSetError(pVM, rc, RT_SRC_POS,
     517                          N_("Configuration error: Failed to querying uint32_t value \"HostHzFudgeFactorTimerCpu\""));
     518
     519    rc = CFGMR3QueryU32Def(pCfgHandle, "HostHzFudgeFactorOtherCpu", &pVM->tm.s.cPctHostHzFudgeFactorOtherCpu, 110);
     520    if (RT_FAILURE(rc))
     521        return VMSetError(pVM, rc, RT_SRC_POS,
     522                          N_("Configuration error: Failed to querying uint32_t value \"HostHzFudgeFactorOtherCpu\""));
     523
     524    rc = CFGMR3QueryU32Def(pCfgHandle, "HostHzFudgeFactorCatchUp100", &pVM->tm.s.cPctHostHzFudgeFactorCatchUp100, 300);
     525    if (RT_FAILURE(rc))
     526        return VMSetError(pVM, rc, RT_SRC_POS,
     527                          N_("Configuration error: Failed to querying uint32_t value \"HostHzFudgeFactorCatchUp100\""));
     528
     529    rc = CFGMR3QueryU32Def(pCfgHandle, "HostHzFudgeFactorCatchUp200", &pVM->tm.s.cPctHostHzFudgeFactorCatchUp200, 250);
     530    if (RT_FAILURE(rc))
     531        return VMSetError(pVM, rc, RT_SRC_POS,
     532                          N_("Configuration error: Failed to querying uint32_t value \"HostHzFudgeFactorCatchUp200\""));
     533
     534    rc = CFGMR3QueryU32Def(pCfgHandle, "HostHzFudgeFactorCatchUp400", &pVM->tm.s.cPctHostHzFudgeFactorCatchUp400, 200);
     535    if (RT_FAILURE(rc))
     536        return VMSetError(pVM, rc, RT_SRC_POS,
     537                          N_("Configuration error: Failed to querying uint32_t value \"HostHzFudgeFactorCatchUp400\""));
     538
     539    /*
    507540     * Start the timer (guard against REM not yielding).
    508541     */
     
    546579    STAM_REL_REG(     pVM,(void*)&pVM->tm.s.offVirtualSync,               STAMTYPE_U64, "/TM/VirtualSync/CurrentOffset",               STAMUNIT_NS, "The current offset. (subtract GivenUp to get the lag)");
    547580    STAM_REL_REG_USED(pVM,(void*)&pVM->tm.s.offVirtualSyncGivenUp,        STAMTYPE_U64, "/TM/VirtualSync/GivenUp",                     STAMUNIT_NS, "Nanoseconds of the 'CurrentOffset' that's been given up and won't ever be attemted caught up with.");
     581    STAM_REL_REG(     pVM,(void*)&pVM->tm.s.uMaxHzHint,                   STAMTYPE_U32, "/TM/MaxHzHint",                               STAMUNIT_HZ, "Max guest timer frequency hint.");
    548582
    549583#ifdef VBOX_WITH_STATISTICS
     
    637671        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsTotal,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,               "Resettable: Total CPU run time.",   "/TM/CPU/%02u", i);
    638672        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsExecuting,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code.",    "/TM/CPU/%02u/PrfExecuting", i);
     673        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsExecLong,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - long hauls.",    "/TM/CPU/%02u/PrfExecLong", i);
     674        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsExecShort,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - short streches.",    "/TM/CPU/%02u/PrfExecShort", i);
     675        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsExecTiny,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - tiny bits.",    "/TM/CPU/%02u/PrfExecTiny", i);
    639676        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsHalted,      STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent halted.",                  "/TM/CPU/%02u/PrfHalted", i);
    640677        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsOther,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent in the VMM or preempted.", "/TM/CPU/%02u/PrfOther", i);
  • trunk/src/VBox/VMM/TMInternal.h

    r32484 r32796  
    426426    /** Alignment */
    427427    bool                        afAlignment2[3];
     428    /** @cfgm{TM/HostHzMax, uint32_t, Hz, 0, UINT32_MAX, 20000}
     429     * The max host Hz frequency hint returned by TMCalcHostTimerFrequency.  */
     430    uint32_t                    cHostHzMax;
     431    /** @cfgm{TM/HostHzFudgeFactorTimerCpu, uint32_t, Hz, 0, UINT32_MAX, 111}
     432     * The number of Hz TMCalcHostTimerFrequency adds for the timer CPU.  */
     433    uint32_t                    cPctHostHzFudgeFactorTimerCpu;
     434    /** @cfgm{TM/HostHzFudgeFactorOtherCpu, uint32_t, Hz, 0, UINT32_MAX, 110}
     435     * The number of Hz TMCalcHostTimerFrequency adds for the other CPUs. */
     436    uint32_t                    cPctHostHzFudgeFactorOtherCpu;
     437    /** @cfgm{TM/HostHzFudgeFactorCatchUp100, uint32_t, Hz, 0, UINT32_MAX, 300}
     438     *  The fudge factor (expressed in percent) that catch-up percentages below
     439     * 100% is multiplied by. */
     440    uint32_t                    cPctHostHzFudgeFactorCatchUp100;
     441    /** @cfgm{TM/HostHzFudgeFactorCatchUp200, uint32_t, Hz, 0, UINT32_MAX, 250}
     442     * The fudge factor (expressed in percent) that catch-up percentages
     443     * 100%-199% is multiplied by. */
     444    uint32_t                    cPctHostHzFudgeFactorCatchUp200;
     445    /** @cfgm{TM/HostHzFudgeFactorCatchUp400, uint32_t, Hz, 0, UINT32_MAX, 200}
     446     * The fudge factor (expressed in percent) that catch-up percentages
     447     * 200%-399% is multiplied by. */
     448    uint32_t                    cPctHostHzFudgeFactorCatchUp400;
    428449
    429450    /** The UTC offset in ns.
     
    645666    /** Resettable version of cNsExecuting. */
    646667    STAMPROFILE                 StatNsExecuting;
     668    /** Long execution intervals. */
     669    STAMPROFILE                 StatNsExecLong;
     670    /** Short execution intervals . */
     671    STAMPROFILE                 StatNsExecShort;
     672    /** Tiny execution intervals . */
     673    STAMPROFILE                 StatNsExecTiny;
    647674    /** Resettable version of cNsHalted. */
    648675    STAMPROFILE                 StatNsHalted;
  • trunk/src/VBox/VMM/VMMAll/TMAll.cpp

    r32572 r32796  
    201201# if defined(VBOX_WITH_STATISTICS) || defined(VBOX_WITH_NS_ACCOUNTING_STATS)
    202202    STAM_REL_PROFILE_ADD_PERIOD(&pVCpu->tm.s.StatNsExecuting, cNsExecutingDelta);
     203    if (cNsExecutingDelta < 5000)
     204        STAM_REL_PROFILE_ADD_PERIOD(&pVCpu->tm.s.StatNsExecTiny, cNsExecutingDelta);
     205    else if (cNsExecutingDelta < 50000)
     206        STAM_REL_PROFILE_ADD_PERIOD(&pVCpu->tm.s.StatNsExecShort, cNsExecutingDelta);
     207    else
     208        STAM_REL_PROFILE_ADD_PERIOD(&pVCpu->tm.s.StatNsExecLong, cNsExecutingDelta);
    203209    STAM_REL_COUNTER_ADD(&pVCpu->tm.s.StatNsTotal, cNsTotalNew - pVCpu->tm.s.cNsTotal);
    204210    int64_t  const cNsOtherNewDelta  = cNsOtherNew - pVCpu->tm.s.cNsOther;
     
    14431449{
    14441450    TMTIMER_ASSERT_CRITSECT(pTimer);
     1451
     1452    uint32_t const uHzOldHint = pTimer->uHzHint;
    14451453    pTimer->uHzHint = uHzHint;
     1454
    14461455    PVM pVM = pTimer->CTX_SUFF(pVM);
    1447     if (uHzHint >= pVM->tm.s.uMaxHzHint)
     1456    uint32_t const uMaxHzHint = pVM->tm.s.uMaxHzHint;
     1457    if (   uHzHint    >  uMaxHzHint
     1458        || uHzOldHint >= uMaxHzHint)
    14481459        ASMAtomicWriteBool(&pVM->tm.s.fHzHintNeedsUpdating, true);
     1460
    14491461    return VINF_SUCCESS;
    14501462}
     
    23502362    uint32_t uHz = tmGetFrequencyHint(pVM);
    23512363
    2352     /* Catch up. */
     2364    /* Catch up, we have to be more aggressive than the % indicates at the
     2365       beginning of the effort. */
    23532366    if (ASMAtomicUoReadBool(&pVM->tm.s.fVirtualSyncCatchUp))
    23542367    {
     
    23562369        if (ASMAtomicReadBool(&pVM->tm.s.fVirtualSyncCatchUp))
    23572370        {
     2371            if (u32Pct <= 100)
     2372                u32Pct = u32Pct * pVM->tm.s.cPctHostHzFudgeFactorCatchUp100 / 100;
     2373            else if (u32Pct <= 200)
     2374                u32Pct = u32Pct * pVM->tm.s.cPctHostHzFudgeFactorCatchUp200 / 100;
     2375            else if (u32Pct <= 400)
     2376                u32Pct = u32Pct * pVM->tm.s.cPctHostHzFudgeFactorCatchUp400 / 100;
    23582377            uHz *= u32Pct + 100;
    23592378            uHz /= 100;
     
    23612380    }
    23622381
    2363     /* Warp drive */
     2382    /* Warp drive. */
    23642383    if (ASMAtomicUoReadBool(&pVM->tm.s.fVirtualWarpDrive))
    23652384    {
     
    23732392
    23742393    /* Fudge factor. */
    2375     /** @todo make this configurable. */
    2376 #if 0 /* what's wrong with this expression? I end up with uHz = 0 after this multiplication... */
    2377     uHz *= 110 + pVCpu->idCpu == pVM->tm.s.idTimerCpu;
    2378 #else
    23792394    if (pVCpu->idCpu == pVM->tm.s.idTimerCpu)
    2380         uHz *= 111;
     2395        uHz *= pVM->tm.s.cPctHostHzFudgeFactorTimerCpu;
    23812396    else
    2382         uHz *= 110;
    2383 #endif
     2397        uHz *= pVM->tm.s.cPctHostHzFudgeFactorOtherCpu;
    23842398    uHz /= 100;
    23852399
    2386     //LogAlways(("TMCalcHostTimerFrequency->%u\n", uHz));
     2400    /* Make sure it isn't too high. */
     2401    if (uHz > pVM->tm.s.cHostHzMax)
     2402        uHz = pVM->tm.s.cHostHzMax;
     2403
    23872404    return uHz;
    23882405}
  • trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp

    r32572 r32796  
    154154         * are added at iHzHistory. This is updated approximately every
    155155         * GVMMHOSTCPU_PPT_HIST_INTERVAL_NS by the timer callback. */
    156         uint32_t            aHzHistory[32];
     156        uint32_t            aHzHistory[8];
    157157        /** Statistics counter for recording the number of interval changes. */
    158         uint64_t            cChanges;
     158        uint32_t            cChanges;
    159159        /** Statistics counter for recording the number of timer starts. */
    160         uint64_t            cStarts;
     160        uint32_t            cStarts;
    161161    } Ppt;
    162162#endif /* GVMM_SCHED_WITH_PPT */
     
    21822182     * callback here.
    21832183     */
    2184     if (uHz > 20000)
    2185         uHz = 20000;
     2184    if (uHz > 16384)
     2185        uHz = 16384;  /** @todo add a query method for this! */
    21862186    if (RT_UNLIKELY(   uHz > ASMAtomicReadU32(&pCpu->Ppt.uDesiredHz)
    21872187                    && uHz >= pCpu->Ppt.uMinHz
     
    23082308        }
    23092309    }
     2310
     2311    /*
     2312     * Copy out the per host CPU statistics.
     2313     */
     2314    uint32_t iDstCpu = 0;
     2315    uint32_t cSrcCpus = pGVMM->cHostCpus;
     2316    for (uint32_t iSrcCpu = 0; iSrcCpu < cSrcCpus; iSrcCpu++)
     2317    {
     2318        if (pGVMM->aHostCpus[iSrcCpu].idCpu != NIL_RTCPUID)
     2319        {
     2320            pStats->aHostCpus[iDstCpu].idCpu      = pGVMM->aHostCpus[iSrcCpu].idCpu;
     2321            pStats->aHostCpus[iDstCpu].idxCpuSet  = pGVMM->aHostCpus[iSrcCpu].idxCpuSet;
     2322#ifdef GVMM_SCHED_WITH_PPT
     2323            pStats->aHostCpus[iDstCpu].uDesiredHz = pGVMM->aHostCpus[iSrcCpu].Ppt.uDesiredHz;
     2324            pStats->aHostCpus[iDstCpu].uTimerHz   = pGVMM->aHostCpus[iSrcCpu].Ppt.uTimerHz;
     2325            pStats->aHostCpus[iDstCpu].cChanges   = pGVMM->aHostCpus[iSrcCpu].Ppt.cChanges;
     2326            pStats->aHostCpus[iDstCpu].cStarts    = pGVMM->aHostCpus[iSrcCpu].Ppt.cStarts;
     2327#else
     2328            pStats->aHostCpus[iDstCpu].uDesiredHz = 0;
     2329            pStats->aHostCpus[iDstCpu].uTimerHz   = 0;
     2330            pStats->aHostCpus[iDstCpu].cChanges   = 0;
     2331            pStats->aHostCpus[iDstCpu].cStarts    = 0;
     2332#endif
     2333            iDstCpu++;
     2334        }
     2335    }
     2336    pStats->cHostCpus = iDstCpu;
    23102337
    23112338    gvmmR0UsedUnlock(pGVMM);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette