VirtualBox

Changeset 54224 in vbox for trunk/include/VBox


Ignore:
Timestamp:
Feb 16, 2015 10:41:32 PM (10 years ago)
Author:
vboxsync
Message:

SUP,IPRT: Started as a build fix ended up as a cleanup (mostly untested as I'm windows). We'll keep SUP_IOCTL_TSC_READ for the purpose of dealing with the i64TSCDelta == INT64_MAX in SUPReadTsc/SUPReadTscWithDelta. Moved the excessive inline code from sup.h to SUPLibAll.cpp (new file) and SUPDrv.c (apply delta). Don't bother too much about trying to share code between SUPLibAll.cpp and SUPDrv.c/++ as the SUPReadTsc[WithDelta] scenario does not care about knowing when things goes bad, it just needs a TSC that is as good as we can get. The SUPDrv.c code on the other hand probably needs other kind of status codes, assertions and whatnot to be better off with its own version of the code. Remove the now unused assembly macro for applying the delta - the way the delta is applied will not change, period, so better just document it instead.

File:
1 edited

Legend:

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

    r54222 r54224  
    240240    /** Current CPU Frequency. */
    241241    volatile uint64_t   u64CpuHz;
    242     /** The TSC delta with reference to the master TSC. */
     242    /** The TSC delta with reference to the master TSC, subtract from RDTSC. */
    243243    volatile int64_t    i64TSCDelta;
    244244    /** Number of errors during updating.
     
    439439    ((a_pGip)->u32Mode == SUPGIPMODE_INVARIANT_TSC && !((a_pGip)->fOsTscDeltasInSync))
    440440
    441 /** Whether the application of TSC-deltas are worth it (performance matters). */
    442 #define GIP_TSC_DELTAS_ROUGHLY_IN_SYNC(a_pGip)         ((a_pGip)->fTscDeltasRoughlyInSync)
    443441
    444442#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     
    15471545#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    15481546
    1549 /**
    1550  * Applies the TSC delta to the supplied raw TSC value.
    1551  *
    1552  * @returns VBox status code.
    1553  * @param   pGip            Pointer to the GIP.
    1554  * @param   puTsc           Pointer to a valid TSC value before the TSC delta has been applied.
    1555  * @param   idApic          The APIC ID of the CPU @c puTsc corresponds to.
    1556  * @param   fDeltaApplied   Where to store whether the TSC delta was succesfully
    1557  *                          applied or not (optional, can be NULL).
    1558  *
    1559  * @remarks Maybe called with interrupts disabled in ring-0!
    1560  *
    1561  * @note    If you change the delta calculation made here, make sure to update
    1562  *          the assembly version in sup.mac! Also update supdrvGipMpEvent()
    1563  *          while re-adjusting deltas while choosing a new GIP master.
    1564  */
    1565 DECLINLINE(int) SUPTscDeltaApply(PSUPGLOBALINFOPAGE pGip, uint64_t *puTsc, uint16_t idApic, bool *pfDeltaApplied)
    1566 {
    1567     PSUPGIPCPU pGipCpu;
    1568     uint16_t  iCpu;
    1569 
    1570     /* Validate. */
    1571     Assert(puTsc);
    1572     Assert(pGip);
    1573     Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pGip));
    1574 
    1575     /** @todo convert these to AssertMsg() after sufficient testing before public
    1576      *        release. */
    1577     AssertMsgReturn(idApic < RT_ELEMENTS(pGip->aiCpuFromApicId), ("idApic=%u\n", idApic), VERR_INVALID_CPU_ID);
    1578     iCpu = pGip->aiCpuFromApicId[idApic];
    1579     AssertMsgReturn(iCpu < pGip->cCpus, ("iCpu=%u cCpus=%u\n", iCpu, pGip->cCpus), VERR_INVALID_CPU_INDEX);
    1580     pGipCpu = &pGip->aCPUs[iCpu];
    1581     Assert(pGipCpu);
    1582 
    1583     if (RT_LIKELY(pGipCpu->i64TSCDelta != INT64_MAX))
    1584     {
    1585         *puTsc -= pGipCpu->i64TSCDelta;
    1586         if (pfDeltaApplied)
    1587             *pfDeltaApplied = true;
    1588     }
    1589     else if (pfDeltaApplied)
    1590         *pfDeltaApplied = false;
    1591 
    1592     return VINF_SUCCESS;
    1593 }
    1594 
    1595 
    1596 /**
    1597  * Gets the delta-adjusted TSC.
    1598  *
    1599  * Must only be called when GIP mode is invariant (i.e. when TSC deltas are
    1600  * likely to be computed and available).  In other GIP modes, like async, we
    1601  * don't bother with computing TSC deltas and therefore it is meaningless to
    1602  * call this function, use SUPReadTSC() instead.
    1603  *
    1604  * @returns VBox status code.
    1605  * @param   puTsc           Where to store the normalized TSC value.
    1606  * @param   pidApic         Where to store the APIC ID of the CPU where the TSC
    1607  *                          was read (optional, can be NULL). This is updated
    1608  *                          even if the function fails with
    1609  *                          VERR_SUPDRV_TSC_READ_FAILED. Not guaranteed to be
    1610  *                          updated for other failures.
    1611  *
    1612  * @remarks May be called with interrupts disabled in ring-0!
    1613  */
    1614 DECLINLINE(int) SUPGetTsc(uint64_t *puTsc, uint16_t *pidApic)
    1615 {
    1616 # ifdef IN_RING3
    1617 
    1618     /** @todo Use rdtscp after figuring out what the host OS has stuffed into the
    1619      *        TSC_AUX msr, otherwise use the fallback below. */
    1620     int cTries = 10;
    1621     Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(g_pSUPGlobalInfoPage));
    1622     do
    1623     {
    1624         uint16_t idApicBefore;
    1625         uint16_t idApicAfter;
    1626 
    1627         /* The chance of getting preempted twice here is rather low, hence we
    1628            take this approach. Performance matters, see @bugref{6710} comment #24. */
    1629         idApicBefore = ASMGetApicId();
    1630         *puTsc       = ASMReadTSC();
    1631         idApicAfter  = ASMGetApicId();
    1632         if (RT_LIKELY(idApicBefore == idApicAfter))
    1633         {
    1634             SUPTscDeltaApply(g_pSUPGlobalInfoPage, puTsc, idApicBefore, NULL);
    1635             if (pidApic)
    1636                 *pidApic = idApicBefore;
    1637             return VINF_SUCCESS;
    1638         }
    1639     } while (cTries-- > 0);
    1640     *puTsc = 0;
    1641     return VERR_SUPDRV_TSC_READ_FAILED;
    1642 
    1643     /** @todo get rid of SUPR3ReadTsc(). */
    1644     //return SUPR3ReadTsc(puTsc, pidApic);
    1645 # else
    1646     RTCCUINTREG uFlags;
    1647     uint16_t    idApic;
    1648     bool        fDeltaApplied;
    1649     int         rc;
    1650 
    1651     /** @todo Use rdtscp after figuring out what the host OS has stuffed into the
    1652      *        TSC_AUX msr, otherwise use the fallback below. */
    1653 
    1654     /* Validate. */
    1655     Assert(puTsc);
    1656 
    1657     uFlags = ASMIntDisableFlags();
    1658     idApic = ASMGetApicId();        /* Doubles as serialization. */
    1659     *puTsc = ASMReadTSC();
    1660     ASMSetFlags(uFlags);
    1661 
    1662     if (pidApic)
    1663         *pidApic = idApic;
    1664 
    1665     rc = SUPTscDeltaApply(g_pSUPGlobalInfoPage, puTsc, idApic, &fDeltaApplied);
    1666     AssertRC(rc);
    1667     return fDeltaApplied ? VINF_SUCCESS : VERR_SUPDRV_TSC_READ_FAILED;
    1668 # endif
    1669 }
    1670 
     1547/** @internal */
     1548SUPDECL(uint64_t) SUPReadTscWithDelta(void);
    16711549
    16721550/**
     
    16821560{
    16831561    if (    GIP_ARE_TSC_DELTAS_APPLICABLE(g_pSUPGlobalInfoPage)
    1684         && !GIP_TSC_DELTAS_ROUGHLY_IN_SYNC(g_pSUPGlobalInfoPage))
    1685     {
    1686         uint64_t u64Tsc = UINT64_MAX;
    1687         int rc = SUPGetTsc(&u64Tsc, NULL /* pidApic */);
    1688         NOREF(rc);
    1689 #ifdef DEBUG_ramshankar
    1690         AssertRC(rc);
    1691 #endif
    1692         return u64Tsc;
    1693     }
     1562        && !g_pSUPGlobalInfoPage->fTscDeltasRoughlyInSync)
     1563        return SUPReadTscWithDelta();
    16941564    return ASMReadTSC();
    16951565}
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