VirtualBox

Changeset 51940 in vbox for trunk/src


Ignore:
Timestamp:
Jul 8, 2014 5:45:51 PM (11 years ago)
Author:
vboxsync
Message:

GMMR0: Switched from fast mutex to critical section for the giant GMMR0 lock to avoid running into unnecessary trouble with the windows driver verifier. Required making the critical section code compile and link in the ring-0 environment.

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r51868 r51940  
    17551755        common/time/timesup.cpp \
    17561756        generic/RTAssertShouldPanic-generic.cpp \
     1757        generic/critsect-generic.cpp \
    17571758        \
    17581759        $(RuntimeNoCrt_SOURCES)
     
    19351936        generic/RTSemEventMultiWait-2-ex-generic.cpp \
    19361937        generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
     1938        generic/critsect-generic.cpp \
    19371939        generic/errvars-generic.cpp \
    19381940        generic/uuid-generic.cpp \
  • trunk/src/VBox/Runtime/generic/critsect-generic.cpp

    r48935 r51940  
    5959     */
    6060    pCritSect->u32Magic             = RTCRITSECT_MAGIC;
    61     pCritSect->fFlags               = fFlags;
     61#ifdef IN_RING0
     62    pCritSect->fFlags               = fFlags | RTCRITSECT_FLAGS_RING0;
     63#else
     64    pCritSect->fFlags               = fFlags & ~RTCRITSECT_FLAGS_RING0;
     65#endif
    6266    pCritSect->cNestings            = 0;
    6367    pCritSect->cLockers             = -1;
     
    8791    if (RT_SUCCESS(rc))
    8892    {
     93#ifdef IN_RING0
     94        rc = RTSemEventCreate(&pCritSect->EventSem);
     95
     96#else
    8997        rc = RTSemEventCreateEx(&pCritSect->EventSem,
    9098                                fFlags & RTCRITSECT_FLAGS_BOOTSTRAP_HACK
     
    93101                                NIL_RTLOCKVALCLASS,
    94102                                NULL);
     103#endif
    95104        if (RT_SUCCESS(rc))
    96105            return VINF_SUCCESS;
     106#ifdef RTCRITSECT_STRICT
    97107        RTLockValidatorRecExclDestroy(&pCritSect->pValidatorRec);
     108#endif
    98109    }
    99110
     
    108119RTDECL(uint32_t) RTCritSectSetSubClass(PRTCRITSECT pCritSect, uint32_t uSubClass)
    109120{
    110 #ifdef RTCRITSECT_STRICT
     121# ifdef RTCRITSECT_STRICT
    111122    AssertPtrReturn(pCritSect, RTLOCKVAL_SUB_CLASS_INVALID);
    112123    AssertReturn(pCritSect->u32Magic == RTCRITSECT_MAGIC, RTLOCKVAL_SUB_CLASS_INVALID);
    113124    AssertReturn(!(pCritSect->fFlags & RTCRITSECT_FLAGS_NOP), RTLOCKVAL_SUB_CLASS_INVALID);
    114125    return RTLockValidatorRecExclSetSubClass(pCritSect->pValidatorRec, uSubClass);
    115 #else
     126# else
    116127    return RTLOCKVAL_SUB_CLASS_INVALID;
    117 #endif
     128# endif
    118129}
    119130
     
    124135    Assert(pCritSect->u32Magic == RTCRITSECT_MAGIC);
    125136    /*AssertReturn(pCritSect->u32Magic == RTCRITSECT_MAGIC, VERR_SEM_DESTROYED);*/
     137#ifdef IN_RING0
     138    Assert(pCritSect->fFlags & RTCRITSECT_FLAGS_RING0);
     139#else
     140    Assert(!(pCritSect->fFlags & RTCRITSECT_FLAGS_RING0));
     141#endif
    126142
    127143    /*
     
    196212    AssertPtr(pCritSect);
    197213    AssertReturn(pCritSect->u32Magic == RTCRITSECT_MAGIC, VERR_SEM_DESTROYED);
     214#ifdef IN_RING0
     215    Assert(pCritSect->fFlags & RTCRITSECT_FLAGS_RING0);
     216#else
     217    Assert(!(pCritSect->fFlags & RTCRITSECT_FLAGS_RING0));
     218#endif
    198219
    199220    /*
     
    267288                return rc9;
    268289            }
    269 #else
     290#elif defined(IN_RING3)
    270291            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT, false);
    271292#endif
    272293            int rc = RTSemEventWait(pCritSect->EventSem, RT_INDEFINITE_WAIT);
     294#ifdef IN_RING3
    273295            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_CRITSECT);
     296#endif
    274297
    275298            if (pCritSect->u32Magic != RTCRITSECT_MAGIC)
     
    322345    Assert(pCritSect);
    323346    Assert(pCritSect->u32Magic == RTCRITSECT_MAGIC);
     347#ifdef IN_RING0
     348    Assert(pCritSect->fFlags & RTCRITSECT_FLAGS_RING0);
     349#else
     350    Assert(!(pCritSect->fFlags & RTCRITSECT_FLAGS_RING0));
     351#endif
    324352    if (pCritSect->fFlags & RTCRITSECT_FLAGS_NOP)
    325353        return VINF_SUCCESS;
     
    363391
    364392
    365 
     393#ifdef IN_RING3
    366394
    367395static int rtCritSectEnterMultiple(size_t cCritSects, PRTCRITSECT *papCritSects, PCRTLOCKVALSRCPOS pSrcPos)
     
    477505RT_EXPORT_SYMBOL(RTCritSectLeaveMultiple);
    478506
     507#endif /* IN_RING3 */
     508
     509
    479510
    480511RTDECL(int) RTCritSectDelete(PRTCRITSECT pCritSect)
     
    488519    Assert(pCritSect->cLockers == -1);
    489520    Assert(pCritSect->NativeThreadOwner == NIL_RTNATIVETHREAD);
     521#ifdef IN_RING0
     522    Assert(pCritSect->fFlags & RTCRITSECT_FLAGS_RING0);
     523#else
     524    Assert(!(pCritSect->fFlags & RTCRITSECT_FLAGS_RING0));
     525#endif
    490526
    491527    /*
     
    506542    AssertRC(rc);
    507543
     544#ifdef RTCRITSECT_STRICT
    508545    RTLockValidatorRecExclDestroy(&pCritSect->pValidatorRec);
     546#endif
    509547
    510548    return rc;
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r49789 r51940  
    165165# include <iprt/crc.h>
    166166#endif
     167#include <iprt/critsect.h>
    167168#include <iprt/list.h>
    168169#include <iprt/mem.h>
     
    172173#include <iprt/string.h>
    173174#include <iprt/time.h>
     175
     176
     177/*******************************************************************************
     178*   Defined Constants And Macros                                               *
     179*******************************************************************************/
     180/** @def VBOX_USE_CRIT_SECT_FOR_GIANT
     181 * Use a critical section instead of a fast mutex for the giant GMM lock.
     182 *
     183 * @remarks This is primarily a way of avoiding the deadlock checks in the
     184 *          windows driver verifier. */
     185#if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
     186# define VBOX_USE_CRIT_SECT_FOR_GIANT
     187#endif
    174188
    175189
     
    476490    /** The number of threads waiting on the mutex. */
    477491    uint32_t            cMtxContenders;
     492#ifdef VBOX_USE_CRIT_SECT_FOR_GIANT
     493    /** The critical section protecting the GMM.
     494     * More fine grained locking can be implemented later if necessary. */
     495    RTCRITSECT          GiantCritSect;
     496#else
    478497    /** The fast mutex protecting the GMM.
    479498     * More fine grained locking can be implemented later if necessary. */
    480499    RTSEMFASTMUTEX      hMtx;
     500#endif
    481501#ifdef VBOX_STRICT
    482502    /** The current mutex owner. */
     
    758778    ASMBitSet(&pGMM->bmChunkId[0], NIL_GMM_CHUNKID);
    759779
     780#ifdef VBOX_USE_CRIT_SECT_FOR_GIANT
     781    int rc = RTCritSectInit(&pGMM->GiantCritSect);
     782#else
    760783    int rc = RTSemFastMutexCreate(&pGMM->hMtx);
     784#endif
    761785    if (RT_SUCCESS(rc))
    762786    {
     
    816840        while (iMtx-- > 0)
    817841            RTSemFastMutexDestroy(pGMM->aChunkMtx[iMtx].hMtx);
     842#ifdef VBOX_USE_CRIT_SECT_FOR_GIANT
     843        RTCritSectDelete(&pGMM->GiantCritSect);
     844#else
    818845        RTSemFastMutexDestroy(pGMM->hMtx);
     846#endif
    819847    }
    820848
     
    851879    g_pGMM = NULL;
    852880    pGMM->u32Magic    = ~GMM_MAGIC;
     881#ifdef VBOX_USE_CRIT_SECT_FOR_GIANT
     882    RTCritSectDelete(&pGMM->GiantCritSect);
     883#else
    853884    RTSemFastMutexDestroy(pGMM->hMtx);
    854885    pGMM->hMtx        = NIL_RTSEMFASTMUTEX;
     886#endif
    855887
    856888    /* Free any chunks still hanging around. */
     
    933965{
    934966    ASMAtomicIncU32(&pGMM->cMtxContenders);
     967#ifdef VBOX_USE_CRIT_SECT_FOR_GIANT
     968    int rc = RTCritSectEnter(&pGMM->GiantCritSect);
     969#else
    935970    int rc = RTSemFastMutexRequest(pGMM->hMtx);
     971#endif
    936972    ASMAtomicDecU32(&pGMM->cMtxContenders);
    937973    AssertRC(rc);
     
    954990    pGMM->hMtxOwner = NIL_RTNATIVETHREAD;
    955991#endif
     992#ifdef VBOX_USE_CRIT_SECT_FOR_GIANT
     993    int rc = RTCritSectLeave(&pGMM->GiantCritSect);
     994#else
    956995    int rc = RTSemFastMutexRelease(pGMM->hMtx);
    957996    AssertRC(rc);
     997#endif
    958998    return rc;
    959999}
     
    9911031#endif
    9921032    ASMAtomicIncU32(&pGMM->cMtxContenders);
     1033#ifdef VBOX_USE_CRIT_SECT_FOR_GIANT
     1034    int rc1 = RTCritSectLeave(&pGMM->GiantCritSect); AssertRC(rc1);
     1035#else
    9931036    int rc1 = RTSemFastMutexRelease(pGMM->hMtx); AssertRC(rc1);
     1037#endif
    9941038
    9951039    RTThreadYield();
    9961040
     1041#ifdef VBOX_USE_CRIT_SECT_FOR_GIANT
     1042    int rc2 = RTCritSectEnter(&pGMM->GiantCritSect); AssertRC(rc2);
     1043#else
    9971044    int rc2 = RTSemFastMutexRequest(pGMM->hMtx); AssertRC(rc2);
     1045#endif
    9981046    *puLockNanoTS = RTTimeSystemNanoTS();
    9991047    ASMAtomicDecU32(&pGMM->cMtxContenders);
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