VirtualBox

Changeset 57224 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Aug 6, 2015 7:25:07 PM (10 years ago)
Author:
vboxsync
Message:

SUPDrv: Try deal more correctly with multiple SUPGIP_FLAGS_TESTING_ENABLE settings per session and multiple sessions setting & clearing SUPGIP_FLAGS_TESTING_ENABLE. Untested.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp

    r57218 r57224  
    635635        && pDevExt->pGip)
    636636    {
    637         uint32_t fFlags = pDevExt->pGip->fFlags;
    638         fFlags &= ~SUPGIP_FLAGS_TESTING_ENABLE;
    639         supdrvGipSetFlags(pDevExt, pSession, 0, fFlags);
     637        supdrvGipSetFlags(pDevExt, pSession, 0, ~SUPGIP_FLAGS_TESTING_ENABLE);
    640638        Assert(!pSession->fGipTestMode);
    641639    }
     
    21012099static void supdrvGipDoUpdateCpu(PSUPDRVDEVEXT pDevExt, PSUPGIPCPU pGipCpu, uint64_t u64NanoTS, uint64_t u64TSC, uint64_t iTick)
    21022100{
    2103     uint64_t    u64TSCDelta;
    2104     uint32_t    u32UpdateIntervalTSC;
    2105     uint32_t    u32UpdateIntervalTSCSlack;
    2106     unsigned    iTSCHistoryHead;
    2107     bool        fUpdateCpuHz;
    2108     uint32_t    fGipFlags;
    2109     uint64_t    u64CpuHz;
    2110     uint32_t    u32TransactionId;
    2111 
    2112     PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
     2101    uint64_t            u64TSCDelta;
     2102    bool                fUpdateCpuHz;
     2103    PSUPGLOBALINFOPAGE  pGip = pDevExt->pGip;
    21132104    AssertPtrReturnVoid(pGip);
    21142105
     
    21272118    ASMAtomicWriteU64(&pGipCpu->u64TSC, u64TSC);
    21282119
    2129     /* Determine when we need to update the TSC frequency. */
     2120    /*
     2121     * Determine if we need to update the CPU (TSC) frequency calculation.
     2122     *
     2123     * We don't need to keep realculating the frequency when it's invariant,
     2124     * unless the special tstGIP-2 testing mode is enabled.
     2125     */
    21302126    fUpdateCpuHz = pGip->u32Mode != SUPGIPMODE_INVARIANT_TSC;
    2131 
    2132     /*
    2133      * Handle GIP test mode toggle.
    2134      */
    2135     fGipFlags = pGip->fFlags;
    2136     if (!(fGipFlags & SUPGIP_FLAGS_TESTING))
     2127    if (!(pGip->fFlags & SUPGIP_FLAGS_TESTING))
    21372128    { /* likely*/ }
    21382129    else
    21392130    {
     2131        uint32_t fGipFlags = pGip->fFlags;
    21402132        if (fGipFlags & (SUPGIP_FLAGS_TESTING_ENABLE | SUPGIP_FLAGS_TESTING_START))
    21412133        {
     
    21452137                if (!fUpdateCpuHz)
    21462138                    pDevExt->uGipTestModeInvariantCpuHz = pGip->aCPUs[0].u64CpuHz;
    2147                 fGipFlags &= ~SUPGIP_FLAGS_TESTING_START;
    2148                 ASMAtomicWriteU32(&pGip->fFlags, fGipFlags);
     2139                ASMAtomicAndU32(&pGip->fFlags, ~SUPGIP_FLAGS_TESTING_START);
    21492140            }
    21502141            fUpdateCpuHz = true;
     
    21582149                ASMAtomicWriteU64(&pGip->aCPUs[0].u64CpuHz, pDevExt->uGipTestModeInvariantCpuHz);
    21592150            }
    2160             fGipFlags &= ~(SUPGIP_FLAGS_TESTING_STOP | SUPGIP_FLAGS_TESTING);
    2161             ASMAtomicWriteU32(&pGip->fFlags, fGipFlags);
    2162         }
    2163     }
    2164 
    2165     /*
    2166      * We don't need to keep realculating the frequency when it's invariant, so
    2167      * the remainder of this function is only for the sync and async TSC modes.
     2151            ASMAtomicAndU32(&pGip->fFlags, ~(SUPGIP_FLAGS_TESTING_STOP | SUPGIP_FLAGS_TESTING));
     2152        }
     2153    }
     2154
     2155    /*
     2156     * Calculate the CPU (TSC) frequency if necessary.
    21682157     */
    21692158    if (fUpdateCpuHz)
    21702159    {
     2160        uint64_t    u64CpuHz;
     2161        uint32_t    u32UpdateIntervalTSC;
     2162        uint32_t    u32UpdateIntervalTSCSlack;
     2163        uint32_t    u32TransactionId;
     2164        unsigned    iTSCHistoryHead;
     2165
    21712166        if (u64TSCDelta >> 32)
    21722167        {
     
    21982193         * Wait until we have at least one full history since the above history reset. The
    21992194         * assumption is that the majority of the previous history values will be tolerable.
    2200          * See @bugref{6710} comment #67.
     2195         * See @bugref{6710#c67}.
    22012196         */
    22022197        /** @todo Could we drop the fuding there now that we initializes the history
     
    47784773 *
    47794774 * @returns VBox status code.
     4775 * @retval  VERR_WRONG_ORDER if an enable-once-per-session flag is set again for
     4776 *          a session.
     4777 *
    47804778 * @param   pDevExt         Pointer to the device instance data.
    47814779 * @param   pSession        The support driver session.
     
    47834781 * @param   fAndMask        The AND mask of the GIP flags, see SUPGIP_FLAGS_XXX.
    47844782 *
     4783 * @remarks Caller must own the GIP mutex.
     4784 *
    47854785 * @remarks This function doesn't validate any of the flags.
    47864786 */
     
    47894789    uint32_t           cRefs;
    47904790    PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
     4791    AssertMsg((fOrMask & fAndMask) == fOrMask, ("%#x & %#x\n", fOrMask, fAndMask)); /* ASSUMED by code below */
    47914792
    47924793    /*
     
    47954796    if (fOrMask & SUPGIP_FLAGS_TESTING_ENABLE)
    47964797    {
    4797         pSession->fGipTestMode = true;
    4798         cRefs = ASMAtomicIncU32(&pDevExt->cGipTestModeRefs);
    4799         if (cRefs == 1)
    4800             fOrMask |= SUPGIP_FLAGS_TESTING | SUPGIP_FLAGS_TESTING_START;
    4801     }
    4802     else
    4803     {
    4804         cRefs = ASMAtomicDecU32(&pDevExt->cGipTestModeRefs);
     4798        if (!pSession->fGipTestMode)
     4799        {
     4800            Assert(pDevExt->cGipTestModeRefs < _64K);
     4801            pSession->fGipTestMode = true;
     4802            cRefs = ++pDevExt->cGipTestModeRefs;
     4803            if (cRefs == 1)
     4804            {
     4805                fOrMask  |= SUPGIP_FLAGS_TESTING | SUPGIP_FLAGS_TESTING_START;
     4806                fAndMask &= ~SUPGIP_FLAGS_TESTING_STOP;
     4807            }
     4808        }
     4809        else
     4810        {
     4811            LogRelMax(10, ("supdrvGipSetFlags: SUPGIP_FLAGS_TESTING_ENABLE already set for this session\n"));
     4812            return VERR_WRONG_ORDER;
     4813        }
     4814    }
     4815    else if (   !(fAndMask & SUPGIP_FLAGS_TESTING_ENABLE)
     4816             && pSession->fGipTestMode)
     4817    {
     4818        Assert(pDevExt->cGipTestModeRefs > 0);
     4819        Assert(pDevExt->cGipTestModeRefs < _64K);
    48054820        pSession->fGipTestMode = false;
     4821        cRefs = --pDevExt->cGipTestModeRefs;
    48064822        if (!cRefs)
    48074823            fOrMask |= SUPGIP_FLAGS_TESTING_STOP;
    4808     }
    4809 
    4810     /*
    4811      * Commit the flags.
    4812      */
    4813     uint32_t fFlags = ASMAtomicUoReadU32(&pGip->fFlags);
    4814     fFlags |= fOrMask;
    4815     fFlags &= fAndMask;
    4816     ASMAtomicWriteU32(&pGip->fFlags, fFlags);
     4824        else
     4825            fAndMask |= SUPGIP_FLAGS_TESTING_ENABLE;
     4826    }
     4827
     4828    /*
     4829     * Commit the flags.  This should be done as atomically as possible
     4830     * since the flag consumers won't be holding the GIP mutex.
     4831     */
     4832    ASMAtomicOrU32(&pGip->fFlags, fOrMask);
     4833    ASMAtomicAndU32(&pGip->fFlags, fAndMask);
     4834
    48174835    return VINF_SUCCESS;
    48184836}
     
    48314849{
    48324850    PSUPGLOBALINFOPAGE pGip;
     4851    int                rc;
    48334852
    48344853    /*
     
    48474866        return VERR_INVALID_PARAMETER;
    48484867
    4849     return supdrvGipSetFlags(pDevExt, pSession, fOrMask, fAndMask);
    4850 }
    4851 
     4868    /*
     4869     * Don't confuse supdrvGipSetFlags or anyone else by both setting
     4870     * and clearing the same flags.  AND takes precedence.
     4871     */
     4872    fOrMask &= fAndMask;
     4873
     4874    /*
     4875     * Take the loader lock to avoid having to think about races between two
     4876     * clients changing the flags at the same time (state is not simple).
     4877     */
     4878#ifdef SUPDRV_USE_MUTEX_FOR_GIP
     4879    RTSemMutexRequest(pDevExt->mtxGip, RT_INDEFINITE_WAIT);
     4880#else
     4881    RTSemFastMutexRequest(pDevExt->mtxGip);
     4882#endif
     4883
     4884    rc = supdrvGipSetFlags(pDevExt, pSession, fOrMask, fAndMask);
     4885
     4886#ifdef SUPDRV_USE_MUTEX_FOR_GIP
     4887    RTSemMutexRelease(pDevExt->mtxGip);
     4888#else
     4889    RTSemFastMutexRelease(pDevExt->mtxGip);
     4890#endif
     4891    return rc;
     4892}
     4893
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r57218 r57224  
    757757     *  @{ */
    758758    /** Reference counter for GIP test-mode sessions. */
    759     uint32_t volatile               cGipTestModeRefs;
     759    uint32_t                        cGipTestModeRefs;
    760760    /** Cache of TSC frequency before enabling test-mode on invariant GIP systems. */
    761761    uint64_t                        uGipTestModeInvariantCpuHz;
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