VirtualBox

Changeset 19360 in vbox


Ignore:
Timestamp:
May 5, 2009 10:14:15 AM (16 years ago)
Author:
vboxsync
Message:

Split up GVM and introduced GVMCPU.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/gvm.h

    r8155 r19360  
    3636#include <iprt/thread.h>
    3737
     38/** @defgroup grp_gvm   GVMCPU - The Global VMCPU Data
     39 * @{
     40 */
     41
     42typedef struct GVMCPU
     43{
     44    /* VCPU id (0 - (pVM->cCPUs - 1) */
     45    uint32_t        idCpu;
     46
     47    /** The GVMM per vcpu data. */
     48    struct
     49    {
     50#ifdef ___GVMMR0Internal_h
     51        struct GVMMPERVCPU  s;
     52#endif
     53        uint8_t             padding[64];
     54    } gvmm;
     55} GVMCPU;
     56/** Pointer to the GVMCPU data. */
     57typedef GVMCPU *PGVMCPU;
     58
     59/** @} */
    3860
    3961/** @defgroup grp_gvm   GVM - The Global VM Data
     
    6082    /** The ring-0 mapping of the VM structure. */
    6183    PVM             pVM;
     84    /** Number of VCPUs (same as pVM->cCPUs) */
     85    uint32_t        cCPUs;
     86    uint32_t        padding;
    6287
    6388    /** The GVMM per vm data. */
     
    79104    } gmm;
    80105
     106    /** GVMCPU array for the configured number of virtual CPUs. */
     107    GVMCPU          aCpus[1];
    81108} GVM;
    82109
  • trunk/include/VBox/gvmm.h

    r14811 r19360  
    135135GVMMR0DECL(PVM)     GVMMR0GetVMByHandle(uint32_t hGVM);
    136136GVMMR0DECL(PVM)     GVMMR0GetVMByEMT(RTNATIVETHREAD hEMT);
    137 GVMMR0DECL(int)     GVMMR0SchedHalt(PVM pVM, uint64_t u64ExpireGipTime);
    138 GVMMR0DECL(int)     GVMMR0SchedWakeUp(PVM pVM);
     137GVMMR0DECL(int)     GVMMR0SchedHalt(PVM pVM, unsigned idCpu, uint64_t u64ExpireGipTime);
     138GVMMR0DECL(int)     GVMMR0SchedWakeUp(PVM pVM, unsigned idCpu);
    139139GVMMR0DECL(int)     GVMMR0SchedPoll(PVM pVM, bool fYield);
    140140GVMMR0DECL(int)     GVMMR0QueryStatistics(PGVMMSTATS pStats, PSUPDRVSESSION pSession, PVM pVM);
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r18870 r19360  
    725725{
    726726    AssertCompile(RT_SIZEOFMEMB(GVM,gmm.s) <= RT_SIZEOFMEMB(GVM,gmm.padding));
    727     AssertRelease(RT_SIZEOFMEMB(GVM,gmm.s) <= RT_SIZEOFMEMB(GVM,gmm.padding));
    728727
    729728    pGVM->gmm.s.enmPolicy = GMMOCPOLICY_INVALID;
  • trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp

    r19238 r19360  
    571571                     * Allocate the global VM structure (GVM) and initialize it.
    572572                     */
    573                     PGVM pGVM = (PGVM)RTMemAllocZ(sizeof(*pGVM));
     573                    PGVM pGVM = (PGVM)RTMemAllocZ(RT_UOFFSETOF(GVM, aCpus[cCPUs]));
    574574                    if (pGVM)
    575575                    {
    576                         pGVM->u32Magic = GVM_MAGIC;
    577                         pGVM->hSelf = iHandle;
    578                         pGVM->hEMT = NIL_RTNATIVETHREAD;
    579                         pGVM->pVM = NULL;
     576                        pGVM->u32Magic  = GVM_MAGIC;
     577                        pGVM->hSelf     = iHandle;
     578                        pGVM->hEMT      = NIL_RTNATIVETHREAD;
     579                        pGVM->pVM       = NULL;
     580                        pGVM->cCPUs     = cCPUs;
    580581
    581582                        gvmmR0InitPerVMData(pGVM);
     
    701702{
    702703    AssertCompile(RT_SIZEOFMEMB(GVM,gvmm.s) <= RT_SIZEOFMEMB(GVM,gvmm.padding));
    703     Assert(RT_SIZEOFMEMB(GVM,gvmm.s) <= RT_SIZEOFMEMB(GVM,gvmm.padding));
    704704    pGVM->gvmm.s.VMMemObj = NIL_RTR0MEMOBJ;
    705705    pGVM->gvmm.s.VMMapObj = NIL_RTR0MEMOBJ;
    706706    pGVM->gvmm.s.VMPagesMemObj = NIL_RTR0MEMOBJ;
    707707    pGVM->gvmm.s.VMPagesMapObj = NIL_RTR0MEMOBJ;
    708     pGVM->gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI;
    709708    pGVM->gvmm.s.fDoneVMMR0Init = false;
    710709    pGVM->gvmm.s.fDoneVMMR0Term = false;
     710
     711    for (unsigned i=0; i< pGVM->cCPUs; i++)
     712        pGVM->aCpus[i].gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI;
    711713}
    712714
     
    731733    {
    732734        if (   !pGVM->gvmm.s.fDoneVMMR0Init
    733             && pGVM->gvmm.s.HaltEventMulti == NIL_RTSEMEVENTMULTI)
    734         {
    735             rc = RTSemEventMultiCreate(&pGVM->gvmm.s.HaltEventMulti);
    736             if (RT_FAILURE(rc))
    737                 pGVM->gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI;
     735            && pGVM->aCpus[0].gvmm.s.HaltEventMulti == NIL_RTSEMEVENTMULTI)
     736        {
     737            for (unsigned i=0; i < pGVM->cCPUs; i++)
     738            {
     739                rc = RTSemEventMultiCreate(&pGVM->aCpus[i].gvmm.s.HaltEventMulti);
     740                if (RT_FAILURE(rc))
     741                {
     742                    pGVM->aCpus[i].gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI;
     743                    break;
     744                }
     745            }
    738746        }
    739747        else
     
    10081016        }
    10091017
    1010         if (pGVM->gvmm.s.HaltEventMulti != NIL_RTSEMEVENTMULTI)
    1011         {
    1012             rc = RTSemEventMultiDestroy(pGVM->gvmm.s.HaltEventMulti); AssertRC(rc);
    1013             pGVM->gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI;
     1018        for (unsigned i=0; i< pGVM->cCPUs; i++)
     1019        {
     1020            if (pGVM->aCpus[i].gvmm.s.HaltEventMulti != NIL_RTSEMEVENTMULTI)
     1021            {
     1022                rc = RTSemEventMultiDestroy(pGVM->aCpus[i].gvmm.s.HaltEventMulti); AssertRC(rc);
     1023                pGVM->aCpus[i].gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI;
     1024            }
    10141025        }
    10151026
     
    13071318            &&  pCurGVM->u32Magic == GVM_MAGIC)
    13081319        {
    1309             uint64_t u64 = pCurGVM->gvmm.s.u64HaltExpire;
    1310             if (u64)
     1320            for (unsigned idCpu = 0; idCpu < pCurGVM->cCPUs; idCpu++)
    13111321            {
    1312                 if (u64 <= u64Now)
     1322                PGVMCPU pCurGVCpu = &pCurGVM->aCpus[idCpu];
     1323
     1324                uint64_t u64 = pCurGVCpu->gvmm.s.u64HaltExpire;
     1325                if (u64)
    13131326                {
    1314                     if (ASMAtomicXchgU64(&pCurGVM->gvmm.s.u64HaltExpire, 0))
     1327                    if (u64 <= u64Now)
    13151328                    {
    1316                         int rc = RTSemEventMultiSignal(pCurGVM->gvmm.s.HaltEventMulti);
    1317                         AssertRC(rc);
    1318                         cWoken++;
     1329                        if (ASMAtomicXchgU64(&pCurGVCpu->gvmm.s.u64HaltExpire, 0))
     1330                        {
     1331                            int rc = RTSemEventMultiSignal(pCurGVCpu->gvmm.s.HaltEventMulti);
     1332                            AssertRC(rc);
     1333                            cWoken++;
     1334                        }
    13191335                    }
    1320                 }
    1321                 else
    1322                 {
    1323                     cHalted++;
    1324                     if (u64 <= u64Now + pGVMM->nsEarlyWakeUp1)
    1325                         cTodo2nd++;
    1326                     else if (u64 <= u64Now + pGVMM->nsEarlyWakeUp2)
    1327                         cTodo3rd++;
     1336                    else
     1337                    {
     1338                        cHalted++;
     1339                        if (u64 <= u64Now + pGVMM->nsEarlyWakeUp1)
     1340                            cTodo2nd++;
     1341                        else if (u64 <= u64Now + pGVMM->nsEarlyWakeUp2)
     1342                            cTodo3rd++;
     1343                    }
    13281344                }
    13291345            }
     
    13401356            PGVM pCurGVM = pGVMM->aHandles[i].pGVM;
    13411357            if (    VALID_PTR(pCurGVM)
    1342                 &&  pCurGVM->u32Magic == GVM_MAGIC
    1343                 &&  pCurGVM->gvmm.s.u64HaltExpire
    1344                 &&  pCurGVM->gvmm.s.u64HaltExpire <= u64Now + pGVMM->nsEarlyWakeUp1)
     1358                &&  pCurGVM->u32Magic == GVM_MAGIC)
    13451359            {
    1346                 if (ASMAtomicXchgU64(&pCurGVM->gvmm.s.u64HaltExpire, 0))
     1360                for (unsigned idCpu = 0; idCpu < pCurGVM->cCPUs; idCpu++)
    13471361                {
    1348                     int rc = RTSemEventMultiSignal(pCurGVM->gvmm.s.HaltEventMulti);
    1349                     AssertRC(rc);
    1350                     cWoken++;
     1362                    PGVMCPU pCurGVCpu = &pCurGVM->aCpus[idCpu];
     1363
     1364                    if (    pCurGVCpu->gvmm.s.u64HaltExpire
     1365                        &&  pCurGVCpu->gvmm.s.u64HaltExpire <= u64Now + pGVMM->nsEarlyWakeUp1)
     1366                    {
     1367                        if (ASMAtomicXchgU64(&pCurGVCpu->gvmm.s.u64HaltExpire, 0))
     1368                        {
     1369                            int rc = RTSemEventMultiSignal(pCurGVCpu->gvmm.s.HaltEventMulti);
     1370                            AssertRC(rc);
     1371                            cWoken++;
     1372                        }
     1373                    }
    13511374                }
    13521375            }
     
    13631386            PGVM pCurGVM = pGVMM->aHandles[i].pGVM;
    13641387            if (    VALID_PTR(pCurGVM)
    1365                 &&  pCurGVM->u32Magic == GVM_MAGIC
    1366                 &&  pCurGVM->gvmm.s.u64HaltExpire
    1367                 &&  pCurGVM->gvmm.s.u64HaltExpire <= u64Now + pGVMM->nsEarlyWakeUp2)
     1388                &&  pCurGVM->u32Magic == GVM_MAGIC)
    13681389            {
    1369                 if (ASMAtomicXchgU64(&pCurGVM->gvmm.s.u64HaltExpire, 0))
     1390                for (unsigned idCpu = 0; idCpu < pCurGVM->cCPUs; idCpu++)
    13701391                {
    1371                     int rc = RTSemEventMultiSignal(pCurGVM->gvmm.s.HaltEventMulti);
    1372                     AssertRC(rc);
    1373                     cWoken++;
     1392                    PGVMCPU pCurGVCpu = &pCurGVM->aCpus[idCpu];
     1393
     1394                    if (    pCurGVCpu->gvmm.s.u64HaltExpire
     1395                        &&  pCurGVCpu->gvmm.s.u64HaltExpire <= u64Now + pGVMM->nsEarlyWakeUp2)
     1396                    {
     1397                        if (ASMAtomicXchgU64(&pCurGVCpu->gvmm.s.u64HaltExpire, 0))
     1398                        {
     1399                            int rc = RTSemEventMultiSignal(pCurGVCpu->gvmm.s.HaltEventMulti);
     1400                            AssertRC(rc);
     1401                            cWoken++;
     1402                        }
     1403                    }
    13741404                }
    13751405            }
     
    13881418 *          VERR_INTERRUPTED if a signal was scheduled for the thread.
    13891419 * @param   pVM                 Pointer to the shared VM structure.
     1420 * @param   idCpu               VCPU id
    13901421 * @param   u64ExpireGipTime    The time for the sleep to expire expressed as GIP time.
    13911422 * @thread  EMT.
    13921423 */
    1393 GVMMR0DECL(int) GVMMR0SchedHalt(PVM pVM, uint64_t u64ExpireGipTime)
     1424GVMMR0DECL(int) GVMMR0SchedHalt(PVM pVM, unsigned idCpu, uint64_t u64ExpireGipTime)
    13941425{
    13951426    LogFlow(("GVMMR0SchedHalt: pVM=%p\n", pVM));
     
    13981429     * Validate the VM structure, state and handle.
    13991430     */
    1400     PGVMM pGVMM;
    1401     PGVM pGVM;
     1431    PGVMM   pGVMM;
     1432    PGVM    pGVM;
     1433    PGVMCPU pCurGVCpu;
     1434
    14021435    int rc = gvmmR0ByVMAndEMT(pVM, &pGVM, &pGVMM);
    14031436    if (RT_FAILURE(rc))
    14041437        return rc;
     1438
    14051439    pGVM->gvmm.s.StatsSched.cHaltCalls++;
    14061440
    1407     Assert(!pGVM->gvmm.s.u64HaltExpire);
     1441    pCurGVCpu = &pGVM->aCpus[idCpu];
     1442    Assert(idCpu < pGVM->cCPUs);
     1443    Assert(!pCurGVCpu->gvmm.s.u64HaltExpire);
    14081444
    14091445    /*
     
    14151451    AssertRC(rc);
    14161452
    1417     pGVM->gvmm.s.iCpuEmt = ASMGetApicId();
     1453    pCurGVCpu->gvmm.s.iCpuEmt = ASMGetApicId();
    14181454
    14191455    Assert(ASMGetFlags() & X86_EFL_IF);
     
    14301466    {
    14311467        pGVM->gvmm.s.StatsSched.cHaltBlocking++;
    1432         ASMAtomicXchgU64(&pGVM->gvmm.s.u64HaltExpire, u64ExpireGipTime);
     1468        ASMAtomicXchgU64(&pCurGVCpu->gvmm.s.u64HaltExpire, u64ExpireGipTime);
    14331469        gvmmR0UsedUnlock(pGVMM);
    14341470
    14351471        uint32_t cMillies = (u64ExpireGipTime - u64Now) / 1000000;
    1436         rc = RTSemEventMultiWaitNoResume(pGVM->gvmm.s.HaltEventMulti, cMillies ? cMillies : 1);
    1437         ASMAtomicXchgU64(&pGVM->gvmm.s.u64HaltExpire, 0);
     1472        rc = RTSemEventMultiWaitNoResume(pCurGVCpu->gvmm.s.HaltEventMulti, cMillies ? cMillies : 1);
     1473        ASMAtomicXchgU64(&pCurGVCpu->gvmm.s.u64HaltExpire, 0);
    14381474        if (rc == VERR_TIMEOUT)
    14391475        {
     
    14491485
    14501486    /* Make sure false wake up calls (gvmmR0SchedDoWakeUps) cause us to spin. */
    1451     RTSemEventMultiReset(pGVM->gvmm.s.HaltEventMulti);
     1487    RTSemEventMultiReset(pCurGVCpu->gvmm.s.HaltEventMulti);
    14521488
    14531489    return rc;
     
    14611497 *          VINF_GVM_NOT_BLOCKED if the EMT thread wasn't blocked.
    14621498 * @param   pVM                 Pointer to the shared VM structure.
     1499 * @param   idCpu               VCPU id
    14631500 * @thread  Any but EMT.
    14641501 */
    1465 GVMMR0DECL(int) GVMMR0SchedWakeUp(PVM pVM)
     1502GVMMR0DECL(int) GVMMR0SchedWakeUp(PVM pVM, unsigned idCpu)
    14661503{
    14671504    /*
    14681505     * Validate input and take the UsedLock.
    14691506     */
    1470     PGVM pGVM;
    1471     PGVMM pGVMM;
     1507    PGVMM   pGVMM;
     1508    PGVM    pGVM;
     1509    PGVMCPU pCurGVCpu;
     1510
    14721511    int rc = gvmmR0ByVM(pVM, &pGVM, &pGVMM, true /* fTakeUsedLock */);
    14731512    if (RT_SUCCESS(rc))
    14741513    {
     1514        Assert(idCpu < pGVM->cCPUs);
     1515
     1516        pCurGVCpu = &pGVM->aCpus[idCpu];
     1517
    14751518        pGVM->gvmm.s.StatsSched.cWakeUpCalls++;
    14761519
     
    14831526         * the it is flagged as halted in the VMM.
    14841527         */
    1485         if (pGVM->gvmm.s.u64HaltExpire)
     1528        if (pCurGVCpu->gvmm.s.u64HaltExpire)
    14861529        {
    14871530            rc = VINF_SUCCESS;
    1488             ASMAtomicXchgU64(&pGVM->gvmm.s.u64HaltExpire, 0);
     1531            ASMAtomicXchgU64(&pCurGVCpu->gvmm.s.u64HaltExpire, 0);
    14891532        }
    14901533        else
     
    14941537        }
    14951538
    1496         int rc2 = RTSemEventMultiSignal(pGVM->gvmm.s.HaltEventMulti);
     1539        int rc2 = RTSemEventMultiSignal(pCurGVCpu->gvmm.s.HaltEventMulti);
    14971540        AssertRC(rc2);
    14981541
  • trunk/src/VBox/VMM/VMMR0/GVMMR0Internal.h

    r14811 r19360  
    2525#include <iprt/mem.h>
    2626
     27/**
     28 * The GVMM per VM data.
     29 */
     30typedef struct GVMMPERVCPU
     31{
     32    /** The time the halted EMT thread expires.
     33     * 0 if the EMT thread is blocked here. */
     34    uint64_t volatile   u64HaltExpire;
     35    /** The event semaphore the EMT thread is blocking on. */
     36    RTSEMEVENTMULTI     HaltEventMulti;
     37    /** The APIC ID of the CPU that EMT was scheduled on the last time we checked. */
     38    uint8_t             iCpuEmt;
     39} GVMMPERVCPU;
     40/** Pointer to the GVMM per VCPU data. */
     41typedef GVMMPERVCPU *PGVMMPERVCPU;
    2742
    2843/**
     
    4055    RTR0MEMOBJ          VMPagesMapObj;
    4156
    42     /** The time the halted EMT thread expires.
    43      * 0 if the EMT thread is blocked here. */
    44     uint64_t volatile   u64HaltExpire;
    45     /** The event semaphore the EMT thread is blocking on. */
    46     RTSEMEVENTMULTI     HaltEventMulti;
    47     /** The APIC ID of the CPU that EMT was scheduled on the last time we checked. */
    48     uint8_t             iCpuEmt;
    49 
    5057    /** The scheduler statistics. */
    5158    GVMMSTATSSCHED      StatsSched;
  • trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp

    r19227 r19360  
    11921192            return pVCpu;
    11931193    }
    1194     AssertReleaseFailed();
    1195     return 0;
     1194    return NULL;
    11961195}
    11971196
     
    12071206        return pVCpu->idCpu;
    12081207
    1209     AssertReleaseFailed();
    12101208    return 0;
    12111209}
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r19262 r19360  
    746746            if (pReqHdr)
    747747                return VERR_INVALID_PARAMETER;
    748             return GVMMR0SchedHalt(pVM, u64Arg);
     748            return GVMMR0SchedHalt(pVM, idCpu, u64Arg);
    749749
    750750        case VMMR0_DO_GVMM_SCHED_WAKE_UP:
    751751            if (pReqHdr || u64Arg)
    752752                return VERR_INVALID_PARAMETER;
    753             return GVMMR0SchedWakeUp(pVM);
     753            return GVMMR0SchedWakeUp(pVM, idCpu);
    754754
    755755        case VMMR0_DO_GVMM_SCHED_POLL:
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