VirtualBox

Changeset 87812 in vbox for trunk/src/VBox/VMM/include


Ignore:
Timestamp:
Feb 19, 2021 8:54:49 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142873
Message:

VMM/TM: Replaced the global timer active list lock with per queue locks. bugref:9943

Location:
trunk/src/VBox/VMM/include
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/include/TMInline.h

    r87792 r87812  
    163163}
    164164
     165/** @def TMTIMER_HANDLE_TO_VARS_RETURN_EX
     166 * Converts a timer handle to a timer pointer, returning @a a_rcRet if the
     167 * handle is invalid.
     168 *
     169 * This defines the following variables:
     170 *      - idxQueue: The queue index.
     171 *      - pQueueCC: Pointer to the context specific queue data.
     172 *      - pTimer:   The timer pointer.
     173 *      - idxTimer: The timer index.
     174 *
     175 * @param   a_pVM           The cross context VM structure.
     176 * @param   a_hTimer        The timer handle to translate.
     177 * @param   a_rcRet         What to return on failure.
     178 *
     179 * @note    This macro has no scoping, so careful when using it around
     180 *          conditional statements!
     181 */
     182#ifdef IN_RING3
     183# define TMTIMER_HANDLE_TO_VARS_RETURN_EX(a_pVM, a_hTimer, a_rcRet) \
     184        uintptr_t const idxQueue = (uintptr_t)((a_hTimer) >> TMTIMERHANDLE_QUEUE_IDX_SHIFT) \
     185                                 & (uintptr_t)TMTIMERHANDLE_QUEUE_IDX_SMASK; \
     186        AssertReturn(idxQueue < RT_ELEMENTS((a_pVM)->tm.s.aTimerQueues), a_rcRet); \
     187        PTMTIMERQUEUE const pQueue = &(a_pVM)->tm.s.aTimerQueues[idxQueue]; \
     188        PTMTIMERQUEUE const pQueueCC = pQueue; RT_NOREF(pQueueCC); \
     189        \
     190        uintptr_t const idxTimer = (uintptr_t)((a_hTimer) & TMTIMERHANDLE_TIMER_IDX_MASK); \
     191        AssertReturn(idxQueue < pQueue->cTimersAlloc, a_rcRet); \
     192        \
     193        PTMTIMER const pTimer = &pQueue->paTimers[idxTimer]; \
     194        AssertReturn(pTimer->hSelf == a_hTimer, a_rcRet)
     195#else
     196# define TMTIMER_HANDLE_TO_VARS_RETURN_EX(a_pVM, a_hTimer, a_rcRet) \
     197        uintptr_t const idxQueue = (uintptr_t)((a_hTimer) >> TMTIMERHANDLE_QUEUE_IDX_SHIFT) \
     198                                 & (uintptr_t)TMTIMERHANDLE_QUEUE_IDX_SMASK; \
     199        AssertReturn(idxQueue < RT_ELEMENTS((a_pVM)->tm.s.aTimerQueues), a_rcRet); \
     200        AssertCompile(RT_ELEMENTS((a_pVM)->tm.s.aTimerQueues) == RT_ELEMENTS((a_pVM)->tmr0.s.aTimerQueues)); \
     201        PTMTIMERQUEUE const   pQueue   = &(a_pVM)->tm.s.aTimerQueues[idxQueue]; RT_NOREF(pQueue); \
     202        PTMTIMERQUEUER0 const pQueueCC = &(a_pVM)->tmr0.s.aTimerQueues[idxQueue]; \
     203        \
     204        uintptr_t const idxTimer = (uintptr_t)((a_hTimer) & TMTIMERHANDLE_TIMER_IDX_MASK); \
     205        AssertReturn(idxQueue < pQueueCC->cTimersAlloc, a_rcRet); \
     206        \
     207        PTMTIMER const pTimer = &pQueueCC->paTimers[idxTimer]; \
     208        AssertReturn(pTimer->hSelf == a_hTimer, a_rcRet); \
     209        Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0); \
     210        Assert(VM_IS_EMT(pVM))
     211#endif
     212
     213
     214/** @def TMTIMER_HANDLE_TO_VARS_RETURN_EX
     215 * Converts a timer handle to a timer pointer, returning VERR_INVALID_HANDLE if
     216 * the handle is invalid.
     217 *
     218 * This defines the following variables:
     219 *      - idxQueue: The queue index.
     220 *      - pQueueCC: Pointer to the context specific queue data.
     221 *      - pTimer:   The timer pointer.
     222 *      - idxTimer: The timer index.
     223 *
     224 * @param   a_pVM       The cross context VM structure.
     225 * @param   a_hTimer    The timer handle to translate.
     226 *
     227 * @note    This macro has no scoping, so careful when using it around
     228 *          conditional statements!
     229 */
     230#define TMTIMER_HANDLE_TO_VARS_RETURN(a_pVM, a_hTimer) TMTIMER_HANDLE_TO_VARS_RETURN_EX(a_pVM, a_hTimer, VERR_INVALID_HANDLE)
     231
    165232
    166233/** @def TMTIMER_HANDLE_TO_PTR_RETURN_EX
  • trunk/src/VBox/VMM/include/TMInternal.h

    r87794 r87812  
    284284    bool                    fCannotGrow;
    285285    /** Align on 64-byte boundrary. */
    286     bool                    afAlignment[7];
    287     /** Lock serializing timer allocation and deallocation. */
     286    bool                    afAlignment1[7];
     287    /** Time spent doing scheduling and timer callbacks. */
     288    STAMPROFILE             StatDo;
     289    /** The current max timer Hz hint. */
     290    uint32_t volatile       uMaxHzHint;
     291    uint32_t                u64Alignment2[7];
     292    /** Lock serializing the active timer list and associated work. */
     293    PDMCRITSECT             TimerLock;
     294    /** Lock serializing timer allocation and deallocation.
     295     * @note This may be used in read-mode all over the place if we later
     296     *       implement runtime array growing. */
    288297    PDMCRITSECTRW           AllocLock;
    289298} TMTIMERQUEUE;
     
    391400typedef struct TM
    392401{
     402    /** Timer queues for the different clock types.
     403     * @note is first in the structure to ensure cache-line alignment.  */
     404    TMTIMERQUEUE                aTimerQueues[TMCLOCK_MAX];
     405
    393406    /** The current TSC mode of the VM.
    394407     *  Config variable: Mode (string). */
     
    496509    }                           aVirtualSyncCatchUpPeriods[TM_MAX_CATCHUP_PERIODS];
    497510
    498     /** The current max timer Hz hint. */
    499     uint32_t volatile           uMaxHzHint;
    500     /** Whether to recalulate the HzHint next time its queried. */
    501     bool volatile               fHzHintNeedsUpdating;
    502     /** Alignment */
    503     bool                        afAlignment2[3];
     511    union
     512    {
     513        /** Combined value for updating. */
     514        uint64_t volatile       u64Combined;
     515        struct
     516        {
     517            /** Bitmap indicating which timer queues needs their uMaxHzHint updated. */
     518            uint32_t volatile   bmNeedsUpdating;
     519            /** The current max timer Hz hint. */
     520            uint32_t volatile   uMax;
     521        } s;
     522    } HzHint;
    504523    /** @cfgm{/TM/HostHzMax, uint32_t, Hz, 0, UINT32_MAX, 20000}
    505524     * The max host Hz frequency hint returned by TMCalcHostTimerFrequency.  */
     
    537556    R3PTRTYPE(char *)           pszAlignment2b;
    538557
    539     /** Timer queues for the different clock types. */
    540     TMTIMERQUEUE                aTimerQueues[TMCLOCK_MAX];
    541 
    542558    /** Pointer to our RC mapping of the GIP. */
    543559    RCPTRTYPE(void *)           pvGIPRC;
    544560    /** Pointer to our R3 mapping of the GIP. */
    545561    R3PTRTYPE(void *)           pvGIPR3;
     562
    546563
    547564    /** The schedule timer timer handle (runtime timer).
     
    560577    bool                        afAlignment3[2];
    561578
    562     /** Lock serializing access to the timer lists. */
    563     PDMCRITSECT                 TimerCritSect;
    564579    /** Lock serializing access to the VirtualSync clock and the associated
    565580     * timer queue. */
     
    572587     * @{ */
    573588    STAMPROFILE                 StatDoQueues;
    574     STAMPROFILEADV              aStatDoQueues[TMCLOCK_MAX];
    575589    /** @} */
    576590    /** tmSchedule
     
    836850DECLCALLBACK(DECLEXPORT(uint64_t))  tmVirtualNanoTSRediscover(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
    837851DECLCALLBACK(DECLEXPORT(uint64_t))  tmVirtualNanoTSBadCpuIndex(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra,
    838                                                                uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu);
    839 
    840 /**
    841  * Try take the timer lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC.
    842  *
    843  * @retval  VINF_SUCCESS on success (always in ring-3).
    844  * @retval  VERR_SEM_BUSY in RC and R0 if the semaphore is busy.
    845  *
    846  * @param   a_pVM       Pointer to the VM.
    847  *
    848  * @remarks The virtual sync timer queue requires the virtual sync lock.
    849  */
    850 #define TM_LOCK_TIMERS(a_pVM)       PDMCritSectEnter(&(a_pVM)->tm.s.TimerCritSect, VERR_SEM_BUSY)
    851 
    852 /**
    853  * Try take the timer lock, no waiting.
    854  *
    855  * @retval  VINF_SUCCESS on success.
    856  * @retval  VERR_SEM_BUSY if busy.
    857  *
    858  * @param   a_pVM       Pointer to the VM.
    859  *
    860  * @remarks The virtual sync timer queue requires the virtual sync lock.
    861  */
    862 #define TM_TRY_LOCK_TIMERS(a_pVM)   PDMCritSectTryEnter(&(a_pVM)->tm.s.TimerCritSect)
    863 
    864 /** Lock the timers (sans the virtual sync queue). */
    865 #define TM_UNLOCK_TIMERS(a_pVM)     do { PDMCritSectLeave(&(a_pVM)->tm.s.TimerCritSect); } while (0)
    866 
    867 /** Checks that the caller owns the timer lock.  */
    868 #define TM_ASSERT_TIMER_LOCK_OWNERSHIP(a_pVM) \
    869     Assert(PDMCritSectIsOwner(&(a_pVM)->tm.s.TimerCritSect))
    870 
     852                                                              uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu);
    871853/** @} */
    872854
     
    874856
    875857#endif /* !VMM_INCLUDED_SRC_include_TMInternal_h */
    876 
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