VirtualBox

Changeset 24641 in vbox for trunk/src


Ignore:
Timestamp:
Nov 13, 2009 4:20:15 PM (15 years ago)
Author:
vboxsync
Message:

#3987: Virtio: TX delay timer for batching, fixed assertion on state loading, minor GC improvements.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DevVirtioNet.cpp

    r24623 r24641  
    5757//- TODO: Move to Virtio.h ----------------------------------------------------
    5858
     59/*
     60 * The saved state version is changed if either common or any of specific
     61 * parts are changed. That is, it is perfectly possible that the version
     62 * of saved vnet state will increase as a result of change in vblk structure
     63 * for example.
     64 */
     65#define VIRTIO_SAVEDSTATE_VERSION_3_1_BETA1 1
     66#define VIRTIO_SAVEDSTATE_VERSION           2
     67
    5968#define VPCI_F_NOTIFY_ON_EMPTY 0x01000000
    6069#define VPCI_F_BAD_FEATURE     0x40000000
     
    158167};
    159168
    160 #define VIRTIO_NET_NQUEUES 3
    161169#define VIRTIO_MAX_NQUEUES 3
     170#define VNET_NQUEUES       3
    162171
    163172struct VPCIState_st
     
    197206    uint8_t                uISR;                   /**< Interrupt Status Register. */
    198207
    199 #if HC_ARCH_BITS == 64
    200     uint32_t               padding3;
    201 #endif
    202 
     208// #if HC_ARCH_BITS == 64
     209//     uint32_t               padding3;
     210// #endif
     211
     212    uint32_t               nQueues;       /**< Actual number of queues used. */
    203213    VQUEUE                 Queues[VIRTIO_MAX_NQUEUES];
    204214
     
    253263    /*  Vendor  Device SSVendor SubSys             Class   NQ Name          Instance */
    254264    { /* Virtio Network Device */
    255         0x1AF4, 0x1000, 0x1AF4, 1 + VIRTIO_NET_ID, 0x0200, VIRTIO_NET_NQUEUES,
     265        0x1AF4, 0x1000, 0x1AF4, 1 + VIRTIO_NET_ID, 0x0200, VNET_NQUEUES,
    256266                                                              "virtio-net", "vnet%d",
    257267        vnetGetHostFeatures, vnetGetHostMinimalFeatures, vnetSetHostFeatures,
     
    517527    pState->uISR           = 0;
    518528
    519     for (unsigned i = 0; i < g_VPCIDevices[pState->enmDevType].nQueues; i++)
     529    for (unsigned i = 0; i < pState->nQueues; i++)
    520530        vqueueReset(&pState->Queues[i]);
    521531}
     
    727737
    728738        case VPCI_QUEUE_SEL:
    729 #ifdef IN_RING3
    730739            Assert(cb == 2);
    731740            u32 &= 0xFFFF;
    732             if (u32 < g_VPCIDevices[pState->enmDevType].nQueues)
     741            if (u32 < pState->nQueues)
    733742                pState->uQueueSelector = u32;
    734743            else
    735744                Log3(("%s virtioIOPortOut: Invalid queue selector %08x\n", szInst, u32));
    736 #else
    737             rc = VINF_IOM_HC_IOPORT_WRITE;
    738 #endif
    739745            break;
    740746
     
    743749            Assert(cb == 2);
    744750            u32 &= 0xFFFF;
    745             if (u32 < g_VPCIDevices[pState->enmDevType].nQueues)
     751            if (u32 < pState->nQueues)
    746752                if (pState->Queues[u32].VRing.addrDescriptors)
    747753                    pState->Queues[u32].pfnCallback(pState, &pState->Queues[u32]);
     
    962968          pState->uISR));
    963969
    964     for (unsigned i = 0; i < g_VPCIDevices[pState->enmDevType].nQueues; i++)
     970    for (unsigned i = 0; i < pState->nQueues; i++)
    965971        Log2((" %s queue:\n"
    966972              "  VRing.uSize           = %u\n"
     
    10071013
    10081014    /* Save queue states */
    1009     for (unsigned i = 0; i < g_VPCIDevices[pState->enmDevType].nQueues; i++)
     1015    rc = SSMR3PutU32(pSSM, pState->nQueues);
     1016    AssertRCReturn(rc, rc);
     1017    for (unsigned i = 0; i < pState->nQueues; i++)
    10101018    {
    10111019        rc = SSMR3PutU16(pSSM, pState->Queues[i].VRing.uSize);
     
    10481056
    10491057        /* Restore queues */
    1050         for (unsigned i = 0; i < g_VPCIDevices[pState->enmDevType].nQueues; i++)
     1058        if (uVersion > VIRTIO_SAVEDSTATE_VERSION_3_1_BETA1)
     1059        {
     1060            rc = SSMR3GetU32(pSSM, &pState->nQueues);
     1061            AssertRCReturn(rc, rc);
     1062        }
     1063        else
     1064            pState->nQueues = g_VPCIDevices[pState->enmDevType].nQueues;
     1065        for (unsigned i = 0; i < pState->nQueues; i++)
    10511066        {
    10521067            rc = SSMR3GetU16(pSSM, &pState->Queues[i].VRing.uSize);
     
    11361151    pState->pLedsConnector = (PPDMILEDCONNECTORS)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS);
    11371152
     1153    pState->nQueues = g_VPCIDevices[pState->enmDevType].nQueues;
     1154
    11381155#if defined(VBOX_WITH_STATISTICS)
    11391156    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatIOReadGC,           STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling IO reads in GC",           "/Devices/VNet%d/IO/ReadGC", iInstance);
     
    11941211    PVQUEUE pQueue = NULL;
    11951212    /* Find an empty queue slot */
    1196     for (unsigned i = 0; i < g_VPCIDevices[pState->enmDevType].nQueues; i++)
     1213    for (unsigned i = 0; i < pState->nQueues; i++)
    11971214    {
    11981215        if (pState->Queues[i].VRing.uSize == 0)
     
    12281245//- TODO: Move to VirtioNet.h -------------------------------------------------
    12291246
     1247#define VNET_TX_DELAY           150   /* 150 microseconds */
    12301248#define VNET_MAX_FRAME_SIZE     65536  // TODO: Is it the right limit?
    1231 #define VNET_SAVEDSTATE_VERSION 1
    12321249
    12331250/* Virtio net features */
     
    12901307    /**< Link Up(/Restore) Timer. */
    12911308    PTMTIMERR3              pLinkUpTimer;
     1309#ifdef VNET_TX_DELAY
     1310    /**< Transmit Delay Timer - R3. */
     1311    PTMTIMERR3              pTxTimerR3;
     1312    /**< Transmit Delay Timer - R0. */
     1313    PTMTIMERR0              pTxTimerR0;
     1314    /**< Transmit Delay Timer - GC. */
     1315    PTMTIMERRC              pTxTimerRC;
     1316#if HC_ARCH_BITS == 64
     1317    uint32_t    padding2;
     1318#endif
     1319
     1320#endif /* VNET_TX_DELAY */
    12921321
    12931322    /** PCI config area holding MAC address as well as TBD. */
     
    17751804}
    17761805
    1777 static DECLCALLBACK(void) vnetQueueTransmit(void *pvState, PVQUEUE pQueue)
    1778 {
    1779     VNETSTATE *pState = (VNETSTATE*)pvState;
     1806static DECLCALLBACK(void) vnetTransmitPendingPackets(PVNETSTATE pState, PVQUEUE pQueue)
     1807{
    17801808    if ((pState->VPCI.uStatus & VPCI_STATUS_DRV_OK) == 0)
    17811809    {
     
    18241852}
    18251853
     1854#ifdef VNET_TX_DELAY
     1855static DECLCALLBACK(void) vnetQueueTransmit(void *pvState, PVQUEUE pQueue)
     1856{
     1857    VNETSTATE *pState = (VNETSTATE*)pvState;
     1858
     1859    if (TMTimerIsActive(pState->CTX_SUFF(pTxTimer)))
     1860    {
     1861        int rc = TMTimerStop(pState->CTX_SUFF(pTxTimer));
     1862        vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, true);
     1863        Log3(("%s vnetQueueTransmit: Got kicked with notification disabled, "
     1864              "re-enable notification and flush TX queue\n", INSTANCE(pState)));
     1865        vnetTransmitPendingPackets(pState, pQueue);
     1866    }
     1867    else
     1868    {
     1869        TMTimerSetMicro(pState->CTX_SUFF(pTxTimer), VNET_TX_DELAY);
     1870        vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, false);
     1871    }
     1872}
     1873
     1874/**
     1875 * Transmit Delay Timer handler.
     1876 *
     1877 * @remarks We only get here when the timer expires.
     1878 *
     1879 * @param   pDevIns     Pointer to device instance structure.
     1880 * @param   pTimer      Pointer to the timer.
     1881 * @param   pvUser      NULL.
     1882 * @thread  EMT
     1883 */
     1884static DECLCALLBACK(void) vnetTxTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     1885{
     1886    VNETSTATE *pState = (VNETSTATE*)pvUser;
     1887
     1888    vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, true);
     1889    Log3(("%s vnetTxTimer: Expired, %d packets pending\n", INSTANCE(pState),
     1890          vringReadAvailIndex(&pState->VPCI, &pState->pTxQueue->VRing) - pState->pTxQueue->uNextAvailIndex));
     1891    vnetTransmitPendingPackets(pState, pState->pTxQueue);
     1892}
     1893
     1894#else /* !VNET_TX_DELAY */
     1895static DECLCALLBACK(void) vnetQueueTransmit(void *pvState, PVQUEUE pQueue)
     1896{
     1897    VNETSTATE *pState = (VNETSTATE*)pvState;
     1898
     1899    vnetTransmitPendingPackets(pState, pQueue);
     1900}
     1901#endif /* !VNET_TX_DELAY */
     1902
    18261903static DECLCALLBACK(void) vnetQueueControl(void *pvState, PVQUEUE pQueue)
    18271904{
     
    19692046        rc = SSMR3GetMem( pSSM, pState->config.mac.au8, sizeof(pState->config.mac));
    19702047        AssertRCReturn(rc, rc);
    1971         /* Indicate link down to the guest OS that all network connections have
    1972            been lost, unless we've been teleported here. */
    1973         if (!PDMDevHlpVMTeleportedAndNotFullyResumedYet(pDevIns))
    1974             vnetTempLinkDown(pState);
    19752048    }
    19762049
    19772050    return rc;
     2051}
     2052
     2053/**
     2054 * Link status adjustments after loading.
     2055 *
     2056 * @returns VBox status code.
     2057 * @param   pDevIns     The device instance.
     2058 * @param   pSSM        The handle to the saved state.
     2059 */
     2060static DECLCALLBACK(int) vnetLoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     2061{
     2062    VNETSTATE *pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
     2063
     2064    /*
     2065     * Indicate link down to the guest OS that all network connections have
     2066     * been lost, unless we've been teleported here.
     2067     */
     2068    if (!PDMDevHlpVMTeleportedAndNotFullyResumedYet(pDevIns))
     2069        vnetTempLinkDown(pState);
     2070
     2071    return VINF_SUCCESS;
    19782072}
    19792073
     
    20462140
    20472141    /* Register save/restore state handlers. */
    2048     rc = PDMDevHlpSSMRegisterEx(pDevIns, VNET_SAVEDSTATE_VERSION, sizeof(VNETSTATE), NULL,
     2142    rc = PDMDevHlpSSMRegisterEx(pDevIns, VIRTIO_SAVEDSTATE_VERSION, sizeof(VNETSTATE), NULL,
    20492143                                NULL,         vnetLiveExec, NULL,
    20502144                                vnetSavePrep, vnetSaveExec, NULL,
    2051                                 vnetLoadPrep, vnetLoadExec, NULL);
     2145                                vnetLoadPrep, vnetLoadExec, vnetLoadDone);
    20522146    if (RT_FAILURE(rc))
    20532147        return rc;
     
    20672161    if (RT_FAILURE(rc))
    20682162        return rc;
     2163
     2164#ifdef VNET_TX_DELAY
     2165    /* Create Transmit Delay Timer */
     2166    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetTxTimer, pState,
     2167                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
     2168                                "VirtioNet TX Delay Timer", &pState->pTxTimerR3);
     2169    if (RT_FAILURE(rc))
     2170        return rc;
     2171    pState->pTxTimerR0 = TMTimerR0Ptr(pState->pTxTimerR3);
     2172    pState->pTxTimerRC = TMTimerRCPtr(pState->pTxTimerR3);
     2173#endif /* VNET_TX_DELAY */
    20692174
    20702175    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->VPCI.IBase, &pState->pDrvBase, "Network Port");
     
    21612266    vpciRelocate(pDevIns, offDelta);
    21622267    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
     2268#ifdef VNET_TX_DELAY
     2269    pState->pTxTimerRC    = TMTimerRCPtr(pState->pTxTimerR3);
     2270#endif /* VNET_TX_DELAY */
    21632271    // TBD
    21642272}
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