VirtualBox

Changeset 81751 in vbox for trunk/src/VBox/Devices/Storage


Ignore:
Timestamp:
Nov 8, 2019 3:01:34 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
134539
Message:

DevLsiLogicSCSI: Replaced the three dynamically allocated queues with static arrays in the device instance data. The queue size can be configured by VBoxInternal trickery, so we'll typically always be using the defaults of 256+1, so no real need to use the hyper heap here (we want to avoid it due to cross ring pointer resolving fun). bugref:9218

Location:
trunk/src/VBox/Devices/Storage
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r81745 r81751  
    269269    uint32_t              iDiagnosticAccess;
    270270
    271     /** Number entries allocated for the reply queue. */
     271    /** Number entries configured for the reply queue. */
    272272    uint32_t              cReplyQueueEntries;
    273     /** Number entries allocated for the outstanding request queue. */
     273    /** Number entries configured for the outstanding request queue. */
    274274    uint32_t              cRequestQueueEntries;
    275 
    276275
    277276    /** Critical section protecting the reply post queue. */
     
    286285    PDMCRITSECT           ReplyFreeQueueWriteCritSect;
    287286
    288     /** Pointer to the start of the reply free queue - R3. */
    289     R3PTRTYPE(volatile uint32_t *) pReplyFreeQueueBaseR3;
    290     /** Pointer to the start of the reply post queue - R3. */
    291     R3PTRTYPE(volatile uint32_t *) pReplyPostQueueBaseR3;
    292     /** Pointer to the start of the request queue - R3. */
    293     R3PTRTYPE(volatile uint32_t *) pRequestQueueBaseR3;
    294 
    295     /** Pointer to the start of the reply queue - R0. */
    296     R0PTRTYPE(volatile uint32_t *) pReplyFreeQueueBaseR0;
    297     /** Pointer to the start of the reply queue - R0. */
    298     R0PTRTYPE(volatile uint32_t *) pReplyPostQueueBaseR0;
    299     /** Pointer to the start of the request queue - R0. */
    300     R0PTRTYPE(volatile uint32_t *) pRequestQueueBaseR0;
    301 
    302     /** Pointer to the start of the reply queue - RC. */
    303     RCPTRTYPE(volatile uint32_t *) pReplyFreeQueueBaseRC;
    304     /** Pointer to the start of the reply queue - RC. */
    305     RCPTRTYPE(volatile uint32_t *) pReplyPostQueueBaseRC;
    306     /** Pointer to the start of the request queue - RC. */
    307     RCPTRTYPE(volatile uint32_t *) pRequestQueueBaseRC;
    308     /** End these RC pointers on a 64-bit boundrary. */
    309     RTRCPTR                        RCPtrPadding1;
     287    /** The reply free qeueue (only the first cReplyQueueEntries are used). */
     288    uint32_t volatile       aReplyFreeQueue[LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX];
     289    /** The reply post qeueue (only the first cReplyQueueEntries are used). */
     290    uint32_t volatile       aReplyPostQueue[LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX];
     291    /** The request qeueue (only the first cRequestQueueEntries are used). */
     292    uint32_t volatile       aRequestQueue[LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MAX];
    310293
    311294    /** Next free entry in the reply queue the guest can write a address to. */
     
    673656
    674657    /* We have a context reply. */
    675     ASMAtomicWriteU32(&pThis->CTX_SUFF(pReplyPostQueueBase)[pThis->uReplyPostQueueNextEntryFreeWrite], u32MessageContext);
     658    ASMAtomicWriteU32(&pThis->aReplyPostQueue[pThis->uReplyPostQueueNextEntryFreeWrite], u32MessageContext);
    676659    ASMAtomicIncU32(&pThis->uReplyPostQueueNextEntryFreeWrite);
    677660    pThis->uReplyPostQueueNextEntryFreeWrite %= pThis->cReplyQueueEntries;
     
    729712        }
    730713
    731         uint32_t u32ReplyFrameAddressLow = pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead];
     714        uint32_t u32ReplyFrameAddressLow = pThis->aReplyFreeQueue[pThis->uReplyFreeQueueNextAddressRead];
    732715
    733716        pThis->uReplyFreeQueueNextAddressRead++;
     
    757740
    758741        /* We have a address reply. Set the 31th bit to indicate that. */
    759         ASMAtomicWriteU32(&pThis->CTX_SUFF(pReplyPostQueueBase)[pThis->uReplyPostQueueNextEntryFreeWrite],
     742        ASMAtomicWriteU32(&pThis->aReplyPostQueue[pThis->uReplyPostQueueNextEntryFreeWrite],
    760743                          RT_BIT(31) | (u32ReplyFrameAddressLow >> 1));
    761744        ASMAtomicIncU32(&pThis->uReplyPostQueueNextEntryFreeWrite);
     
    12781261                return rc;
    12791262            /* Add the entry to the reply free queue. */
    1280             ASMAtomicWriteU32(&pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextEntryFreeWrite], u32);
     1263            ASMAtomicWriteU32(&pThis->aReplyFreeQueue[pThis->uReplyFreeQueueNextEntryFreeWrite], u32);
    12811264            pThis->uReplyFreeQueueNextEntryFreeWrite++;
    12821265            pThis->uReplyFreeQueueNextEntryFreeWrite %= pThis->cReplyQueueEntries;
     
    12921275            uint32_t uNextWrite = ASMAtomicReadU32(&pThis->uRequestQueueNextEntryFreeWrite);
    12931276
    1294             ASMAtomicWriteU32(&pThis->CTX_SUFF(pRequestQueueBase)[uNextWrite], u32);
     1277            ASMAtomicWriteU32(&pThis->aRequestQueue[uNextWrite], u32);
    12951278
    12961279            /*
     
    15571540            if (idxReplyPostQueueWrite != idxReplyPostQueueRead)
    15581541            {
    1559                 u32 = pThis->CTX_SUFF(pReplyPostQueueBase)[idxReplyPostQueueRead];
     1542                u32 = pThis->aReplyPostQueue[idxReplyPostQueueRead];
    15601543                idxReplyPostQueueRead++;
    15611544                idxReplyPostQueueRead %= pThis->cReplyQueueEntries;
     
    16161599                    if (pThis->uReplyFreeQueueNextEntryFreeWrite != pThis->uReplyFreeQueueNextAddressRead)
    16171600                    {
    1618                         u32 |= pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead] & UINT32_C(0xffff);
     1601                        u32 |= pThis->aReplyFreeQueue[pThis->uReplyFreeQueueNextAddressRead] & UINT32_C(0xffff);
    16191602                        pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH;
    16201603                        lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
     
    16221605                    break;
    16231606                case LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH:
    1624                     u32 |= pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead] >> 16;
     1607                    u32 |= pThis->aReplyFreeQueue[pThis->uReplyFreeQueueNextAddressRead] >> 16;
    16251608                    pThis->uReplyFreeQueueNextAddressRead++;
    16261609                    pThis->uReplyFreeQueueNextAddressRead %= pThis->cReplyQueueEntries;
     
    41714154    {
    41724155        for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++)
    4173             pHlp->pfnPrintf(pHlp, "RFQ[%u]=%#x\n", i, pThis->pReplyFreeQueueBaseR3[i]);
     4156            pHlp->pfnPrintf(pHlp, "RFQ[%u]=%#x\n", i, pThis->aReplyFreeQueue[i]);
    41744157
    41754158        pHlp->pfnPrintf(pHlp, "\n");
    41764159
    41774160        for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++)
    4178             pHlp->pfnPrintf(pHlp, "RPQ[%u]=%#x\n", i, pThis->pReplyPostQueueBaseR3[i]);
     4161            pHlp->pfnPrintf(pHlp, "RPQ[%u]=%#x\n", i, pThis->aReplyPostQueue[i]);
    41794162
    41804163        pHlp->pfnPrintf(pHlp, "\n");
    41814164
    41824165        for (unsigned i = 0; i < pThis->cRequestQueueEntries; i++)
    4183             pHlp->pfnPrintf(pHlp, "ReqQ[%u]=%#x\n", i, pThis->pRequestQueueBaseR3[i]);
     4166            pHlp->pfnPrintf(pHlp, "ReqQ[%u]=%#x\n", i, pThis->aRequestQueue[i]);
    41844167    }
    41854168
     
    41964179                        i, pDevice->pDrvBase != NULL, pDevice->cOutstandingRequests);
    41974180    }
    4198 }
    4199 
    4200 /**
    4201  * Allocate the queues.
    4202  *
    4203  * @returns VBox status code.
    4204  *
    4205  * @param   pThis       Pointer to the LsiLogic device state.
    4206  */
    4207 static int lsilogicR3QueuesAlloc(PLSILOGICSCSI pThis)
    4208 {
    4209     PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
    4210     uint32_t cbQueues;
    4211 
    4212     Assert(!pThis->pReplyFreeQueueBaseR3);
    4213 
    4214     cbQueues  = 2*pThis->cReplyQueueEntries * sizeof(uint32_t);
    4215     cbQueues += pThis->cRequestQueueEntries * sizeof(uint32_t);
    4216     int rc = MMHyperAlloc(pVM, cbQueues, 1, MM_TAG_PDM_DEVICE_USER,
    4217                           (void **)&pThis->pReplyFreeQueueBaseR3);
    4218     if (RT_FAILURE(rc))
    4219         return VERR_NO_MEMORY;
    4220     pThis->pReplyFreeQueueBaseR0 = MMHyperR3ToR0(pVM, (void *)pThis->pReplyFreeQueueBaseR3);
    4221     pThis->pReplyFreeQueueBaseRC = MMHyperR3ToRC(pVM, (void *)pThis->pReplyFreeQueueBaseR3);
    4222 
    4223     pThis->pReplyPostQueueBaseR3 = pThis->pReplyFreeQueueBaseR3 + pThis->cReplyQueueEntries;
    4224     pThis->pReplyPostQueueBaseR0 = MMHyperR3ToR0(pVM, (void *)pThis->pReplyPostQueueBaseR3);
    4225     pThis->pReplyPostQueueBaseRC = MMHyperR3ToRC(pVM, (void *)pThis->pReplyPostQueueBaseR3);
    4226 
    4227     pThis->pRequestQueueBaseR3   = pThis->pReplyPostQueueBaseR3 + pThis->cReplyQueueEntries;
    4228     pThis->pRequestQueueBaseR0   = MMHyperR3ToR0(pVM, (void *)pThis->pRequestQueueBaseR3);
    4229     pThis->pRequestQueueBaseRC   = MMHyperR3ToRC(pVM, (void *)pThis->pRequestQueueBaseR3);
    4230 
    4231     return VINF_SUCCESS;
    4232 }
    4233 
    4234 /**
    4235  * Free the hyper memory used or the queues.
    4236  *
    4237  * @returns nothing.
    4238  *
    4239  * @param   pThis       Pointer to the LsiLogic device state.
    4240  */
    4241 static void lsilogicR3QueuesFree(PLSILOGICSCSI pThis)
    4242 {
    4243     PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
    4244     int rc = VINF_SUCCESS;
    4245 
    4246     AssertPtr(pThis->pReplyFreeQueueBaseR3);
    4247 
    4248     rc = MMHyperFree(pVM, (void *)pThis->pReplyFreeQueueBaseR3);
    4249     AssertRC(rc);
    4250 
    4251     pThis->pReplyFreeQueueBaseR3 = NULL;
    4252     pThis->pReplyPostQueueBaseR3 = NULL;
    4253     pThis->pRequestQueueBaseR3   = NULL;
    42544181}
    42554182
     
    42974224        {
    42984225            MptRequestUnion GuestRequest;
    4299             uint32_t  u32RequestMessageFrameDesc = pThis->CTX_SUFF(pRequestQueueBase)[pThis->uRequestQueueNextAddressRead];
     4226            uint32_t  u32RequestMessageFrameDesc = pThis->aRequestQueue[pThis->uRequestQueueNextAddressRead];
    43004227            RTGCPHYS  GCPhysMessageFrameAddr = LSILOGIC_RTGCPHYS_FROM_U32(pThis->u32HostMFAHighAddr,
    43014228                                                                          (u32RequestMessageFrameDesc & ~0x07));
     
    44684395                    {
    44694396                        /* Write only the lower 32bit part of the address. */
    4470                         ASMAtomicWriteU32(&pThis->CTX_SUFF(pRequestQueueBase)[pThis->uRequestQueueNextEntryFreeWrite],
     4397                        ASMAtomicWriteU32(&pThis->aRequestQueue[pThis->uRequestQueueNextEntryFreeWrite],
    44714398                                          pReq->GCPhysMessageFrameAddr & UINT32_C(0xffffffff));
    44724399
     
    45254452
    45264453    for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++)
    4527         pHlp->pfnSSMPutU32(pSSM, pThis->pReplyFreeQueueBaseR3[i]);
     4454        pHlp->pfnSSMPutU32(pSSM, pThis->aReplyFreeQueue[i]);
    45284455    for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++)
    4529         pHlp->pfnSSMPutU32(pSSM, pThis->pReplyPostQueueBaseR3[i]);
     4456        pHlp->pfnSSMPutU32(pSSM, pThis->aReplyPostQueue[i]);
    45304457    for (unsigned i = 0; i < pThis->cRequestQueueEntries; i++)
    4531         pHlp->pfnSSMPutU32(pSSM, pThis->pRequestQueueBaseR3[i]);
     4458        pHlp->pfnSSMPutU32(pSSM, pThis->aRequestQueue[i]);
    45324459
    45334460    pHlp->pfnSSMPutU16(pSSM, pThis->u16NextHandle);
     
    47484675        || cRequestQueueEntries != pThis->cRequestQueueEntries)
    47494676    {
    4750         LogFlow(("Reallocating queues cReplyQueueEntries=%u cRequestQueuEntries=%u\n",
    4751                  cReplyQueueEntries, cRequestQueueEntries));
    4752         lsilogicR3QueuesFree(pThis);
     4677        LogRel(("Changing queue sizes: cReplyQueueEntries=%u cRequestQueuEntries=%u\n", cReplyQueueEntries, cRequestQueueEntries));
     4678        if (   cReplyQueueEntries   > RT_ELEMENTS(pThis->aReplyFreeQueue)
     4679            || cReplyQueueEntries   <  LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN
     4680            || cRequestQueueEntries > RT_ELEMENTS(pThis->aRequestQueue)
     4681            || cRequestQueueEntries <  LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN)
     4682            return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Out of bounds: cReplyQueueEntries=%u cRequestQueueEntries=%u"),
     4683                                           cReplyQueueEntries, cRequestQueueEntries);
    47534684        pThis->cReplyQueueEntries = cReplyQueueEntries;
    47544685        pThis->cRequestQueueEntries = cRequestQueueEntries;
    4755         rc = lsilogicR3QueuesAlloc(pThis);
    4756         if (RT_FAILURE(rc))
    4757             return rc;
    47584686    }
    47594687
     
    47754703            return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch: Expected SPI SCSI controller"));
    47764704
    4777         pHlp->pfnSSMGetMem(pSSM, &ConfigPagesV2,
    4778                     sizeof(MptConfigurationPagesSupported_SSM_V2));
     4705        pHlp->pfnSSMGetMem(pSSM, &ConfigPagesV2, sizeof(MptConfigurationPagesSupported_SSM_V2));
    47794706
    47804707        pPages->ManufacturingPage0 = ConfigPagesV2.ManufacturingPage0;
     
    48104737        /* Queue content */
    48114738        for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++)
    4812             pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->pReplyFreeQueueBaseR3[i]);
     4739            pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->aReplyFreeQueue[i]);
    48134740        for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++)
    4814             pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->pReplyPostQueueBaseR3[i]);
     4741            pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->aReplyPostQueue[i]);
    48154742        for (unsigned i = 0; i < pThis->cRequestQueueEntries; i++)
    4816             pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->pRequestQueueBaseR3[i]);
     4743            pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->aRequestQueue[i]);
    48174744
    48184745        pHlp->pfnSSMGetU16(pSSM, &pThis->u16NextHandle);
     
    52795206{
    52805207    PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI);
    5281 
    5282     pThis->pDevInsRC        = PDMDEVINS_2_RCPTR(pDevIns);
    5283 
    5284     /* Relocate queues. */
    5285     pThis->pReplyFreeQueueBaseRC += offDelta;
    5286     pThis->pReplyPostQueueBaseRC += offDelta;
    5287     pThis->pRequestQueueBaseRC   += offDelta;
     5208    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
     5209    RT_NOREF(offDelta);
    52885210}
    52895211
     
    53615283        return PDMDEV_SET_ERROR(pDevIns, rc,
    53625284                                N_("LsiLogic configuration error: failed to read ReplyQueue as integer"));
     5285    if (   pThis->cReplyQueueEntries < LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN
     5286        || pThis->cReplyQueueEntries > LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX - 1 /* see +1 later in the function */)
     5287        return PDMDevHlpVMSetError(pDevIns, VERR_OUT_OF_RANGE, RT_SRC_POS,
     5288                                   N_("LsiLogic configuration error: 'ReplyQueueDepth' = %u is out of ranage (%u..%u)"),
     5289                                   pThis->cReplyQueueEntries, LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN,
     5290                                   LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX - 1);
    53635291    Log(("%s: ReplyQueueDepth=%u\n", __FUNCTION__, pThis->cReplyQueueEntries));
    53645292
     
    53665294                                  &pThis->cRequestQueueEntries, LSILOGICSCSI_REQUEST_QUEUE_DEPTH_DEFAULT);
    53675295    if (RT_FAILURE(rc))
    5368         return PDMDEV_SET_ERROR(pDevIns, rc,
    5369                                 N_("LsiLogic configuration error: failed to read RequestQueue as integer"));
     5296        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic configuration error: failed to read RequestQueue as integer"));
     5297    if (   pThis->cRequestQueueEntries < LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN
     5298        || pThis->cRequestQueueEntries > LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MAX - 1 /* see +1 later in the function */)
     5299        return PDMDevHlpVMSetError(pDevIns, VERR_OUT_OF_RANGE, RT_SRC_POS,
     5300                                   N_("LsiLogic configuration error: 'RequestQueue' = %u is out of ranage (%u..%u)"),
     5301                                   pThis->cRequestQueueEntries, LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN,
     5302                                   LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN - 1);
    53705303    Log(("%s: RequestQueueDepth=%u\n", __FUNCTION__, pThis->cRequestQueueEntries));
    53715304
     
    55155448     */
    55165449    pThis->cReplyQueueEntries++;
     5450    AssertLogRelReturn(pThis->cReplyQueueEntries <= RT_ELEMENTS(pThis->aReplyFreeQueue), VERR_INTERNAL_ERROR_3);
     5451    AssertLogRelReturn(pThis->cReplyQueueEntries <= RT_ELEMENTS(pThis->aReplyPostQueue), VERR_INTERNAL_ERROR_3);
     5452
    55175453    pThis->cRequestQueueEntries++;
     5454    AssertLogRelReturn(pThis->cRequestQueueEntries <= RT_ELEMENTS(pThis->aRequestQueue), VERR_INTERNAL_ERROR_3);
    55185455
    55195456    /*
    5520      * Allocate memory for the queues.
     5457     * Device states.
    55215458     */
    5522     rc = lsilogicR3QueuesAlloc(pThis);
    5523     if (RT_FAILURE(rc))
    5524         return rc;
    5525 
    55265459    if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI)
    55275460        pThis->cDeviceStates = pThis->cPorts * LSILOGICSCSI_PCI_SPI_DEVICES_PER_BUS_MAX;
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.h

    r81744 r81751  
    3232#define LSILOGIC_SAS_BIOS_IO_PORT   0x438
    3333
    34 #define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_DEFAULT 256
    35 #define LSILOGICSCSI_REPLY_QUEUE_DEPTH_DEFAULT   256
     34#define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN        8       /**< (bird just picked this out thin air) */
     35#define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MAX        1024    /**< (bird just picked this out thin air) */
     36#define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_DEFAULT    256
     37
     38#define LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN          8       /**< (bird just picked this out thin air) */
     39#define LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX          1024    /**< (bird just picked this out thin air) */
     40#define LSILOGICSCSI_REPLY_QUEUE_DEPTH_DEFAULT      256
    3641
    3742#define LSILOGICSCSI_MAXIMUM_CHAIN_DEPTH 3
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