VirtualBox

Changeset 90956 in vbox for trunk/src/VBox/VMM/VMMR0


Ignore:
Timestamp:
Aug 27, 2021 1:30:51 PM (3 years ago)
Author:
vboxsync
Message:

VMM: Preparing for using more than one log buffer per ring-0 EMT logger. bugref:10086

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r90953 r90956  
    29882988        pGVM->vmmr0.s.LogFlusher.idxRingHead = (idxHead + 1) % RT_ELEMENTS(pGVM->vmmr0.s.LogFlusher.aRing);
    29892989
    2990         /* Do the waking up. */
    2991         if (   idCpu < pGVM->cCpus
     2990        /* Do the accounting and waking up. */
     2991        if (   idCpu     < pGVM->cCpus
    29922992            && idxLogger < VMMLOGGER_IDX_MAX
    2993             && idxBuffer < 1)
    2994         {
    2995             PGVMCPU             pGVCpu = &pGVM->aCpus[idCpu];
    2996             PVMMR0PERVCPULOGGER pR0Log = &pGVCpu->vmmr0.s.u.aLoggers[idxLogger];
     2993            && idxBuffer < VMMLOGGER_BUFFER_COUNT)
     2994        {
     2995            PGVMCPU             pGVCpu  = &pGVM->aCpus[idCpu];
     2996            PVMMR0PERVCPULOGGER pR0Log  = &pGVCpu->vmmr0.s.u.aLoggers[idxLogger];
     2997            PVMMR3CPULOGGER     pShared = &pGVCpu->vmm.s.u.aLoggers[idxLogger];
     2998
    29972999            pR0Log->fFlushDone = true;
     3000
     3001            uint32_t cFlushing = pR0Log->cFlushing - 1;
     3002            if (RT_LIKELY(cFlushing < VMMLOGGER_BUFFER_COUNT))
     3003            { /*likely*/ }
     3004            else
     3005                cFlushing = 0;
     3006            pR0Log->cFlushing = cFlushing;
     3007            ASMAtomicWriteU32(&pShared->cFlushing, cFlushing);
    29983008
    29993009            RTSpinlockRelease(pGVM->vmmr0.s.LogFlusher.hSpinlock);
     
    31053115                    && RT_VALID_PTR(pGVM))
    31063116                {
    3107                     PVMMR0PERVCPULOGGER const pR0Log  = &pGVCpu->vmmr0.s.u.aLoggers[idxLogger];
    3108                     PVMMR3CPULOGGER const     pShared = &pGVCpu->vmm.s.u.aLoggers[idxLogger];
    3109 
    3110                     /*
    3111                      * Can we wait on the log flusher to do the work?
    3112                      */
    3113                     if (VMMRZCallRing3IsEnabled(pGVCpu))
     3117                    PVMMR0PERVCPULOGGER const pR0Log    = &pGVCpu->vmmr0.s.u.aLoggers[idxLogger];
     3118                    PVMMR3CPULOGGER const     pShared   = &pGVCpu->vmm.s.u.aLoggers[idxLogger];
     3119                    size_t const              idxBuffer = pBufDesc - &pR0Log->aBufDescs[0];
     3120                    if (idxBuffer < RT_ELEMENTS(pR0Log->aBufDescs))
    31143121                    {
    31153122                        /*
    3116                          * Make sure we don't recurse forever here should something in the
    3117                          * following code trigger logging or an assertion.
     3123                         * Can we wait on the log flusher to do the work?
    31183124                         */
    3119                         if (!pR0Log->fFlushing)
     3125                        if (VMMRZCallRing3IsEnabled(pGVCpu))
    31203126                        {
    3121                             pR0Log->fFlushing = true;
    3122 
    31233127                            /*
    3124                              * Prepare to block waiting for the flusher thread.
     3128                             * Make sure we don't recurse forever here should something in the
     3129                             * following code trigger logging or an assertion.
    31253130                             */
    3126                             VMMR0EMTBLOCKCTX Ctx;
    3127                             int rc = VMMR0EmtPrepareToBlock(pGVCpu, VINF_SUCCESS, "vmmR0LoggerFlushCommon",
    3128                                                             pR0Log->hEventFlushWait, &Ctx);
    3129                             if (RT_SUCCESS(rc))
     3131                            if (!pR0Log->fFlushing)
    31303132                            {
     3133                                pR0Log->fFlushing = true;
     3134
    31313135                                /*
    3132                                  * Queue the flush job.
     3136                                 * Prepare to block waiting for the flusher thread.
    31333137                                 */
    3134                                 RTSpinlockAcquire(pGVM->vmmr0.s.LogFlusher.hSpinlock);
    3135                                 if (pGVM->vmmr0.s.LogFlusher.fThreadRunning)
     3138                                VMMR0EMTBLOCKCTX Ctx;
     3139                                int rc = VMMR0EmtPrepareToBlock(pGVCpu, VINF_SUCCESS, "vmmR0LoggerFlushCommon",
     3140                                                                pR0Log->hEventFlushWait, &Ctx);
     3141                                if (RT_SUCCESS(rc))
    31363142                                {
    3137                                     uint32_t const idxHead    = pGVM->vmmr0.s.LogFlusher.idxRingHead
    3138                                                               % RT_ELEMENTS(pGVM->vmmr0.s.LogFlusher.aRing);
    3139                                     uint32_t const idxTail    = pGVM->vmmr0.s.LogFlusher.idxRingTail
    3140                                                               % RT_ELEMENTS(pGVM->vmmr0.s.LogFlusher.aRing);
    3141                                     uint32_t const idxNewTail = (idxTail + 1)
    3142                                                               % RT_ELEMENTS(pGVM->vmmr0.s.LogFlusher.aRing);
    3143                                     if (idxNewTail != idxHead)
     3143                                    /*
     3144                                     * Queue the flush job.
     3145                                     */
     3146                                    RTSpinlockAcquire(pGVM->vmmr0.s.LogFlusher.hSpinlock);
     3147                                    if (pGVM->vmmr0.s.LogFlusher.fThreadRunning)
    31443148                                    {
    3145                                         pGVM->vmmr0.s.LogFlusher.aRing[idxTail].s.idCpu       = pGVCpu->idCpu;
    3146                                         pGVM->vmmr0.s.LogFlusher.aRing[idxTail].s.idxLogger   = idxLogger;
    3147                                         pGVM->vmmr0.s.LogFlusher.aRing[idxTail].s.idxBuffer   = 0;
    3148                                         pGVM->vmmr0.s.LogFlusher.aRing[idxTail].s.fProcessing = 0;
    3149                                         pGVM->vmmr0.s.LogFlusher.idxRingTail = idxNewTail;
    3150 
    3151                                         if (pGVM->vmmr0.s.LogFlusher.fThreadWaiting)
     3149                                        uint32_t const idxHead    = pGVM->vmmr0.s.LogFlusher.idxRingHead
     3150                                                                  % RT_ELEMENTS(pGVM->vmmr0.s.LogFlusher.aRing);
     3151                                        uint32_t const idxTail    = pGVM->vmmr0.s.LogFlusher.idxRingTail
     3152                                                                  % RT_ELEMENTS(pGVM->vmmr0.s.LogFlusher.aRing);
     3153                                        uint32_t const idxNewTail = (idxTail + 1)
     3154                                                                  % RT_ELEMENTS(pGVM->vmmr0.s.LogFlusher.aRing);
     3155                                        if (idxNewTail != idxHead)
     3156                                        {
     3157                                            pGVM->vmmr0.s.LogFlusher.aRing[idxTail].s.idCpu       = pGVCpu->idCpu;
     3158                                            pGVM->vmmr0.s.LogFlusher.aRing[idxTail].s.idxLogger   = idxLogger;
     3159                                            pGVM->vmmr0.s.LogFlusher.aRing[idxTail].s.idxBuffer   = (uint32_t)idxBuffer;
     3160                                            pGVM->vmmr0.s.LogFlusher.aRing[idxTail].s.fProcessing = 0;
     3161                                            pGVM->vmmr0.s.LogFlusher.idxRingTail = idxNewTail;
     3162
     3163                                            pShared->cFlushing = pR0Log->cFlushing = RT_MIN(pR0Log->cFlushing + 1,
     3164                                                                                            VMMLOGGER_BUFFER_COUNT);
     3165
     3166                                            if (pGVM->vmmr0.s.LogFlusher.fThreadWaiting)
     3167                                            {
     3168                                                RTSpinlockRelease(pGVM->vmmr0.s.LogFlusher.hSpinlock);
     3169                                                RTSemEventSignal(pGVM->vmmr0.s.LogFlusher.hEvent);
     3170                                            }
     3171                                            else
     3172                                                RTSpinlockRelease(pGVM->vmmr0.s.LogFlusher.hSpinlock);
     3173
     3174                                            /*
     3175                                             * Wait for it to complete.
     3176                                             */
     3177                                            VMMR0EmtWaitEventInner(pGVCpu, VMMR0EMTWAIT_F_TRY_SUPPRESS_INTERRUPTED,
     3178                                                                   pR0Log->hEventFlushWait, RT_INDEFINITE_WAIT);
     3179                                        }
     3180                                        else
    31523181                                        {
    31533182                                            RTSpinlockRelease(pGVM->vmmr0.s.LogFlusher.hSpinlock);
    3154                                             RTSemEventSignal(pGVM->vmmr0.s.LogFlusher.hEvent);
     3183                                            SUP_DPRINTF(("vmmR0LoggerFlush: ring buffer is full!\n"));
    31553184                                        }
    3156                                         else
    3157                                             RTSpinlockRelease(pGVM->vmmr0.s.LogFlusher.hSpinlock);
    3158 
    3159                                         /*
    3160                                          * Wait for it to complete.
    3161                                          */
    3162                                         VMMR0EmtWaitEventInner(pGVCpu, VMMR0EMTWAIT_F_TRY_SUPPRESS_INTERRUPTED,
    3163                                                                pR0Log->hEventFlushWait, RT_INDEFINITE_WAIT);
    31643185                                    }
    31653186                                    else
    31663187                                    {
    31673188                                        RTSpinlockRelease(pGVM->vmmr0.s.LogFlusher.hSpinlock);
    3168                                         SUP_DPRINTF(("vmmR0LoggerFlush: ring buffer is full!\n"));
     3189                                        SUP_DPRINTF(("vmmR0LoggerFlush: flusher not active - dropping %u bytes\n",
     3190                                                     pBufDesc->offBuf));
    31693191                                    }
     3192                                    VMMR0EmtResumeAfterBlocking(pGVCpu, &Ctx);
    31703193                                }
    31713194                                else
    3172                                 {
    3173                                     RTSpinlockRelease(pGVM->vmmr0.s.LogFlusher.hSpinlock);
    3174                                     SUP_DPRINTF(("vmmR0LoggerFlush: flusher not active - dropping %u bytes\n",
    3175                                                  pBufDesc->offBuf));
    3176                                 }
    3177                                 VMMR0EmtResumeAfterBlocking(pGVCpu, &Ctx);
     3195                                    SUP_DPRINTF(("vmmR0LoggerFlush: VMMR0EmtPrepareToBlock failed! rc=%d\n", rc));
     3196                                pR0Log->fFlushing = false;
    31783197                            }
    31793198                            else
    3180                                 SUP_DPRINTF(("vmmR0LoggerFlush: VMMR0EmtPrepareToBlock failed! rc=%d\n", rc));
    3181                             pR0Log->fFlushing = false;
     3199                                SUP_DPRINTF(("vmmR0LoggerFlush: Recursive flushing!\n"));
    31823200                        }
    31833201                        else
    3184                             SUP_DPRINTF(("vmmR0LoggerFlush: Recursive flushing!\n"));
     3202                        {
     3203#if defined(RT_OS_LINUX)
     3204                            SUP_DPRINTF(("vmmR0LoggerFlush: EMT blocking disabled! (%u bytes)\n", pBufDesc->offBuf));
     3205#endif
     3206                            pShared->cbDropped += pBufDesc->offBuf;
     3207                        }
    31853208                    }
    31863209                    else
    3187                     {
    3188 #if defined(RT_OS_LINUX)
    3189                         SUP_DPRINTF(("vmmR0LoggerFlush: EMT blocking disabled! (%u bytes)\n", pBufDesc->offBuf));
    3190 #endif
    3191                         pShared->cbDropped += pBufDesc->offBuf;
    3192                     }
     3210                        SUP_DPRINTF(("vmmR0LoggerFlush: pLogger=%p pGVCpu=%p: idxBuffer=%#zx\n", pLogger, pGVCpu, idxBuffer));
    31933211                }
    31943212                else
     
    33073325     * Create and configure the logger.
    33083326     */
    3309     pR0Log->BufDesc.u32Magic    = RTLOGBUFFERDESC_MAGIC;
    3310     pR0Log->BufDesc.uReserved   = 0;
    3311     pR0Log->BufDesc.cbBuf       = cbBuf;
    3312     pR0Log->BufDesc.offBuf      = 0;
    3313     pR0Log->BufDesc.pchBuf      = pchBuf;
    3314     pR0Log->BufDesc.pAux        = &pShared->AuxDesc;
    3315 
    3316     pShared->AuxDesc.fFlushedIndicator   = false;
    3317     pShared->AuxDesc.afPadding[0]        = 0;
    3318     pShared->AuxDesc.afPadding[1]        = 0;
    3319     pShared->AuxDesc.afPadding[2]        = 0;
    3320     pShared->AuxDesc.offBuf              = 0;
    3321     pShared->pchBufR3                    = pchBufR3;
    3322     pShared->cbBuf                       = cbBuf;
     3327    for (size_t i = 0; i < VMMLOGGER_BUFFER_COUNT; i++)
     3328    {
     3329        pR0Log->aBufDescs[i].u32Magic    = RTLOGBUFFERDESC_MAGIC;
     3330        pR0Log->aBufDescs[i].uReserved   = 0;
     3331        pR0Log->aBufDescs[i].cbBuf       = cbBuf;
     3332        pR0Log->aBufDescs[i].offBuf      = 0;
     3333        pR0Log->aBufDescs[i].pchBuf      = pchBuf + i * cbBuf;
     3334        pR0Log->aBufDescs[i].pAux        = &pShared->aBufs[i].AuxDesc;
     3335
     3336        pShared->aBufs[i].AuxDesc.fFlushedIndicator   = false;
     3337        pShared->aBufs[i].AuxDesc.afPadding[0]        = 0;
     3338        pShared->aBufs[i].AuxDesc.afPadding[1]        = 0;
     3339        pShared->aBufs[i].AuxDesc.afPadding[2]        = 0;
     3340        pShared->aBufs[i].AuxDesc.offBuf              = 0;
     3341        pShared->aBufs[i].pchBufR3                    = pchBufR3 + i * cbBuf;
     3342    }
     3343    pShared->cbBuf = cbBuf;
    33233344
    33243345    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
    33253346    int rc = RTLogCreateEx(&pR0Log->pLogger, fRelease ? "VBOX_RELEASE_LOG" : "VBOX_LOG", RTLOG_F_NO_LOCKING | RTLOGFLAGS_BUFFERED,
    33263347                           "all", RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX,
    3327                            1 /*cBufDescs*/, &pR0Log->BufDesc, RTLOGDEST_DUMMY,
     3348                           VMMLOGGER_BUFFER_COUNT, pR0Log->aBufDescs, RTLOGDEST_DUMMY,
    33283349                           NULL /*pfnPhase*/, 0 /*cHistory*/, 0 /*cbHistoryFileMax*/, 0 /*cSecsHistoryTimeSlot*/,
    33293350                           NULL /*pErrInfo*/, NULL /*pszFilenameFmt*/);
     
    33613382{
    33623383    RTLogDestroy(pR0Log->pLogger);
    3363     pR0Log->pLogger   = NULL;
    3364     pShared->pchBufR3 = NIL_RTR3PTR;
     3384    pR0Log->pLogger = NULL;
     3385
     3386    for (size_t i = 0; i < VMMLOGGER_BUFFER_COUNT; i++)
     3387        pShared->aBufs[i].pchBufR3 = NIL_RTR3PTR;
    33653388
    33663389    RTSemEventDestroy(pR0Log->hEventFlushWait);
     
    33753398{
    33763399    /* Allocate buffers first. */
    3377     int rc = RTR0MemObjAllocPage(phMemObj, cbBuf * pGVM->cCpus, false /*fExecutable*/);
     3400    int rc = RTR0MemObjAllocPage(phMemObj, cbBuf * pGVM->cCpus * VMMLOGGER_BUFFER_COUNT, false /*fExecutable*/);
    33783401    if (RT_SUCCESS(rc))
    33793402    {
     
    33943417                PVMMR3CPULOGGER     pShared = &pGVCpu->vmm.s.u.aLoggers[idxLogger];
    33953418                rc = vmmR0InitLoggerOne(pGVCpu, idxLogger == VMMLOGGER_IDX_RELEASE, pR0Log, pShared, cbBuf,
    3396                                         pchBuf + i * cbBuf, pchBufR3 + i * cbBuf);
     3419                                        pchBuf   + i * cbBuf * VMMLOGGER_BUFFER_COUNT,
     3420                                        pchBufR3 + i * cbBuf * VMMLOGGER_BUFFER_COUNT);
    33973421                if (RT_FAILURE(rc))
    33983422                {
    3399                     pR0Log->pLogger   = NULL;
    3400                     pShared->pchBufR3 = NIL_RTR3PTR;
     3423                    vmmR0TermLoggerOne(pR0Log, pShared);
    34013424                    while (i-- > 0)
    34023425                    {
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