- Timestamp:
- Aug 23, 2012 8:57:53 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevE1000.cpp
r41808 r42932 51 51 * Ethernet Controllers Software Developer’s Manual"). 52 52 */ 53 #define E1K_ITR_ENABLED 53 //#define E1K_ITR_ENABLED 54 /* 55 * E1K_TX_DELAY aims to improve guest-host transfer rate for TCP streams by 56 * preventing packets to be sent immediately. It allows to send several 57 * packets in a batch reducing the number of acknowledgments. Note that it 58 * effectively disables R0 TX path, forcing sending in R3. 59 */ 60 #define E1K_TX_DELAY 150 54 61 /* 55 62 * E1K_USE_TX_TIMERS aims to reduce the number of generated TX interrupts if a … … 126 133 #include <iprt/semaphore.h> 127 134 #include <iprt/string.h> 135 #include <iprt/time.h> 128 136 #include <iprt/uuid.h> 129 137 #include <VBox/vmm/pdmdev.h> … … 1000 1008 PTMTIMERR3 pTIDTimerR3; /**< Transmit Interrupt Delay Timer - R3. */ 1001 1009 PTMTIMERR3 pTADTimerR3; /**< Transmit Absolute Delay Timer - R3. */ 1010 PTMTIMERR3 pTXDTimerR3; /**< Transmit Delay Timer - R3. */ 1002 1011 PTMTIMERR3 pIntTimerR3; /**< Late Interrupt Timer - R3. */ 1003 1012 PTMTIMERR3 pLUTimerR3; /**< Link Up(/Restore) Timer. */ … … 1013 1022 PTMTIMERR0 pTIDTimerR0; /**< Transmit Interrupt Delay Timer - R0. */ 1014 1023 PTMTIMERR0 pTADTimerR0; /**< Transmit Absolute Delay Timer - R0. */ 1024 PTMTIMERR0 pTXDTimerR0; /**< Transmit Delay Timer - R0. */ 1015 1025 PTMTIMERR0 pIntTimerR0; /**< Late Interrupt Timer - R0. */ 1016 1026 PTMTIMERR0 pLUTimerR0; /**< Link Up(/Restore) Timer - R0. */ … … 1026 1036 PTMTIMERRC pTIDTimerRC; /**< Transmit Interrupt Delay Timer - RC. */ 1027 1037 PTMTIMERRC pTADTimerRC; /**< Transmit Absolute Delay Timer - RC. */ 1038 PTMTIMERRC pTXDTimerRC; /**< Transmit Delay Timer - RC. */ 1028 1039 PTMTIMERRC pIntTimerRC; /**< Late Interrupt Timer - RC. */ 1029 1040 PTMTIMERRC pLUTimerRC; /**< Link Up(/Restore) Timer - RC. */ … … 1032 1043 RTRCPTR RCPtrAlignment; 1033 1044 1034 #if HC_ARCH_BITS == 321045 //#if HC_ARCH_BITS == 32 1035 1046 uint32_t Alignment1; 1036 #endif1047 //#endif 1037 1048 PDMCRITSECT cs; /**< Critical section - what is it protecting? */ 1038 1049 PDMCRITSECT csRx; /**< RX Critical section. */ … … 1203 1214 #ifdef E1K_INT_STATS 1204 1215 /* Internal stats */ 1216 uint64_t u64ArmedAt; 1217 uint64_t uStatMaxTxDelay; 1205 1218 uint32_t uStatInt; 1206 1219 uint32_t uStatIntTry; … … 1222 1235 uint32_t uStatTxNoRS; 1223 1236 uint32_t uStatTxIDE; 1237 uint32_t uStatTxDelayed; 1238 uint32_t uStatTxDelayExp; 1224 1239 uint32_t uStatTAD; 1225 1240 uint32_t uStatTID; … … 1231 1246 uint32_t uStatDescDat; 1232 1247 uint32_t uStatDescLeg; 1248 uint32_t uStatTx1514; 1249 uint32_t uStatTx2962; 1250 uint32_t uStatTx4410; 1251 uint32_t uStatTx5858; 1252 uint32_t uStatTx7306; 1253 uint32_t uStatTx8754; 1254 uint32_t uStatTx16384; 1255 uint32_t uStatTx32768; 1256 uint32_t uStatTxLarge; 1257 uint32_t uStatAlign; 1233 1258 #endif /* E1K_INT_STATS */ 1234 1259 }; … … 1479 1504 if (pTimer == pState->CTX_SUFF(pIntTimer)) 1480 1505 return "Int"; 1506 if (pTimer == pState->CTX_SUFF(pTXDTimer)) 1507 return "TXD"; 1481 1508 return "unknown"; 1482 1509 } … … 1498 1525 E1kLog2(("%s Arming %s timer to fire in %d usec...\n", 1499 1526 INSTANCE(pState), e1kGetTimerName(pState, pTimer), uExpireIn)); 1500 TMTimerSet(pTimer, TMTimerFromMicro(pTimer, uExpireIn) + 1501 TMTimerGet(pTimer)); 1527 TMTimerSetMicro(pTimer, uExpireIn); 1502 1528 } 1503 1529 … … 1527 1553 1528 1554 #ifndef E1K_WITH_TX_CS 1529 #define e1kCsTxEnter(ps, rc) VINF_SUCCESS 1530 #define e1kCsTxLeave(ps) do { } while (0) 1555 # define e1kCsTxEnter(ps, rc) VINF_SUCCESS 1556 # define e1kCsTxLeave(ps) do { } while (0) 1557 # define e1kCsIsOwner(cs) true 1531 1558 #else /* E1K_WITH_TX_CS */ 1532 1559 # define e1kCsTxEnter(ps, rc) PDMCritSectEnter(&ps->csTx, rc) 1533 1560 # define e1kCsTxLeave(ps) PDMCritSectLeave(&ps->csTx) 1561 # define e1kCsIsOwner(cs) PDMCritSectIsOwner(cs) 1534 1562 #endif /* E1K_WITH_TX_CS */ 1535 1563 … … 1833 1861 E1kLog2(("%s e1kRaiseInterrupt: tstamp - pState->u64AckedAt = %d, ITR * 256 = %d\n", 1834 1862 INSTANCE(pState), (uint32_t)(tstamp - pState->u64AckedAt), ITR * 256)); 1835 if (!!ITR && pState->fIntMaskUsed && tstamp - pState->u64AckedAt < ITR * 256) 1863 //if (!!ITR && pState->fIntMaskUsed && tstamp - pState->u64AckedAt < ITR * 256) 1864 if (!!ITR && tstamp - pState->u64AckedAt < ITR * 256 && !(ICR & ICR_RXT0)) 1836 1865 { 1837 1866 E1K_INC_ISTAT_CNT(pState->uStatIntEarly); … … 2991 3020 2992 3021 #ifdef IN_RING3 3022 #ifdef E1K_TX_DELAY 3023 3024 /** 3025 * Transmit Delay Timer handler. 3026 * 3027 * @remarks We only get here when the timer expires. 3028 * 3029 * @param pDevIns Pointer to device instance structure. 3030 * @param pTimer Pointer to the timer. 3031 * @param pvUser NULL. 3032 * @thread EMT 3033 */ 3034 static DECLCALLBACK(void) e1kTxDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 3035 { 3036 E1KSTATE *pState = (E1KSTATE *)pvUser; 3037 Assert(e1kCsIsOwner(&pState->csTx)); 3038 3039 E1K_INC_ISTAT_CNT(pState->uStatTxDelayExp); 3040 #ifdef E1K_INT_STATS 3041 uint64_t u64Elapsed = RTTimeNanoTS() - pState->u64ArmedAt; 3042 if (u64Elapsed > pState->uStatMaxTxDelay) 3043 pState->uStatMaxTxDelay = u64Elapsed; 3044 #endif /* E1K_INT_STATS */ 3045 int rc = e1kXmitPending(pState, false /*fOnWorkerThread*/); 3046 AssertMsg(RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN, ("%Rrc\n", rc)); 3047 } 3048 #endif /* E1K_TX_DELAY */ 3049 2993 3050 #ifdef E1K_USE_TX_TIMERS 2994 3051 … … 3579 3636 if (cbFrame > 70) /* unqualified guess */ 3580 3637 pState->led.Asserted.s.fWriting = pState->led.Actual.s.fWriting = 1; 3638 3639 #ifdef E1K_INT_STATS 3640 if (cbFrame <= 1514) 3641 E1K_INC_ISTAT_CNT(pState->uStatTx1514); 3642 else if (cbFrame <= 2962) 3643 E1K_INC_ISTAT_CNT(pState->uStatTx2962); 3644 else if (cbFrame <= 4410) 3645 E1K_INC_ISTAT_CNT(pState->uStatTx4410); 3646 else if (cbFrame <= 5858) 3647 E1K_INC_ISTAT_CNT(pState->uStatTx5858); 3648 else if (cbFrame <= 7306) 3649 E1K_INC_ISTAT_CNT(pState->uStatTx7306); 3650 else if (cbFrame <= 8754) 3651 E1K_INC_ISTAT_CNT(pState->uStatTx8754); 3652 else if (cbFrame <= 16384) 3653 E1K_INC_ISTAT_CNT(pState->uStatTx16384); 3654 else if (cbFrame <= 32768) 3655 E1K_INC_ISTAT_CNT(pState->uStatTx32768); 3656 else 3657 E1K_INC_ISTAT_CNT(pState->uStatTxLarge); 3658 #endif /* E1K_INT_STATS */ 3581 3659 3582 3660 /* Add VLAN tag */ … … 4807 4885 * Grab the xmit lock of the driver as well as the E1K device state. 4808 4886 */ 4809 PPDMINETWORKUP pDrv = pState->CTX_SUFF(pDrv);4810 if (pDrv)4811 {4812 rc = pDrv->pfnBeginXmit(pDrv, fOnWorkerThread);4813 if (RT_FAILURE(rc))4814 return rc;4815 }4816 4887 rc = e1kCsTxEnter(pState, VERR_SEM_BUSY); 4817 4888 if (RT_LIKELY(rc == VINF_SUCCESS)) 4818 4889 { 4890 PPDMINETWORKUP pDrv = pState->CTX_SUFF(pDrv); 4891 if (pDrv) 4892 { 4893 rc = pDrv->pfnBeginXmit(pDrv, fOnWorkerThread); 4894 if (RT_FAILURE(rc)) 4895 { 4896 e1kCsTxLeave(pState); 4897 return rc; 4898 } 4899 } 4819 4900 /* 4820 4901 * Process all pending descriptors. … … 4847 4928 /// @todo: uncomment: pState->uStatIntTXQE++; 4848 4929 /// @todo: uncomment: e1kRaiseInterrupt(pState, ICR_TXQE); 4930 /* 4931 * Release the lock. 4932 */ 4933 if (pDrv) 4934 pDrv->pfnEndXmit(pDrv); 4849 4935 e1kCsTxLeave(pState); 4850 4936 } 4851 4937 4852 /*4853 * Release the lock.4854 */4855 if (pDrv)4856 pDrv->pfnEndXmit(pDrv);4857 4938 return rc; 4858 4939 } … … 5067 5148 /* Transmit pending packets if possible, defer it if we cannot do it 5068 5149 in the current context. */ 5150 #ifdef E1K_TX_DELAY 5151 rc = e1kCsTxEnter(pState, VERR_SEM_BUSY); 5152 if (RT_LIKELY(rc == VINF_SUCCESS)) 5153 { 5154 if (!TMTimerIsActive(pState->CTX_SUFF(pTXDTimer))) 5155 { 5156 #ifdef E1K_INT_STATS 5157 pState->u64ArmedAt = RTTimeNanoTS(); 5158 #endif /* E1K_INT_STATS */ 5159 e1kArmTimer(pState, pState->CTX_SUFF(pTXDTimer), E1K_TX_DELAY); 5160 } 5161 E1K_INC_ISTAT_CNT(pState->uStatTxDelayed); 5162 e1kCsTxLeave(pState); 5163 return rc; 5164 } 5165 /* We failed to enter the TX critical section -- transmit as usual. */ 5166 #endif /* E1K_TX_DELAY */ 5069 5167 # ifndef IN_RING3 5070 5168 if (!pState->CTX_SUFF(pDrv)) … … 5697 5795 LogRel(("%s Interrupts by TXQE: %d\n", INSTANCE(pState), pState->uStatIntTXQE)); 5698 5796 LogRel(("%s TX int delay asked: %d\n", INSTANCE(pState), pState->uStatTxIDE)); 5797 LogRel(("%s TX delayed: %d\n", INSTANCE(pState), pState->uStatTxDelayed)); 5798 LogRel(("%s TX delay expired: %d\n", INSTANCE(pState), pState->uStatTxDelayExp)); 5699 5799 LogRel(("%s TX no report asked: %d\n", INSTANCE(pState), pState->uStatTxNoRS)); 5700 5800 LogRel(("%s TX abs timer expd : %d\n", INSTANCE(pState), pState->uStatTAD)); … … 5707 5807 LogRel(("%s Received frames : %d\n", INSTANCE(pState), pState->uStatRxFrm)); 5708 5808 LogRel(("%s Transmitted frames: %d\n", INSTANCE(pState), pState->uStatTxFrm)); 5809 LogRel(("%s TX frames up to 1514: %d\n", INSTANCE(pState), pState->uStatTx1514)); 5810 LogRel(("%s TX frames up to 2962: %d\n", INSTANCE(pState), pState->uStatTx2962)); 5811 LogRel(("%s TX frames up to 4410: %d\n", INSTANCE(pState), pState->uStatTx4410)); 5812 LogRel(("%s TX frames up to 5858: %d\n", INSTANCE(pState), pState->uStatTx5858)); 5813 LogRel(("%s TX frames up to 7306: %d\n", INSTANCE(pState), pState->uStatTx7306)); 5814 LogRel(("%s TX frames up to 8754: %d\n", INSTANCE(pState), pState->uStatTx8754)); 5815 LogRel(("%s TX frames up to 16384: %d\n", INSTANCE(pState), pState->uStatTx16384)); 5816 LogRel(("%s TX frames up to 32768: %d\n", INSTANCE(pState), pState->uStatTx32768)); 5817 LogRel(("%s Larger TX frames : %d\n", INSTANCE(pState), pState->uStatTxLarge)); 5818 LogRel(("%s Max TX Delay : %lld\n", INSTANCE(pState), pState->uStatMaxTxDelay)); 5709 5819 #endif /* E1K_INT_STATS */ 5710 5820 } … … 6278 6388 //pState->fLocked = true; 6279 6389 /* 2) Cancel all timers */ 6390 #ifdef E1K_TX_DELAY 6391 e1kCancelTimer(pState, pState->CTX_SUFF(pTXDTimer)); 6392 #endif /* E1K_TX_DELAY */ 6280 6393 #ifdef E1K_USE_TX_TIMERS 6281 6394 e1kCancelTimer(pState, pState->CTX_SUFF(pTIDTimer)); … … 6652 6765 { 6653 6766 E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*); 6767 e1kCancelTimer(pState, pState->CTX_SUFF(pTXDTimer)); 6654 6768 e1kCancelTimer(pState, pState->CTX_SUFF(pIntTimer)); 6655 6769 e1kCancelTimer(pState, pState->CTX_SUFF(pLUTimer)); … … 6706 6820 # endif /* E1K_NO_TAD */ 6707 6821 #endif /* E1K_USE_TX_TIMERS */ 6822 #ifdef E1K_TX_DELAY 6823 pState->pTXDTimerRC = TMTimerRCPtr(pState->pTXDTimerR3); 6824 #endif /* E1K_TX_DELAY */ 6708 6825 pState->pIntTimerRC = TMTimerRCPtr(pState->pIntTimerR3); 6709 6826 pState->pLUTimerRC = TMTimerRCPtr(pState->pLUTimerR3); … … 6939 7056 pHlp->pfnPrintf(pHlp, "Interrupts by TXQE: %d\n", pState->uStatIntTXQE); 6940 7057 pHlp->pfnPrintf(pHlp, "TX int delay asked: %d\n", pState->uStatTxIDE); 7058 pHlp->pfnPrintf(pHlp, "TX delayed: %d\n", pState->uStatTxDelayed); 7059 pHlp->pfnPrintf(pHlp, "TX delayed expired: %d\n", pState->uStatTxDelayExp); 6941 7060 pHlp->pfnPrintf(pHlp, "TX no report asked: %d\n", pState->uStatTxNoRS); 6942 7061 pHlp->pfnPrintf(pHlp, "TX abs timer expd : %d\n", pState->uStatTAD); … … 6949 7068 pHlp->pfnPrintf(pHlp, "Received frames : %d\n", pState->uStatRxFrm); 6950 7069 pHlp->pfnPrintf(pHlp, "Transmitted frames: %d\n", pState->uStatTxFrm); 7070 pHlp->pfnPrintf(pHlp, "TX frames up to 1514: %d\n", pState->uStatTx1514); 7071 pHlp->pfnPrintf(pHlp, "TX frames up to 2962: %d\n", pState->uStatTx2962); 7072 pHlp->pfnPrintf(pHlp, "TX frames up to 4410: %d\n", pState->uStatTx4410); 7073 pHlp->pfnPrintf(pHlp, "TX frames up to 5858: %d\n", pState->uStatTx5858); 7074 pHlp->pfnPrintf(pHlp, "TX frames up to 7306: %d\n", pState->uStatTx7306); 7075 pHlp->pfnPrintf(pHlp, "TX frames up to 8754: %d\n", pState->uStatTx8754); 7076 pHlp->pfnPrintf(pHlp, "TX frames up to 16384: %d\n", pState->uStatTx16384); 7077 pHlp->pfnPrintf(pHlp, "TX frames up to 32768: %d\n", pState->uStatTx32768); 7078 pHlp->pfnPrintf(pHlp, "Larger TX frames : %d\n", pState->uStatTxLarge); 6951 7079 #endif /* E1K_INT_STATS */ 6952 7080 … … 7139 7267 } 7140 7268 7141 E1kLog(("%s Chip=%s LinkUpDelay=%ums\n", INSTANCE(pState), 7142 g_Chips[pState->eChip].pcszName, pState->cMsLinkUpDelay)); 7269 E1kLog(("%s Chip=%s LinkUpDelay=%ums EthernetCRC=%s\n", INSTANCE(pState), 7270 g_Chips[pState->eChip].pcszName, pState->cMsLinkUpDelay, 7271 pState->fEthernetCRC ? "on" : "off")); 7143 7272 7144 7273 /* Initialize state structure */ … … 7175 7304 pState->uStatTxNoRS = 0; 7176 7305 pState->uStatTxIDE = 0; 7306 pState->uStatTxDelayed = 0; 7307 pState->uStatTxDelayExp = 0; 7177 7308 pState->uStatTAD = 0; 7178 7309 pState->uStatTID = 0; … … 7184 7315 pState->uStatDescDat = 0; 7185 7316 pState->uStatDescLeg = 0; 7317 pState->uStatTx1514 = 0; 7318 pState->uStatTx2962 = 0; 7319 pState->uStatTx4410 = 0; 7320 pState->uStatTx5858 = 0; 7321 pState->uStatTx7306 = 0; 7322 pState->uStatTx8754 = 0; 7323 pState->uStatTx16384 = 0; 7324 pState->uStatTx32768 = 0; 7325 pState->uStatTxLarge = 0; 7326 pState->uStatMaxTxDelay = 0; 7186 7327 #endif /* E1K_INT_STATS */ 7187 7328 … … 7274 7415 pState->pCanRxQueueR0 = PDMQueueR0Ptr(pState->pCanRxQueueR3); 7275 7416 pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3); 7417 7418 #ifdef E1K_TX_DELAY 7419 /* Create Transmit Delay Timer */ 7420 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kTxDelayTimer, pState, 7421 TMTIMER_FLAGS_NO_CRIT_SECT, 7422 "E1000 Transmit Delay Timer", &pState->pTXDTimerR3); 7423 if (RT_FAILURE(rc)) 7424 return rc; 7425 pState->pTXDTimerR0 = TMTimerR0Ptr(pState->pTXDTimerR3); 7426 pState->pTXDTimerRC = TMTimerRCPtr(pState->pTXDTimerR3); 7427 TMR3TimerSetCritSect(pState->pTXDTimerR3, &pState->csTx); 7428 #endif /* E1K_TX_DELAY */ 7276 7429 7277 7430 #ifdef E1K_USE_TX_TIMERS
Note:
See TracChangeset
for help on using the changeset viewer.