VirtualBox

Changeset 37466 in vbox for trunk


Ignore:
Timestamp:
Jun 15, 2011 12:44:16 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
72280
Message:

VMM,Devices: Automatically use a per-device lock instead of the giant IOM lock. With exception of the PIC, APIC, IOAPIC and PCI buses which are all using the PDM crit sect, there should be no calls between devices. So, this change should be relatively safe.

Location:
trunk
Files:
28 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/iom.h

    r37452 r37466  
    264264VMMR3_INT_DECL(int)  IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);
    265265
    266 VMMR3DECL(PPDMCRITSECT) IOMR3GetCritSect(PVM pVM);
    267 
    268266/** @} */
    269267#endif /* IN_RING3 */
  • trunk/include/VBox/vmm/pdmapi.h

    r35361 r37466  
    122122VMMR3DECL(int)  PDMR3DeviceAttach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags, PPDMIBASE *ppBase);
    123123VMMR3DECL(int)  PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags);
     124VMMR3_INT_DECL(PPDMCRITSECT) PDMR3DevGetCritSect(PVM pVM, PPDMDEVINS pDevIns);
    124125VMMR3DECL(int)  PDMR3DriverAttach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, uint32_t fFlags, PPPDMIBASE ppBase);
    125126VMMR3DECL(int)  PDMR3DriverDetach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun,
  • trunk/include/VBox/vmm/pdmdev.h

    r37443 r37466  
    29432943
    29442944    /**
     2945     * Changes the device level critical section from the automatically created
     2946     * default to one desired by the device constructor.
     2947     *
     2948     * @returns VBox status code.
     2949     * @param   pDevIns             The device instance.
     2950     * @param   pCritSect           The critical section to use.  NULL is not
     2951     *                              valid, instead use the NOP critical
     2952     *                              section.
     2953     */
     2954    DECLR3CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
     2955
     2956    /**
    29452957     * Creates a PDM thread.
    29462958     *
     
    34223434
    34233435/** Current PDMDEVHLPR3 version number. */
    3424 #define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 5, 0)
     3436#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 7, 0)
    34253437
    34263438
     
    38303842    /** Pointer to device instance data. */
    38313843    RTRCPTR                     pvInstanceDataRC;
    3832     /** The critical section for the device, see pCritSectR3.
    3833      * This is automatically resolved by PDM when pCritSectR3 is set by the
    3834      * constructor. */
    3835     RCPTRTYPE(PPDMCRITSECT)     pCritSectRC;
     3844    /** The critical section for the device, see pCritSectXR3. */
     3845    RCPTRTYPE(PPDMCRITSECT)     pCritSectRoRC;
    38363846    /** Alignment padding.  */
    38373847    RTRCPTR                     pAlignmentRC;
     
    38413851    /** Pointer to device instance data (R0). */
    38423852    RTR0PTR                     pvInstanceDataR0;
    3843     /** The critical section for the device, see pCritSectR3.
    3844     * This is automatically resolved by PDM when pCritSectR3 is set by the
    3845     * constructor. */
    3846     R0PTRTYPE(PPDMCRITSECT)     pCritSectR0;
     3853    /** The critical section for the device, see pCritSectXR3. */
     3854    R0PTRTYPE(PPDMCRITSECT)     pCritSectRoR0;
    38473855
    38483856    /** Pointer the HC PDM Device API. */
     
    38503858    /** Pointer to device instance data. */
    38513859    RTR3PTR                     pvInstanceDataR3;
    3852     /** The critical section for the device. (Optional)
    3853      *
    3854      * The device constructor initializes this if it has a critical section for
    3855      * the device and desires it to be taken automatically by MMIO, I/O port
    3856      * and timer callbacks to the device.  The advantages using this locking
    3857      * approach is both less code and avoiding the global IOM lock.
    3858      *
    3859      * @remarks Will not yet be taken by SSM.
    3860      */
    3861     R3PTRTYPE(PPDMCRITSECT)     pCritSectR3;
     3860    /** The critical section for the device.
     3861     *
     3862     * TM and IOM will enter this critical section before calling into the
     3863     * device code.  SSM will currently not, but this will be changed later on.
     3864     *
     3865     * The device gets a critical section automatically assigned to it before
     3866     * the constructor is called.  If the constructor wishes to use a different
     3867     * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
     3868     * very early on.
     3869     */
     3870    R3PTRTYPE(PPDMCRITSECT)     pCritSectRoR3;
    38623871
    38633872    /** Pointer to device registration structure.  */
     
    45624571
    45634572/**
     4573 * @copydoc PDMDEVHLPR3::pfnSetDeviceCritSect
     4574 */
     4575DECLINLINE(int) PDMDevHlpSetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
     4576{
     4577    return pDevIns->pHlpR3->pfnSetDeviceCritSect(pDevIns, pCritSect);
     4578}
     4579
     4580/**
    45644581 * @copydoc PDMDEVHLPR3::pfnThreadCreate
    45654582 */
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r37324 r37466  
    60286028
    60296029    /* Initialize the PDM lock. */
    6030     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->lock, RT_SRC_POS, "VGA");
     6030    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->lock, RT_SRC_POS, "VGA#u", iInstance);
    60316031    if (RT_FAILURE(rc))
    60326032    {
  • trunk/src/VBox/Devices/Input/DevPS2.cpp

    r36989 r37466  
    17791779     * Initialize the critical section.
    17801780     */
    1781     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "PS2KM#%d", iInstance);
     1781    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "PS2KM#%u", iInstance);
    17821782    if (RT_FAILURE(rc))
    17831783        return rc;
  • trunk/src/VBox/Devices/Network/DevPCNet.cpp

    r37324 r37466  
    51755175     * attaching drivers or anything else that may call us back.
    51765176     */
    5177     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "PCNet#%d", iInstance);
     5177    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "PCNet#%u", iInstance);
    51785178    if (RT_FAILURE(rc))
    51795179        return rc;
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r37446 r37466  
    28242824
    28252825    /* Set the default critical section to NOP (related to the PM timer). */
    2826     pDevIns->pCritSectR3 = PDMDevHlpCritSectGetNop(pDevIns);
    2827     int rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "acpi");
     2826    int rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
     2827    AssertRCReturn(rc, rc);
     2828
     2829    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "acpi%u", iInstance);
    28282830    AssertRCReturn(rc, rc);
    28292831
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r37453 r37466  
    23782378
    23792379    /* Disable locking in this device. */
    2380     pDevIns->pCritSectR3 = PDMDevHlpCritSectGetNop(pDevIns);
     2380    rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
     2381    AssertRCReturn(rc, rc);
    23812382
    23822383    PVM pVM = PDMDevHlpGetVM(pDevIns);
  • trunk/src/VBox/Devices/PC/DevHPET.cpp

    r37324 r37466  
    13131313     * Initialize critical section.
    13141314     */
    1315     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->csLock, RT_SRC_POS, "HPET");
     1315    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->csLock, RT_SRC_POS, "HPET#%u", pDevIns->iInstance);
    13161316    if (RT_FAILURE(rc))
    13171317        return PDMDEV_SET_ERROR(pDevIns, rc, N_("HPET cannot initialize critical section"));
  • trunk/src/VBox/Devices/Parallel/DevParallel.cpp

    r35353 r37466  
    749749     * This must of course be done before attaching drivers or anything else which can call us back..
    750750     */
    751     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Parallel#%d", iInstance);
     751    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Parallel#%u", iInstance);
    752752    if (RT_FAILURE(rc))
    753753        return rc;
  • trunk/src/VBox/Devices/Serial/DevSerial.cpp

    r37324 r37466  
    11901190
    11911191    /*
    1192      * We have a critical section make TM and IOM take it for callbacks.
    1193      */
    1194     pDevIns->pCritSectR3 = &pThis->CritSect;
    1195 
    1196     /*
    11971192     * Validate and read the configuration.
    11981193     */
     
    12701265
    12711266    /*
    1272      * Initialize critical section and the semaphore.
    1273      * This must of be done before attaching drivers or doing anything else
    1274      * which can call us back.
     1267     * Initialize critical section and the semaphore.  Change the default
     1268     * critical section to ours so that TM and IOM will enter it before
     1269     * calling us.
     1270     *
     1271     * Note! This must of be done BEFORE creating timers, registering I/O ports
     1272     *       and other things which might pick up the default CS or end up
     1273     *       calling back into the device.
    12751274     */
    1276     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Serial#%d", iInstance);
    1277     if (RT_FAILURE(rc))
    1278         return rc;
     1275    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Serial#%u", iInstance);
     1276    AssertRCReturn(rc, rc);
     1277
     1278    rc = PDMDevHlpSetDeviceCritSect(pDevIns, &pThis->CritSect);
     1279    AssertRCReturn(rc, rc);
    12791280
    12801281    rc = RTSemEventCreate(&pThis->ReceiveSem);
    12811282    AssertRCReturn(rc, rc);
    12821283
     1284    /*
     1285     * Create the timers.
     1286     */
    12831287    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, serialFifoTimer, pThis,
    12841288                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "Serial Fifo Timer",
  • trunk/src/VBox/Devices/Storage/ATAController.cpp

    r37264 r37466  
    55815581                      uint32_t *pcbSSMState, const char *szName)
    55825582{
    5583     int      rc;
     5583    int rc;
    55845584
    55855585    AssertMsg(pcbSSMState, ("pcbSSMState is invalid\n"));
  • trunk/src/VBox/Devices/Storage/DevAHCI.cpp

    r37324 r37466  
    83378337                                N_("AHCI cannot register PCI memory region for registers"));
    83388338
    8339     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->lock, RT_SRC_POS, "AHCI%d", pDevIns->iInstance);
     8339    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->lock, RT_SRC_POS, "AHCI#%u", iInstance);
    83408340    if (RT_FAILURE(rc))
    83418341    {
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r37264 r37466  
    70327032
    70337033        /* Initialize per-controller critical section */
    7034         rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].lock, RT_SRC_POS, "ATA%u", i);
     7034        rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].lock, RT_SRC_POS, "ATA#%u", i);
    70357035        if (RT_FAILURE(rc))
    70367036            return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot initialize critical section"));
  • trunk/src/VBox/Devices/Storage/DevBusLogic.cpp

    r36039 r37466  
    31363136    pThis->pNotifierQueueRC = PDMQueueRCPtr(pThis->pNotifierQueueR3);
    31373137
    3138     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSectIntr, RT_SRC_POS, "BusLogic-Intr");
     3138    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSectIntr, RT_SRC_POS, "BusLogic-Intr#%u", pDevIns->iInstance);
    31393139    if (RT_FAILURE(rc))
    31403140        return PDMDEV_SET_ERROR(pDevIns, rc,
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r35353 r37466  
    49564956    int rc = VINF_SUCCESS;
    49574957    char *pszCtrlType = NULL;
    4958     char  szDevTag[20], szTaggedText[64];
     4958    char  szDevTag[20];
    49594959    bool fBootable = true;
    49604960    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
     
    50115011    MMR3HeapFree(pszCtrlType);
    50125012
    5013     RTStrPrintf(szDevTag, sizeof(szDevTag), "LSILOGIC%s-%d",
     5013    RTStrPrintf(szDevTag, sizeof(szDevTag), "LSILOGIC%s-%u",
    50145014                pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI ? "SPI" : "SAS",
    50155015                iInstance);
     
    51185118
    51195119    /* Initialize task queue. (Need two items to handle SMP guest concurrency.) */
     5120    char szTaggedText[64];
    51205121    RTStrPrintf(szTaggedText, sizeof(szTaggedText), "%s-Task", szDevTag);
    51215122    rc = PDMDevHlpQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 2, 0,
     
    51445145     * Create critical sections protecting the reply post and free queues.
    51455146     */
    5146     RTStrPrintf(szTaggedText, sizeof(szTaggedText), "%sRFQ", szDevTag);
    5147     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyFreeQueueCritSect, RT_SRC_POS,
    5148                                szTaggedText);
     5147    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyFreeQueueCritSect, RT_SRC_POS, "%sRFQ", szDevTag);
    51495148    if (RT_FAILURE(rc))
    51505149        return PDMDEV_SET_ERROR(pDevIns, rc,
    51515150                                N_("LsiLogic: cannot create critical section for reply free queue"));
    51525151
    5153     RTStrPrintf(szTaggedText, sizeof(szTaggedText), "%sRPQ", szDevTag);
    5154     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyPostQueueCritSect, RT_SRC_POS,
    5155                                szTaggedText);
     5152    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyPostQueueCritSect, RT_SRC_POS, "%sRPQ", szDevTag);
    51565153    if (RT_FAILURE(rc))
    51575154        return PDMDEV_SET_ERROR(pDevIns, rc,
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r37385 r37466  
    30113011     * Create the critical section for the device.
    30123012     */
    3013     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "VMMDev");
     3013    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "VMMDev#u", iInstance);
    30143014    AssertRCReturn(rc, rc);
    30153015    /* Later: pDevIns->pCritSectR3 = &pThis->CritSect; */
  • trunk/src/VBox/Devices/VirtIO/Virtio.cpp

    r35346 r37466  
    809809                                uint32_t nQueues)
    810810{
    811     int rc = VINF_SUCCESS;
    812811    /* Init handles and log related stuff. */
    813812    RTStrPrintf(pState->szInstance, sizeof(pState->szInstance),
     
    822821
    823822    /* Initialize critical section. */
    824     rc = PDMDevHlpCritSectInit(pDevIns, &pState->cs, RT_SRC_POS, "%s", pState->szInstance);
     823    int rc = PDMDevHlpCritSectInit(pDevIns, &pState->cs, RT_SRC_POS, "%s", pState->szInstance);
    825824    if (RT_FAILURE(rc))
    826825        return rc;
  • trunk/src/VBox/VMM/VMMAll/IOMAll.cpp

    r37452 r37466  
    9494}
    9595
     96
    9697/**
    9798 * Returns the contents of register or immediate data of instruction's parameter.
     
    316317        void           *pvUser    = pRange->pvUser;
    317318        PPDMDEVINS      pDevIns   = pRange->pDevIns;
    318         PPDMCRITSECT    pCritSect = pDevIns->CTX_SUFF(pCritSect);
     319        PPDMCRITSECT    pCritSect = pDevIns->CTX_SUFF(pCritSectRo);
    319320
    320321        /*
     
    512513        void           *pvUser    = pRange->pvUser;
    513514        PPDMDEVINS      pDevIns   = pRange->pDevIns;
    514         PPDMCRITSECT    pCritSect = pDevIns->CTX_SUFF(pCritSect);
     515        PPDMCRITSECT    pCritSect = pDevIns->CTX_SUFF(pCritSectRo);
    515516
    516517        /*
     
    680681        }
    681682#endif
    682         void           *pvUser    =  pRange->pvUser;
     683        void           *pvUser    = pRange->pvUser;
    683684        PPDMDEVINS      pDevIns   = pRange->pDevIns;
    684         PPDMCRITSECT    pCritSect = pDevIns->CTX_SUFF(pCritSect);
     685        PPDMCRITSECT    pCritSect = pDevIns->CTX_SUFF(pCritSectRo);
    685686
    686687        /*
     
    852853        void           *pvUser    = pRange->pvUser;
    853854        PPDMDEVINS      pDevIns   = pRange->pDevIns;
    854         PPDMCRITSECT    pCritSect = pDevIns->CTX_SUFF(pCritSect);
     855        PPDMCRITSECT    pCritSect = pDevIns->CTX_SUFF(pCritSectRo);
    855856
    856857        /*
  • trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp

    r37452 r37466  
    11371137    iomMmioRetainRange(pRange);
    11381138    PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
    1139     PPDMCRITSECT pLock = pDevIns->CTX_SUFF(pCritSect);
     1139    PPDMCRITSECT pLock = pDevIns->CTX_SUFF(pCritSectRo);
    11401140    if (!pLock)
    11411141        pLock = &pVM->iom.s.EmtLock;
     
    13761376    iomMmioRetainRange(pRange);
    13771377    PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
    1378     PPDMCRITSECT pLock = pDevIns->CTX_SUFF(pCritSect);
     1378    PPDMCRITSECT pLock = pDevIns->CTX_SUFF(pCritSectRo);
    13791379    if (!pLock)
    13801380        pLock = &pVM->iom.s.EmtLock;
     
    14601460        iomMmioRetainRange(pRange);
    14611461        PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
    1462         PPDMCRITSECT pLock = pDevIns->CTX_SUFF(pCritSect);
     1462        PPDMCRITSECT pLock = pDevIns->CTX_SUFF(pCritSectRo);
    14631463        if (!pLock)
    14641464            pLock = &pVM->iom.s.EmtLock;
     
    16101610        iomMmioRetainRange(pRange);
    16111611        PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
    1612         PPDMCRITSECT pLock = pDevIns->CTX_SUFF(pCritSect);
     1612        PPDMCRITSECT pLock = pDevIns->CTX_SUFF(pCritSectRo);
    16131613        if (!pLock)
    16141614            pLock = &pVM->iom.s.EmtLock;
  • trunk/src/VBox/VMM/VMMR3/IOM.cpp

    r37452 r37466  
    159159     * Initialize the REM critical section.
    160160     */
    161     int rc = PDMR3CritSectInit(pVM, &pVM->iom.s.EmtLock, RT_SRC_POS, "IOM EMT Lock");
     161    int rc = PDMR3CritSectInit(pVM, &pVM->iom.s.EmtLock, RT_SRC_POS, "IOM Lock");
    162162    AssertRCReturn(rc, rc);
    163163
     
    17071707
    17081708/**
    1709  * For TM only!
    1710  *
    1711  * @returns Pointer to the critical section.
    1712  * @param   pVM                 The VM handle.
    1713  */
    1714 VMMR3DECL(PPDMCRITSECT) IOMR3GetCritSect(PVM pVM)
    1715 {
    1716     return &pVM->iom.s.EmtLock;
    1717 }
    1718 
    1719 
    1720 /**
    17211709 * Display a single MMIO range.
    17221710 *
  • trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r37443 r37466  
    366366        rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.CritSect, RT_SRC_POS, "PDM");
    367367    if (RT_SUCCESS(rc))
    368         rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.GiantDevCritSect, RT_SRC_POS, "Giant PDM Dev");
    369     if (RT_SUCCESS(rc))
    370368    {
    371369        rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.NopCritSect, RT_SRC_POS, "NOP");
     
    507505            pDevIns->pHlpRC             = pDevHlpRC;
    508506            pDevIns->pvInstanceDataRC   = MMHyperR3ToRC(pVM, pDevIns->pvInstanceDataR3);
    509             if (pDevIns->pCritSectR3)
    510                 pDevIns->pCritSectRC    = MMHyperR3ToRC(pVM, pDevIns->pCritSectR3);
     507            if (pDevIns->pCritSectRoR3)
     508                pDevIns->pCritSectRoRC  = MMHyperR3ToRC(pVM, pDevIns->pCritSectRoR3);
    511509            pDevIns->Internal.s.pVMRC   = pVM->pVMRC;
    512510            if (pDevIns->Internal.s.pPciBusR3)
  • trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp

    r37443 r37466  
    165165                pCritSect->pVMRC                     = pVM->pVMRC;
    166166                pCritSect->pvKey                     = pvKey;
     167                pCritSect->fAutomaticDefaultCritsect = false;
     168                pCritSect->fUsedByTimerOrSimilar     = false;
    167169                pCritSect->EventToSignal             = NIL_RTSEMEVENT;
    168170                pCritSect->pNext                     = pVM->pUVM->pdm.s.pCritSects;
     
    236238{
    237239    return pdmR3CritSectInitOne(pVM, &pCritSect->s, pDevIns, RT_SRC_POS_ARGS, pszNameFmt, va);
     240}
     241
     242
     243/**
     244 * Initializes the automatic default PDM critical section for a device.
     245 *
     246 * @returns VBox status code.
     247 * @param   pVM             The VM handle.
     248 * @param   pDevIns         Device instance.
     249 * @param   pCritSect       Pointer to the critical section.
     250 */
     251int pdmR3CritSectInitDeviceAuto(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
     252                                const char *pszNameFmt, ...)
     253{
     254    va_list va;
     255    va_start(va, pszNameFmt);
     256    int rc = pdmR3CritSectInitOne(pVM, &pCritSect->s, pDevIns, RT_SRC_POS_ARGS, pszNameFmt, va);
     257    if (RT_SUCCESS(rc))
     258        pCritSect->s.fAutomaticDefaultCritsect = true;
     259    va_end(va);
     260    return rc;
    238261}
    239262
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r37452 r37466  
    15831583             pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
    15841584    return pCritSect;
     1585}
     1586
     1587
     1588/** @interface_method_impl{PDMDEVHLPR3,pfnSetDeviceCritSect} */
     1589static DECLCALLBACK(int) pdmR3DevHlp_SetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
     1590{
     1591    /*
     1592     * Validate input.
     1593     *
     1594     * Note! We only allow the automatically created default critical section
     1595     *       to be replaced by this API.
     1596     */
     1597    PDMDEV_ASSERT_DEVINS(pDevIns);
     1598    AssertPtrReturn(pCritSect, VERR_INVALID_POINTER);
     1599    LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: pCritSect=%p (%s)\n",
     1600             pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pCritSect->s.pszName));
     1601    AssertReturn(PDMCritSectIsInitialized(pCritSect), VERR_INVALID_PARAMETER);
     1602    PVM pVM = pDevIns->Internal.s.pVMR3;
     1603    AssertReturn(pCritSect->s.pVMR3 == pVM, VERR_INVALID_PARAMETER);
     1604
     1605    VM_ASSERT_EMT(pVM);
     1606    VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
     1607
     1608    AssertReturn(pDevIns->pCritSectRoR3, VERR_INTERNAL_ERROR_4);
     1609    AssertReturn(pDevIns->pCritSectRoR3->s.fAutomaticDefaultCritsect, VERR_WRONG_ORDER);
     1610    AssertReturn(!pDevIns->pCritSectRoR3->s.fUsedByTimerOrSimilar, VERR_WRONG_ORDER);
     1611    AssertReturn(pDevIns->pCritSectRoR3 != pCritSect, VERR_INVALID_PARAMETER);
     1612
     1613    /*
     1614     * Replace the critical section and destroy the automatic default section.
     1615     */
     1616    PPDMCRITSECT pOldCritSect = pDevIns->pCritSectRoR3;
     1617    pDevIns->pCritSectRoR3 = pCritSect;
     1618    if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
     1619        pDevIns->pCritSectRoR0 = MMHyperCCToR0(pVM, pDevIns->pCritSectRoR3);
     1620    else
     1621        Assert(pDevIns->pCritSectRoR0 == NIL_RTRCPTR);
     1622
     1623    if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
     1624        pDevIns->pCritSectRoRC = MMHyperCCToRC(pVM, pDevIns->pCritSectRoR3);
     1625    else
     1626        Assert(pDevIns->pCritSectRoRC == NIL_RTRCPTR);
     1627
     1628    PDMR3CritSectDelete(pOldCritSect);
     1629    if (pDevIns->pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0))
     1630        MMHyperFree(pVM, pOldCritSect);
     1631    else
     1632        MMR3HeapFree(pOldCritSect);
     1633
     1634    LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
     1635    return VINF_SUCCESS;
    15851636}
    15861637
     
    32633314    pdmR3DevHlp_CritSectGetNopR0,
    32643315    pdmR3DevHlp_CritSectGetNopRC,
     3316    pdmR3DevHlp_SetDeviceCritSect,
    32653317    pdmR3DevHlp_ThreadCreate,
    32663318    pdmR3DevHlp_SetAsyncNotification,
     
    34783530    pdmR3DevHlp_CritSectGetNopR0,
    34793531    pdmR3DevHlp_CritSectGetNopRC,
     3532    pdmR3DevHlp_SetDeviceCritSect,
    34803533    pdmR3DevHlp_ThreadCreate,
    34813534    pdmR3DevHlp_SetAsyncNotification,
  • trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp

    r35810 r37466  
    288288
    289289        /*
    290          * Allocate the device instance.
     290         * Allocate the device instance and critical section.
    291291         */
    292292        AssertReturn(paDevs[i].pDev->cInstances < paDevs[i].pDev->pReg->cMaxInstances, VERR_PDM_TOO_MANY_DEVICE_INSTANCES);
     
    298298        else
    299299            rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_DEVICE, cb, (void **)&pDevIns);
    300         if (RT_FAILURE(rc))
    301         {
    302             AssertMsgFailed(("Failed to allocate %d bytes of instance data for device '%s'. rc=%Rrc\n",
    303                              cb, paDevs[i].pDev->pReg->szName, rc));
    304             return rc;
    305         }
     300        AssertLogRelMsgRCReturn(rc,
     301                                ("Failed to allocate %d bytes of instance data for device '%s'. rc=%Rrc\n",
     302                                cb, paDevs[i].pDev->pReg->szName, rc),
     303                                rc);
     304        PPDMCRITSECT pCritSect;
     305        if (paDevs[i].pDev->pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0))
     306            rc = MMHyperAlloc(pVM, sizeof(*pCritSect), 0, MM_TAG_PDM_DEVICE, (void **)&pCritSect);
     307        else
     308            rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_DEVICE, sizeof(*pCritSect), (void **)&pCritSect);
     309        AssertLogRelMsgRCReturn(rc, ("Failed to allocate a critical section for the device\n",  rc), rc);
    306310
    307311        /*
     
    335339        pDevIns->pvInstanceDataR0               = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0
    336340                                                ? MMHyperR3ToR0(pVM, pDevIns->pvInstanceDataR3) : NIL_RTR0PTR;
    337         //pDevIns->pCritSectR3                    = NULL;
    338         //pDevIns->pCritSectR0                    = NIL_RTR0PTR;
    339         //pDevIns->pCritSectRC                    = NIL_RTRCPTR;
     341
     342        pDevIns->pCritSectRoR3                  = pCritSect;
     343        pDevIns->pCritSectRoRC                  = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC
     344                                                ? MMHyperR3ToRC(pVM, pCritSect) : NIL_RTRCPTR;
     345        pDevIns->pCritSectRoR0                  = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0
     346                                                ? MMHyperR3ToR0(pVM, pCritSect) : NIL_RTR0PTR;
     347
     348        rc = pdmR3CritSectInitDeviceAuto(pVM, pDevIns, pCritSect, RT_SRC_POS,
     349                                         "%s#%u Auto", pDevIns->pReg->szName, pDevIns->iInstance);
     350        AssertLogRelRCReturn(rc, rc);
    340351
    341352        /*
     
    370381        Log(("PDM: Constructing device '%s' instance %d...\n", pDevIns->pReg->szName, pDevIns->iInstance));
    371382        rc = pDevIns->pReg->pfnConstruct(pDevIns, pDevIns->iInstance, pDevIns->pCfg);
    372         if (RT_SUCCESS(rc))
    373         {
    374             /*
    375              * Per-device critsect fun.
    376              */
    377             if (pDevIns->pCritSectR3)
    378             {
    379                 AssertStmt(PDMCritSectIsInitialized(pDevIns->pCritSectR3), rc = VERR_INTERNAL_ERROR_4);
    380                 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
    381                 {
    382                     pDevIns->pCritSectR0 = MMHyperCCToR0(pVM, pDevIns->pCritSectR3);
    383                     AssertStmt(pDevIns->pCritSectR0 != NIL_RTR0PTR, rc = VERR_INTERNAL_ERROR_3);
    384                 }
    385                 else
    386                     AssertStmt(pDevIns->pCritSectR0 == NIL_RTRCPTR, rc = VERR_INTERNAL_ERROR_2);
    387 
    388                 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
    389                 {
    390                     pDevIns->pCritSectRC = MMHyperCCToRC(pVM, pDevIns->pCritSectR3);
    391                     AssertStmt(pDevIns->pCritSectRC != NIL_RTRCPTR, rc = VERR_INTERNAL_ERROR_3);
    392                 }
    393                 else
    394                     AssertStmt(pDevIns->pCritSectRC == NIL_RTRCPTR, rc = VERR_INTERNAL_ERROR_2);
    395             }
    396             else
    397                 AssertStmt(   pDevIns->pCritSectRC == NIL_RTRCPTR
    398                            && pDevIns->pCritSectR0 == NIL_RTR0PTR,
    399                            rc = VERR_INTERNAL_ERROR_5);
    400         }
    401383        if (RT_FAILURE(rc))
    402384        {
    403385            LogRel(("PDM: Failed to construct '%s'/%d! %Rra\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    404386            paDevs[i].pDev->cInstances--;
    405             /* because we're damn lazy right now, we'll say that the destructor will be called even if the constructor fails. */
     387            /* Because we're damn lazy, the destructor will be called even if
     388               the constructor fails.  So, no unlinking. */
    406389            return rc == VERR_VERSION_MISMATCH ? VERR_PDM_DEVICE_VERSION_MISMATCH : rc;
    407390        }
     
    855838
    856839/**
     840 * References the critical section associated with a device for the use by a
     841 * timer or similar created by the device.
     842 *
     843 * @returns Pointer to the critical section.
     844 * @param   pVM             The VM handle.
     845 * @param   pDevIns         The device instance in question.
     846 *
     847 * @internal
     848 */
     849VMMR3_INT_DECL(PPDMCRITSECT) PDMR3DevGetCritSect(PVM pVM, PPDMDEVINS pDevIns)
     850{
     851    VM_ASSERT_EMT(pVM);
     852    VM_ASSERT_STATE(pVM, VMSTATE_CREATING);
     853    AssertPtr(pDevIns);
     854
     855    PPDMCRITSECT pCritSect = pDevIns->pCritSectRoR3;
     856    AssertPtr(pCritSect);
     857    pCritSect->s.fUsedByTimerOrSimilar = true;
     858
     859    return pCritSect;
     860}
     861
     862
     863/**
    857864 * Attaches a preconfigured driver to an existing device or driver instance.
    858865 *
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r37452 r37466  
    13321332        (*ppTimer)->pvUser          = pvUser;
    13331333        if (!(fFlags & TMTIMER_FLAGS_NO_CRIT_SECT))
    1334         {
    1335             if (pDevIns->pCritSectR3)
    1336                 (*ppTimer)->pCritSect = pDevIns->pCritSectR3;
    1337             else
    1338                 (*ppTimer)->pCritSect = IOMR3GetCritSect(pVM);
    1339         }
     1334            (*ppTimer)->pCritSect = PDMR3DevGetCritSect(pVM, pDevIns);
    13401335        Log(("TM: Created device timer %p clock %d callback %p '%s'\n", (*ppTimer), enmClock, pfnCallback, pszDesc));
    13411336    }
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r37443 r37466  
    268268    /** Pointer to the VM - GCPtr. */
    269269    PVMRC                           pVMRC;
     270    /** Set if this critical section is the automatically created default
     271     * section of a device.. */
     272    bool                            fAutomaticDefaultCritsect;
     273    /** Set if the critical section is used by a timer or similar.
     274     * See PDMR3DevGetCritSect.  */
     275    bool                            fUsedByTimerOrSimilar;
    270276    /** Alignment padding. */
    271     uint32_t                        padding;
     277    bool                            afPadding[2];
    272278    /** Event semaphore that is scheduled to be signaled upon leaving the
    273279     * critical section. This is Ring-3 only of course. */
     
    951957     * the PIC, APIC, IOAPIC and PCI devices plus some PDM functions. */
    952958    PDMCRITSECT                     CritSect;
    953 
    954     /** The giant PDM device lock.
    955      * This is a temporary measure and will be removed. */
    956     PDMCRITSECT                     GiantDevCritSect;
    957 
    958959    /** The NOP critical section.
    959960     * This is a dummy critical section that will not do any thread
     
    11261127void        pdmR3CritSectRelocate(PVM pVM);
    11271128int         pdmR3CritSectInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, va_list va);
     1129int         pdmR3CritSectInitDeviceAuto(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
     1130                                        const char *pszNameFmt, ...);
    11281131int         pdmR3CritSectDeleteDevice(PVM pVM, PPDMDEVINS pDevIns);
    11291132int         pdmR3CritSectInitDriver(PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...);
  • trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp

    r37452 r37466  
    291291    GEN_CHECK_SIZE(PDM);
    292292    GEN_CHECK_OFF(PDM, CritSect);
    293     GEN_CHECK_OFF(PDM, GiantDevCritSect);
    294293    GEN_CHECK_OFF(PDM, NopCritSect);
    295294    GEN_CHECK_OFF(PDM, pDevs);
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