VirtualBox

Changeset 92712 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Dec 2, 2021 5:34:24 PM (3 years ago)
Author:
vboxsync
Message:

VMM/TM: Made timer allocation work in driverless mode. bugref:10138

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r92709 r92712  
    152152#include <iprt/file.h>
    153153#include <iprt/getopt.h>
     154#include <iprt/mem.h>
    154155#include <iprt/rand.h>
    155156#include <iprt/semaphore.h>
     
    15241525
    15251526/**
     1527 * Grows a timer queue.
     1528 *
     1529 * @returns VBox status code (errors are LogRel'ed already).
     1530 * @param   pVM         The cross context VM structure.
     1531 * @param   pQueue      The timer queue to grow.
     1532 * @note    Caller owns the queue's allocation lock.
     1533 */
     1534static int tmR3TimerQueueGrow(PVM pVM, PTMTIMERQUEUE pQueue)
     1535{
     1536    /*
     1537     * Validate input and state.
     1538     */
     1539    VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
     1540    VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE); /** @todo must do better than this! */
     1541    AssertReturn(!pQueue->fCannotGrow, VERR_TM_TIMER_QUEUE_CANNOT_GROW);
     1542
     1543    /*
     1544     * Do the growing.
     1545     */
     1546    int rc;
     1547    uint32_t const cOldEntries = pQueue->cTimersAlloc;
     1548    uint32_t       cNewTimers  = cOldEntries + 64;
     1549    Assert(cNewTimers < _32K);
     1550    if (!SUPR3IsDriverless())
     1551    {
     1552        rc = VMMR3CallR0Emt(pVM, VMMGetCpu(pVM), VMMR0_DO_TM_GROW_TIMER_QUEUE,
     1553                            RT_MAKE_U64(cNewTimers, (uint64_t)(pQueue - &pVM->tm.s.aTimerQueues[0])), NULL);
     1554        AssertLogRelRCReturn(rc, rc);
     1555        AssertReturn(pQueue->cTimersAlloc >= cNewTimers, VERR_TM_IPE_3);
     1556    }
     1557    else
     1558    {
     1559        AssertReturn(cNewTimers <= _32K && cOldEntries <= _32K, VERR_TM_TOO_MANY_TIMERS);
     1560        ASMCompilerBarrier();
     1561
     1562        /*
     1563         * Round up the request to the nearest page and do the allocation.
     1564         */
     1565        size_t cbNew = sizeof(TMTIMER) * cNewTimers;
     1566        cbNew = RT_ALIGN_Z(cbNew, PAGE_SIZE);
     1567        cNewTimers = (uint32_t)(cbNew / sizeof(TMTIMER));
     1568
     1569        PTMTIMER paTimers = (PTMTIMER)RTMemPageAllocZ(cbNew);
     1570        if (paTimers)
     1571        {
     1572            /*
     1573             * Copy over the old timer, init the new free ones, then switch over
     1574             * and free the old ones.
     1575             */
     1576            PTMTIMER const paOldTimers = pQueue->paTimers;
     1577            tmHCTimerQueueGrowInit(paTimers, paOldTimers, cNewTimers, cOldEntries);
     1578
     1579            pQueue->paTimers      = paTimers;
     1580            pQueue->cTimersAlloc  = cNewTimers;
     1581            pQueue->cTimersFree  += cNewTimers - (cOldEntries ? cOldEntries : 1);
     1582
     1583            RTMemPageFree(paOldTimers, RT_ALIGN_Z(sizeof(TMTIMER) * cOldEntries, PAGE_SIZE));
     1584            rc = VINF_SUCCESS;
     1585        }
     1586        else
     1587            rc = VERR_NO_PAGE_MEMORY;
     1588    }
     1589    return rc;
     1590}
     1591
     1592
     1593/**
    15261594 * Internal TMR3TimerCreate worker.
    15271595 *
     
    15701638    if (!pQueue->cTimersFree)
    15711639    {
    1572         AssertReturn(!pQueue->fCannotGrow, VERR_TM_TIMER_QUEUE_CANNOT_GROW);
    1573         uint32_t cTimersAlloc = pQueue->cTimersAlloc + 64;
    1574         Assert(cTimersAlloc < _32K);
    1575         rc = VMMR3CallR0Emt(pVM, VMMGetCpu(pVM), VMMR0_DO_TM_GROW_TIMER_QUEUE,
    1576                             RT_MAKE_U64(cTimersAlloc, (uint64_t)(pQueue - &pVM->tm.s.aTimerQueues[0])), NULL);
    1577         AssertLogRelRCReturnStmt(rc, PDMCritSectRwLeaveExcl(pVM, &pQueue->AllocLock), rc);
    1578         AssertReturnStmt(pQueue->cTimersAlloc >= cTimersAlloc, PDMCritSectRwLeaveExcl(pVM, &pQueue->AllocLock), VERR_TM_IPE_3);
     1640        rc = tmR3TimerQueueGrow(pVM, pQueue);
     1641        AssertRCReturnStmt(rc, PDMCritSectRwLeaveExcl(pVM, &pQueue->AllocLock), rc);
    15791642    }
    15801643
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