VirtualBox

Changeset 87983 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 5, 2021 6:50:42 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
143096
Message:

DevHDA/StreamSetUp: Deal with buffer lists w/o IRQs too in the heuristics. Cap the max transfer period/size to 1/4th of a second to prevent the guest from eating up too much heap for the circular buffer. bugref:9890

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/HDAStream.cpp

    r87980 r87983  
    522522
    523523        /*
    524          * IFF the guest is using buffer IRQ, configure the timer to
    525          * the lowest common denominator of those IRQ periods.
    526          *
    527          * Otherwise, fall back on using default timer I/O Hz (set above).
     524         * If the guest doesn't use buffer IRQs or only has one, just split the total
     525         * buffer length in half and use that as timer heuristics.  That gives the
     526         * guest half a buffer to fill while we're processing the other half.
    528527         */
    529         if (cBufferIrqs > 0 && cbTransferHeuristics > 1)
    530         {
    531             pStreamShared->State.cbTransferSize  = cbTransferHeuristics;
    532             pStreamShared->State.cbTransferChunk = cbTransferHeuristics; /* no chunking */
     528        if (cBufferIrqs <= 1)
     529            cbTransferHeuristics = pStreamShared->u32CBL / 2;
     530
     531        /* Paranoia (fall back on I/O timer Hz if this happens). */
     532        if (cbTransferHeuristics >= 8)
     533        {
    533534            ASSERT_GUEST_LOGREL_MSG(DrvAudioHlpBytesIsAligned(cbTransferHeuristics, &pStreamR3->State.Mapping.PCMProps),
    534535                                    ("We arrived at a misaligned transfer size for stream #%RU8: %#x (%u)\n",
    535536                                     uSD, cbTransferHeuristics, cbTransferHeuristics));
    536537
    537             /* Convert to timer ticks. */
    538538            uint64_t const cTimerTicksPerSec = PDMDevHlpTimerGetFreq(pDevIns, pStreamShared->hTimer);
    539539            uint64_t const cbTransferPerSec  = RT_MAX(pStreamR3->State.Mapping.PCMProps.uHz * pStreamR3->State.Mapping.cbFrameSize,
    540540                                                      4096 /* zero div prevention: min is 6kHz, picked 4k in case I'm mistaken */);
    541541
     542            /* Make sure the period is 250ms (random value) or less, in case the guest
     543               want to play the whole "Der Ring des Nibelungen" cycle in one go.  Just
     544               halve the buffer till we get there. */
     545            while (cbTransferHeuristics > 1024 && cbTransferHeuristics > cbTransferPerSec / 4)
     546                cbTransferHeuristics = DrvAudioHlpBytesAlign(cbTransferHeuristics / 2, &pStreamR3->State.Mapping.PCMProps);
     547
     548            /* Set the transfer size per timer callout. (No chunking, so same.) */
     549            pStreamShared->State.cbTransferSize  = cbTransferHeuristics;
     550            pStreamShared->State.cbTransferChunk = cbTransferHeuristics;
     551            ASSERT_GUEST_LOGREL_MSG(DrvAudioHlpBytesIsAligned(cbTransferHeuristics, &pStreamR3->State.Mapping.PCMProps),
     552                                    ("We arrived at a misaligned transfer size for stream #%RU8: %#x (%u)\n",
     553                                     uSD, cbTransferHeuristics, cbTransferHeuristics));
     554
     555            /* Convert to timer ticks. */
    542556            pStreamShared->State.cTicksPerByte = (cTimerTicksPerSec + cbTransferPerSec / 2) / cbTransferPerSec;
    543557            AssertStmt(pStreamShared->State.cTicksPerByte, pStreamShared->State.cTicksPerByte = 4096);
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