VirtualBox

Ignore:
Timestamp:
May 13, 2011 10:18:29 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
71699
Message:

VMM: Support for online/offlining of CPUs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r36730 r37062  
    322322    { "RTMpIsCpuOnline",                        (void *)RTMpIsCpuOnline },
    323323    { "RTMpIsCpuWorkPending",                   (void *)RTMpIsCpuWorkPending },
     324    { "RTMpNotificationRegister",               (void *)RTMpNotificationRegister },
     325    { "RTMpNotificationDeregister",             (void *)RTMpNotificationDeregister },
    324326    { "RTMpOnAll",                              (void *)RTMpOnAll },
    325327    { "RTMpOnOthers",                           (void *)RTMpOnOthers },
     
    49904992
    49914993/**
     4994 * Helper for finding the CPU index from the CPU Id.
     4995 *
     4996 * @param    pGip               The GIP.
     4997 * @param    idCpu              The CPU ID.
     4998 *
     4999 * @returns Index of the CPU in the cache set.
     5000 */
     5001static inline uint32_t supdrvGipCpuIndexFromCpuId(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu)
     5002{
     5003    uint32_t i = 0;
     5004
     5005    /*
     5006     * Find our entry, or allocate one if not found.
     5007     * ASSUMES that CPU IDs are constant.
     5008     */
     5009    for (i = 0; i < pGip->cCpus; i++)
     5010        if (pGip->aCPUs[i].idCpu == idCpu)
     5011            break;
     5012
     5013    if (i >= pGip->cCpus)
     5014        for (i = 0; i < pGip->cCpus; i++)
     5015        {
     5016            bool fRc;
     5017            ASMAtomicCmpXchgSize(&pGip->aCPUs[i].idCpu, idCpu, NIL_RTCPUID, fRc);
     5018            if (fRc)
     5019                break;
     5020        }
     5021
     5022    AssertRelease(i < pGip->cCpus);
     5023    return i;
     5024}
     5025
     5026
     5027/**
    49925028 * The calling CPU should be accounted as online, update GIP accordingly.
    49935029 *
     
    49995035static void supdrvGipMpEventOnline(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu)
    50005036{
    5001     int         iCpuSet;
    5002     uint8_t     idApic;
    5003     uint32_t    i;
    5004 
    5005     Assert(idCpu == RTMpCpuId());
     5037    int         iCpuSet = 0;
     5038    uint16_t    idApic = UINT16_MAX;
     5039    uint32_t    i = 0;
     5040
     5041    AssertRelease(idCpu == RTMpCpuId());
    50065042    Assert(pGip->cPossibleCpus == RTMpGetCount());
    50075043
     
    50195055    }
    50205056
    5021     /*
    5022      * Find our entry, or allocate one if not found.
    5023      * ASSUMES that CPU IDs are constant.
    5024      */
    5025     for (i = 0; i < pGip->cCpus; i++)
    5026         if (pGip->aCPUs[i].idCpu == idCpu)
    5027             break;
    5028 
    5029     if (i >= pGip->cCpus)
    5030         for (i = 0; i < pGip->cCpus; i++)
    5031         {
    5032             bool fRc;
    5033             ASMAtomicCmpXchgSize(&pGip->aCPUs[i].idCpu, idCpu, NIL_RTCPUID, fRc);
    5034             if (fRc)
    5035                 break;
    5036         }
    5037 
    5038     AssertReturnVoid(i < pGip->cCpus);
     5057    i = supdrvGipCpuIndexFromCpuId(pGip, idCpu);
    50395058
    50405059    /*
     
    50455064    ASMAtomicUoWriteS16(&pGip->aCPUs[i].iCpuSet, (int16_t)iCpuSet);
    50465065    ASMAtomicUoWriteSize(&pGip->aCPUs[i].idCpu,  idCpu);
    5047     ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_ONLINE);
    50485066
    50495067    /*
     
    50525070    ASMAtomicWriteU16(&pGip->aiCpuFromApicId[idApic],     i);
    50535071    ASMAtomicWriteU16(&pGip->aiCpuFromCpuSetIdx[iCpuSet], i);
     5072
     5073    ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_ONLINE);
    50545074}
    50555075
     
    50765096
    50775097    Assert(RTCpuSetIsMemberByIndex(&pGip->PossibleCpuSet, iCpuSet));
     5098    RTCpuSetDelByIndex(&pGip->OnlineCpuSet, iCpuSet);
    50785099    ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_OFFLINE);
    5079     RTCpuSetDelByIndex(&pGip->OnlineCpuSet, iCpuSet);
    50805100}
    50815101
     
    50955115    PSUPDRVDEVEXT       pDevExt = (PSUPDRVDEVEXT)pvUser;
    50965116    PSUPGLOBALINFOPAGE  pGip    = pDevExt->pGip;
     5117
     5118    AssertRelease(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
    50975119
    50985120    /*
     
    53595381        pGip->aCPUs[i].idCpu             = NIL_RTCPUID;
    53605382        pGip->aCPUs[i].iCpuSet           = -1;
    5361         pGip->aCPUs[i].idApic            = UINT8_MAX;
     5383        pGip->aCPUs[i].idApic            = UINT16_MAX;
    53625384
    53635385        /*
     
    56185640                                  RTCPUID idCpu, uint8_t idApic, uint64_t iTick)
    56195641{
     5642    /*
     5643     * Avoid a potential race when a CPU online notification doesn't fire on the onlined CPU
     5644     * but the tick creeps in before the event notification is run.
     5645     */
     5646    if (iTick == 1)
     5647    {
     5648        uint32_t i = supdrvGipCpuIndexFromCpuId(pGip, idCpu);
     5649        if (pGip->aCPUs[i].enmState == SUPGIPCPUSTATE_OFFLINE)
     5650            supdrvGipMpEventOnline(pGip, idCpu);
     5651    }
     5652
    56205653    unsigned iCpu = pGip->aiCpuFromApicId[idApic];
    56215654
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette