VirtualBox

Changeset 39828 in vbox


Ignore:
Timestamp:
Jan 22, 2012 11:19:14 AM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
75832
Message:

AHCI: Don't always allocate new memory for the data buffers but reuse it when possible. Also use RTMemPageAlloc for page aligned memory to avoid bounce buffers during I/O

File:
1 edited

Legend:

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

    r39655 r39828  
    5959#include "VBoxDD.h"
    6060
    61 #define AHCI_MAX_NR_PORTS_IMPL 30
    62 #define AHCI_NR_COMMAND_SLOTS 32
     61/** Maximum number of ports available.
     62 * Spec defines 32 but we have one allocated for command completion coalescing
     63 * and another for a reserved future feature.
     64 */
     65#define AHCI_MAX_NR_PORTS_IMPL  30
     66/** Maximum number of command slots available. */
     67#define AHCI_NR_COMMAND_SLOTS   32
     68
     69#define AHCI_MAX_ALLOC_TOO_MUCH 20
    6370
    6471/** The current saved state version. */
     
    286293    /** Flags for this task. */
    287294    uint32_t                   fFlags;
     295    /** Additional memory allocation for this task. */
     296    void                      *pvAlloc;
     297    /** Siize of the allocation. */
     298    size_t                     cbAlloc;
     299    /** Number of times we had too much memory allocated for the request. */
     300    unsigned                   cAllocTooMuch;
    288301    /** Data dependent on the transfer direction. */
    289302    union
     
    51405153
    51415154/**
     5155 * Allocates memory for the given request using already allocated memory if possible.
     5156 *
     5157 * @returns Pointer to the memory or NULL on failure
     5158 * @param   pAhciReq    The request to allocate memory for.
     5159 * @param   cb          The amount of memory to allocate.
     5160 */
     5161static void *ahciReqMemAlloc(PAHCIREQ pAhciReq, size_t cb)
     5162{
     5163    if (pAhciReq->cbAlloc > cb)
     5164    {
     5165        pAhciReq->cAllocTooMuch++;
     5166    }
     5167    else if (pAhciReq->cbAlloc < cb)
     5168    {
     5169        if (pAhciReq->cbAlloc)
     5170            RTMemPageFree(pAhciReq->pvAlloc, pAhciReq->cbAlloc);
     5171
     5172        pAhciReq->pvAlloc = RTMemPageAlloc(RT_ALIGN_Z(cb, _4K));
     5173        pAhciReq->cAllocTooMuch = 0;
     5174    }
     5175
     5176    return pAhciReq->pvAlloc;
     5177}
     5178
     5179/**
     5180 * Frees memory allocated for the given request.
     5181 *
     5182 * @returns nothing.
     5183 * @param   pAhciReq    The request.
     5184 */
     5185static void ahciReqMemFree(PAHCIREQ pAhciReq)
     5186{
     5187    if (pAhciReq->cAllocTooMuch >= AHCI_MAX_ALLOC_TOO_MUCH)
     5188    {
     5189        RTMemPageFree(pAhciReq->pvAlloc, pAhciReq->cbAlloc);
     5190        pAhciReq->cbAlloc = 0;
     5191        pAhciReq->cAllocTooMuch = 0;
     5192    }
     5193}
     5194
     5195/**
    51425196 * Copies a data buffer into the S/G buffer set up by the guest.
    51435197 *
     
    52585312              ("Allocating I/O memory for a non I/O request is not allowed\n"));
    52595313
    5260     pAhciReq->u.Io.DataSeg.pvSeg = RTMemAllocZ(cbTransfer);
     5314    pAhciReq->u.Io.DataSeg.pvSeg = ahciReqMemAlloc(pAhciReq, cbTransfer);
    52615315    if (!pAhciReq->u.Io.DataSeg.pvSeg)
    52625316        return VERR_NO_MEMORY;
     
    53005354    }
    53015355
    5302     RTMemFree(pAhciReq->u.Io.DataSeg.pvSeg);
     5356    ahciReqMemFree(pAhciReq);
    53035357    pAhciReq->u.Io.DataSeg.pvSeg = NULL;
    53045358    pAhciReq->u.Io.DataSeg.cbSeg = 0;
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