VirtualBox

Changeset 90381 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Jul 28, 2021 9:58:54 PM (4 years ago)
Author:
vboxsync
Message:

VMM/PDMCritSect: Don't sleep forever. bugref:6695

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp

    r90379 r90381  
    129129 * @param   hNativeSelf         The native thread handle.
    130130 * @param   pSrcPos             The source position of the lock operation.
    131  */
    132 static int pdmR3R0CritSectEnterContended(PVMCC pVM, PPDMCRITSECT pCritSect, RTNATIVETHREAD hNativeSelf, PCRTLOCKVALSRCPOS pSrcPos)
     131 * @param   rcBusy              The status code to return when we're in RC or R0
     132 */
     133static int pdmR3R0CritSectEnterContended(PVMCC pVM, PPDMCRITSECT pCritSect, RTNATIVETHREAD hNativeSelf,
     134                                         PCRTLOCKVALSRCPOS pSrcPos, int rcBusy)
    133135{
    134136    /*
     
    169171         * been signalled and the interruptible wait function returning
    170172         * immediately.  In that case we do normal R0/RC rcBusy handling.
     173         *
     174         * We always do a timed wait here, so the event handle is revalidated
     175         * regularly and we won't end up stuck waiting for a destroyed critsect.
    171176         */
     177        /** @todo Make SUPSemEventClose wake up all waiters. */
    172178# ifdef IN_RING3
    173179#  ifdef PDMCRITSECT_STRICT
     
    180186        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT, true);
    181187#  endif
    182         int rc = SUPSemEventWaitNoResume(pSession, hEvent, RT_INDEFINITE_WAIT);
     188        int rc = SUPSemEventWaitNoResume(pSession, hEvent, RT_MS_5SEC);
    183189        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_CRITSECT);
    184190# else  /* IN_RING0 */
    185         int rc = SUPSemEventWaitNoResume(pSession, hEvent, RT_INDEFINITE_WAIT);
     191        int rc = SUPSemEventWaitNoResume(pSession, hEvent, RT_MS_5SEC);
    186192# endif /* IN_RING0 */
    187193
     
    189195         * Deal with the return code and critsect destruction.
    190196         */
    191         if (RT_UNLIKELY(pCritSect->s.Core.u32Magic != RTCRITSECT_MAGIC))
     197        if (RT_LIKELY(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC))
     198        { /* likely */ }
     199        else
    192200            return VERR_SEM_DESTROYED;
    193201        if (rc == VINF_SUCCESS)
    194202            return pdmCritSectEnterFirst(pCritSect, hNativeSelf, pSrcPos);
    195         AssertMsg(rc == VERR_INTERRUPTED, ("rc=%Rrc\n", rc));
     203        if (RT_LIKELY(rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED))
     204        { /* likely */ }
     205        else
     206        {
     207            AssertMsgFailed(("rc=%Rrc\n", rc));
     208            return rc;
     209        }
    196210
    197211# ifdef IN_RING0
     
    202216                 it without creating a race with PDMCritSectLeave, resulting in
    203217                 spurious wakeups. */
     218        RT_NOREF(rcBusy);
     219        /** @todo eliminate this and return rcBusy instead.  Guru if
     220         *        rcBusy is VINF_SUCCESS. */
    204221        PVMCPUCC pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu);
    205222        rc = VMMRZCallRing3(pVM, pVCpu, VMMCALLRING3_VM_R0_PREEMPT, NULL);
    206223        AssertRC(rc);
    207224# else
    208         RT_NOREF(pVM);
     225        RT_NOREF(pVM, rcBusy);
    209226# endif
    210227    }
     
    218235 *
    219236 * @returns VINF_SUCCESS if entered successfully.
    220  * @returns rcBusy when encountering a busy critical section in GC/R0.
     237 * @returns rcBusy when encountering a busy critical section in RC/R0.
    221238 * @retval  VERR_SEM_DESTROYED if the critical section is delete before or
    222239 *          during the operation.
     
    224241 * @param   pVM                 The cross context VM structure.
    225242 * @param   pCritSect           The PDM critical section to enter.
    226  * @param   rcBusy              The status code to return when we're in GC or R0
     243 * @param   rcBusy              The status code to return when we're in RC or R0
    227244 * @param   pSrcPos             The source position of the lock operation.
    228245 */
     
    290307     */
    291308    NOREF(rcBusy);
    292     return pdmR3R0CritSectEnterContended(pVM, pCritSect, hNativeSelf, pSrcPos);
     309    return pdmR3R0CritSectEnterContended(pVM, pCritSect, hNativeSelf, pSrcPos, rcBusy);
    293310
    294311#elif defined(IN_RING0)
     
    314331            Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD));
    315332
    316             rc = pdmR3R0CritSectEnterContended(pVM, pCritSect, hNativeSelf, pSrcPos);
     333            rc = pdmR3R0CritSectEnterContended(pVM, pCritSect, hNativeSelf, pSrcPos, rcBusy);
    317334
    318335            VMMR0EmtResumeAfterBlocking(pVCpu, &Ctx);
     
    325342    /* Non-EMT. */
    326343    Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD));
    327     return pdmR3R0CritSectEnterContended(pVM, pCritSect, hNativeSelf, pSrcPos);
     344    return pdmR3R0CritSectEnterContended(pVM, pCritSect, hNativeSelf, pSrcPos, rcBusy);
    328345
    329346# else /* old code: */
     
    333350    if (   RTThreadPreemptIsEnabled(NIL_RTTHREAD)
    334351        && ASMIntAreEnabled())
    335         return pdmR3R0CritSectEnterContended(pVM, pCritSect, hNativeSelf, pSrcPos);
     352        return pdmR3R0CritSectEnterContended(pVM, pCritSect, hNativeSelf, pSrcPos, rcBusy);
    336353
    337354    STAM_REL_COUNTER_INC(&pCritSect->s.StatContentionRZLock);
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