Changeset 25830 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Jan 14, 2010 3:06:13 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet.cpp
r25728 r25830 140 140 /**< Transmit Delay Timer - GC. */ 141 141 PTMTIMERRC pTxTimerRC; 142 142 143 #if HC_ARCH_BITS == 64 143 144 uint32_t padding2; 144 145 #endif 145 146 147 uint32_t u32i; 148 uint32_t u32AvgDiff; 149 uint32_t u32MinDiff; 150 uint32_t u32MaxDiff; 151 uint64_t u64NanoTS; 152 146 153 #endif /* VNET_TX_DELAY */ 154 /** Indicates transmission in progress -- only one thread is allowed. */ 155 uint32_t uIsTransmitting; 147 156 148 157 /** PCI config area holding MAC address as well as TBD. */ … … 170 179 uint8_t aVlanFilter[VNET_MAX_VID / sizeof(uint8_t)]; 171 180 172 #if HC_ARCH_BITS == 64181 #if HC_ARCH_BITS != 64 173 182 uint32_t padding3; 174 183 #endif … … 266 275 // PDMCritSectLeave(&pState->csRx); 267 276 } 277 278 /** 279 * Dump a packet to debug log. 280 * 281 * @param pState The device state structure. 282 * @param cpPacket The packet. 283 * @param cb The size of the packet. 284 * @param cszText A string denoting direction of packet transfer. 285 */ 286 DECLINLINE(void) vnetPacketDump(PVNETSTATE pState, const uint8_t *cpPacket, size_t cb, const char *cszText) 287 { 288 #ifdef DEBUG 289 Log(("%s %s packet #%d (%d bytes):\n", 290 INSTANCE(pState), cszText, ++pState->u32PktNo, cb)); 291 //Log3(("%.*Rhxd\n", cb, cpPacket)); 292 #endif 293 } 294 268 295 269 296 … … 354 381 memset(pState->aMacFilter, 0, VNET_MAC_FILTER_LEN * sizeof(RTMAC)); 355 382 memset(pState->aVlanFilter, 0, sizeof(pState->aVlanFilter)); 383 pState->uIsTransmitting = 0; 356 384 } 357 385 … … 650 678 hdr.u8GSOType = VNETHDR_GSO_NONE; 651 679 680 vnetPacketDump(pState, (const uint8_t*)pvBuf, cb, "<-- Incoming"); 681 652 682 unsigned int uOffset = 0; 653 683 for (unsigned int nElem = 0; uOffset < cb; nElem++) … … 812 842 static DECLCALLBACK(void) vnetTransmitPendingPackets(PVNETSTATE pState, PVQUEUE pQueue) 813 843 { 844 /* 845 * Only one thread is allowed to transmit at a time, others should skip 846 * transmission as the packets will be picked up by the transmitting 847 * thread. 848 */ 849 if (!ASMAtomicCmpXchgU32(&pState->uIsTransmitting, 1, 0)) 850 return; 851 814 852 if ((pState->VPCI.uStatus & VPCI_STATUS_DRV_OK) == 0) 815 853 { … … 818 856 return; 819 857 } 858 859 Log3(("%s vnetTransmitPendingPackets: About to trasmit %d pending packets\n", INSTANCE(pState), 860 vringReadAvailIndex(&pState->VPCI, &pState->pTxQueue->VRing) - pState->pTxQueue->uNextAvailIndex)); 820 861 821 862 vpciSetWriteLed(&pState->VPCI, true); … … 849 890 if (pState->pDrv) 850 891 { 892 vnetPacketDump(pState, pState->pTxBuf, uOffset, "--> Outgoing"); 893 851 894 STAM_PROFILE_START(&pState->StatTransmitSend, a); 852 895 int rc = pState->pDrv->pfnSend(pState->pDrv, pState->pTxBuf, uOffset); … … 860 903 } 861 904 vpciSetWriteLed(&pState->VPCI, false); 905 906 ASMAtomicWriteU32(&pState->uIsTransmitting, 0); 862 907 } 863 908 … … 873 918 "re-enable notification and flush TX queue\n", INSTANCE(pState))); 874 919 vnetTransmitPendingPackets(pState, pQueue); 875 vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, true); 920 if (RT_FAILURE(vnetCsEnter(pState, VERR_SEM_BUSY))) 921 LogRel(("vnetQueueTransmit: Failed to enter critical section!/n")); 922 else 923 { 924 vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, true); 925 vnetCsLeave(pState); 926 } 876 927 } 877 928 else 878 929 { 879 vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, false); 880 TMTimerSetMicro(pState->CTX_SUFF(pTxTimer), VNET_TX_DELAY); 930 if (RT_FAILURE(vnetCsEnter(pState, VERR_SEM_BUSY))) 931 LogRel(("vnetQueueTransmit: Failed to enter critical section!/n")); 932 else 933 { 934 vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, false); 935 TMTimerSetMicro(pState->CTX_SUFF(pTxTimer), VNET_TX_DELAY); 936 pState->u64NanoTS = RTTimeNanoTS(); 937 vnetCsLeave(pState); 938 } 881 939 } 882 940 } … … 896 954 VNETSTATE *pState = (VNETSTATE*)pvUser; 897 955 898 int rc = vnetCsEnter(pState, VERR_SEM_BUSY); 899 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 956 uint32_t u32MicroDiff = (uint32_t)((RTTimeNanoTS() - pState->u64NanoTS)/1000); 957 if (u32MicroDiff < pState->u32MinDiff) 958 pState->u32MinDiff = u32MicroDiff; 959 if (u32MicroDiff > pState->u32MaxDiff) 960 pState->u32MaxDiff = u32MicroDiff; 961 pState->u32AvgDiff = (pState->u32AvgDiff * pState->u32i + u32MicroDiff) / (pState->u32i + 1); 962 pState->u32i++; 963 Log3(("vnetTxTimer: Expired, diff %9d usec, avg %9d usec, min %9d usec, max %9d usec\n", 964 u32MicroDiff, pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff)); 965 966 // Log3(("%s vnetTxTimer: Expired\n", INSTANCE(pState))); 967 vnetTransmitPendingPackets(pState, pState->pTxQueue); 968 if (RT_FAILURE(vnetCsEnter(pState, VERR_SEM_BUSY))) 969 { 970 LogRel(("vnetTxTimer: Failed to enter critical section!/n")); 900 971 return; 972 } 901 973 vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, true); 902 Log3(("%s vnetTxTimer: Expired, %d packets pending\n", INSTANCE(pState),903 vringReadAvailIndex(&pState->VPCI, &pState->pTxQueue->VRing) - pState->pTxQueue->uNextAvailIndex));904 vnetTransmitPendingPackets(pState, pState->pTxQueue);905 974 vnetCsLeave(pState); 906 975 } … … 1486 1555 pState->pTxTimerR0 = TMTimerR0Ptr(pState->pTxTimerR3); 1487 1556 pState->pTxTimerRC = TMTimerRCPtr(pState->pTxTimerR3); 1557 1558 pState->u32i = pState->u32AvgDiff = pState->u32MaxDiff = 0; 1559 pState->u32MinDiff = ~0; 1488 1560 #endif /* VNET_TX_DELAY */ 1489 1561 … … 1544 1616 VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*); 1545 1617 1618 LogRel(("TxTimer stats (avg/min/max): %7d usec %7d usec %7d usec\n", 1619 pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff)); 1546 1620 Log(("%s Destroying instance\n", INSTANCE(pState))); 1547 1621 if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
Note:
See TracChangeset
for help on using the changeset viewer.