VirtualBox

Changeset 64177 in vbox for trunk/src


Ignore:
Timestamp:
Oct 7, 2016 10:49:16 AM (8 years ago)
Author:
vboxsync
Message:

AHCI: Don't do the redo handling ourself but let the driver do it instead

File:
1 edited

Legend:

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

    r64176 r64177  
    243243/** Flag whether the request is stored on the stack. */
    244244#define AHCI_REQ_IS_ON_STACK RT_BIT_32(4)
    245 /** FLag whether this request transfers data from the device to the HBA or
     245/** Flag whether this request transfers data from the device to the HBA or
    246246 * the other way around .*/
    247247#define AHCI_REQ_XFER_2_HOST RT_BIT_32(5)
     
    35833583}
    35843584
    3585 /* -=-=-=-=- IMediaAsyncPort -=-=-=-=- */
    3586 
    3587 /** Makes a PAHCIPort out of a PPDMIMEDIAASYNCPORT. */
    3588 #define PDMIMEDIAASYNCPORT_2_PAHCIPORT(pInterface)    ( (PAHCIPort)((uintptr_t)pInterface - RT_OFFSETOF(AHCIPort, IPortAsync)) )
    3589 
    3590 static void ahciWarningDiskFull(PPDMDEVINS pDevIns)
    3591 {
    3592     int rc;
    3593     LogRel(("AHCI: Host disk full\n"));
    3594     rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevAHCI_DISKFULL",
    3595                                     N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space"));
    3596     AssertRC(rc);
    3597 }
    3598 
    3599 static void ahciWarningFileTooBig(PPDMDEVINS pDevIns)
    3600 {
    3601     int rc;
    3602     LogRel(("AHCI: File too big\n"));
    3603     rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevAHCI_FILETOOBIG",
    3604                                     N_("Host system reported that the file size limit of the host file system has been exceeded. VM execution is suspended. You need to move your virtual hard disk to a filesystem which allows bigger files"));
    3605     AssertRC(rc);
    3606 }
    3607 
    3608 static void ahciWarningISCSI(PPDMDEVINS pDevIns)
    3609 {
    3610     int rc;
    3611     LogRel(("AHCI: iSCSI target unavailable\n"));
    3612     rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevAHCI_ISCSIDOWN",
    3613                                     N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again"));
    3614     AssertRC(rc);
    3615 }
    3616 
    3617 static void ahciWarningDekMissing(PPDMDEVINS pDevIns)
    3618 {
    3619     LogRel(("AHCI#%u: DEK is missing\n", pDevIns->iInstance));
    3620     int rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
    3621                                         N_("AHCI: The DEK for this disk is missing"));
    3622     AssertRC(rc);
    3623 }
    3624 
    3625 bool ahciIsRedoSetWarning(PAHCIPort pAhciPort, int rc)
    3626 {
    3627     if (rc == VERR_DISK_FULL)
    3628     {
    3629         if (ASMAtomicCmpXchgBool(&pAhciPort->fRedo, true, false))
    3630             ahciWarningDiskFull(pAhciPort->CTX_SUFF(pDevIns));
    3631         return true;
    3632     }
    3633     if (rc == VERR_FILE_TOO_BIG)
    3634     {
    3635         if (ASMAtomicCmpXchgBool(&pAhciPort->fRedo, true, false))
    3636             ahciWarningFileTooBig(pAhciPort->CTX_SUFF(pDevIns));
    3637         return true;
    3638     }
    3639     if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED)
    3640     {
    3641         /* iSCSI connection abort (first error) or failure to reestablish
    3642          * connection (second error). Pause VM. On resume we'll retry. */
    3643         if (ASMAtomicCmpXchgBool(&pAhciPort->fRedo, true, false))
    3644             ahciWarningISCSI(pAhciPort->CTX_SUFF(pDevIns));
    3645         return true;
    3646     }
    3647     if (rc == VERR_VD_DEK_MISSING)
    3648     {
    3649         if (ASMAtomicCmpXchgBool(&pAhciPort->fRedo, true, false))
    3650             ahciWarningDekMissing(pAhciPort->CTX_SUFF(pDevIns));
    3651         return true;
    3652     }
    3653 
    3654     return false;
    3655 }
    3656 
    36573585/**
    36583586 * Creates the array of ranges to trim.
     
    37463674
    37473675    int rc = pAhciPort->pDrvMediaEx->pfnIoReqAlloc(pAhciPort->pDrvMediaEx, &hIoReq, (void **)&pAhciReq,
    3748                                                    uTag, PDMIMEDIAEX_F_DEFAULT);
     3676                                                   uTag, PDMIMEDIAEX_F_SUSPEND_ON_RECOVERABLE_ERR);
    37493677    if (RT_SUCCESS(rc))
    37503678    {
     
    37853713static bool ahciTransferComplete(PAHCIPort pAhciPort, PAHCIREQ pAhciReq, int rcReq)
    37863714{
    3787     bool fRedo = false;
    37883715    bool fCanceled = false;
    37893716
     
    38343761            }
    38353762
    3836             fRedo = ahciIsRedoSetWarning(pAhciPort, rcReq);
    3837             if (!fRedo)
    3838             {
    3839                 ahciReqSetStatus(pAhciReq, ID_ERR, ATA_STAT_READY | ATA_STAT_ERR);
    3840                 /*
    3841                  * We have to duplicate the request here as the underlying I/O
    3842                  * request will be freed later.
    3843                  */
    3844                 PAHCIREQ pReqDup = (PAHCIREQ)RTMemDup(pAhciReq, sizeof(AHCIREQ));
    3845                 if (   pReqDup
    3846                     && !ASMAtomicCmpXchgPtr(&pAhciPort->pTaskErr, pReqDup, NULL))
    3847                     RTMemFree(pReqDup);
    3848             }
    3849             else
    3850                 ASMAtomicOrU32(&pAhciPort->u32TasksRedo, RT_BIT_32(pAhciReq->uTag));
     3763            ahciReqSetStatus(pAhciReq, ID_ERR, ATA_STAT_READY | ATA_STAT_ERR);
     3764            /*
     3765             * We have to duplicate the request here as the underlying I/O
     3766             * request will be freed later.
     3767             */
     3768            PAHCIREQ pReqDup = (PAHCIREQ)RTMemDup(pAhciReq, sizeof(AHCIREQ));
     3769            if (   pReqDup
     3770                && !ASMAtomicCmpXchgPtr(&pAhciPort->pTaskErr, pReqDup, NULL))
     3771                RTMemFree(pReqDup);
    38513772        }
    38523773        else
     
    39053826
    39063827        ahciR3ReqFree(pAhciPort, pAhciReq);
    3907         if (!fRedo)
    3908         {
    3909 
    3910             /* Post a PIO setup FIS first if this is a PIO command which transfers data. */
    3911             if (fFlags & AHCI_REQ_PIO_DATA)
    3912                 ahciSendPioSetupFis(pAhciPort, cbTransfer, &cmdFis[0], fRead, false /* fInterrupt */);
    3913 
    3914             if (fFlags & AHCI_REQ_CLEAR_SACT)
    3915             {
    3916                 if (RT_SUCCESS(rcReq) && !ASMAtomicReadPtrT(&pAhciPort->pTaskErr, PAHCIREQ))
    3917                     ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, RT_BIT_32(uTag));
    3918             }
    3919 
    3920             if (fFlags & AHCI_REQ_IS_QUEUED)
    3921             {
    3922                 /*
    3923                  * Always raise an interrupt after task completion; delaying
    3924                  * this (interrupt coalescing) increases latency and has a significant
    3925                  * impact on performance (see @bugref{5071})
    3926                  */
    3927                 ahciSendSDBFis(pAhciPort, 0, true);
    3928             }
    3929             else
    3930                 ahciSendD2HFis(pAhciPort, uTag, &cmdFis[0], true);
    3931         }
     3828
     3829        /* Post a PIO setup FIS first if this is a PIO command which transfers data. */
     3830        if (fFlags & AHCI_REQ_PIO_DATA)
     3831            ahciSendPioSetupFis(pAhciPort, cbTransfer, &cmdFis[0], fRead, false /* fInterrupt */);
     3832
     3833        if (fFlags & AHCI_REQ_CLEAR_SACT)
     3834        {
     3835            if (RT_SUCCESS(rcReq) && !ASMAtomicReadPtrT(&pAhciPort->pTaskErr, PAHCIREQ))
     3836                ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, RT_BIT_32(uTag));
     3837        }
     3838
     3839        if (fFlags & AHCI_REQ_IS_QUEUED)
     3840        {
     3841            /*
     3842             * Always raise an interrupt after task completion; delaying
     3843             * this (interrupt coalescing) increases latency and has a significant
     3844             * impact on performance (see @bugref{5071})
     3845             */
     3846            ahciSendSDBFis(pAhciPort, 0, true);
     3847        }
     3848        else
     3849            ahciSendD2HFis(pAhciPort, uTag, &cmdFis[0], true);
    39323850    }
    39333851    else
     
    40653983                                                  void *pvIoReqAlloc, PDMMEDIAEXIOREQSTATE enmState)
    40663984{
    4067     RT_NOREF(hIoReq);
     3985    RT_NOREF2(hIoReq, pvIoReqAlloc);
    40683986    PAHCIPort pAhciPort = RT_FROM_MEMBER(pInterface, AHCIPort, IMediaExPort);
    4069     PAHCIREQ pIoReq = (PAHCIREQ)pvIoReqAlloc;
    4070 
    4071     RT_NOREF3(pAhciPort, pIoReq, enmState);
    4072     AssertLogRelMsgFailed(("This should not be hit because I/O requests should not be suspended\n"));
     3987
     3988    switch (enmState)
     3989    {
     3990        case PDMMEDIAEXIOREQSTATE_SUSPENDED:
     3991        {
     3992            /* Make sure the request is not accounted for so the VM can suspend successfully. */
     3993            uint32_t cTasksActive = ASMAtomicDecU32(&pAhciPort->cTasksActive);
     3994            if (!cTasksActive && pAhciPort->pAhciR3->fSignalIdle)
     3995                PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3);
     3996            break;
     3997        }
     3998        case PDMMEDIAEXIOREQSTATE_ACTIVE:
     3999            /* Make sure the request is accounted for so the VM suspends only when the request is complete. */
     4000            ASMAtomicIncU32(&pAhciPort->cTasksActive);
     4001            break;
     4002        default:
     4003            AssertMsgFailed(("Invalid request state given %u\n", enmState));
     4004    }
    40734005}
    40744006
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