Changeset 72459 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Jun 6, 2018 8:17:43 AM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 122941
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet.cpp
r71944 r72459 64 64 #endif /* VBOX_DEVICE_STRUCT_TESTCASE */ 65 65 66 67 #define VNET_TX_DELAY 150 /**< 150 microseconds */ 66 /* 67 * Commenting out VNET_TX_DELAY enables async transmission in a dedicated thread. 68 * When VNET_TX_DELAY is defined, a timer handler does the job. 69 */ 70 //#define VNET_TX_DELAY 150 /**< 150 microseconds */ 68 71 #define VNET_MAX_FRAME_SIZE 65535 + 18 /**< Max IP packet size + Ethernet header with VLAN tag */ 69 72 #define VNET_MAC_FILTER_LEN 32 … … 154 157 uint32_t u32MaxDiff; 155 158 uint64_t u64NanoTS; 156 #endif /* VNET_TX_DELAY */ 159 #else /* !VNET_TX_DELAY */ 160 /** The support driver session handle. */ 161 R3R0PTRTYPE(PSUPDRVSESSION) pSupDrvSession; 162 /** The event semaphore TX thread waits on. */ 163 SUPSEMEVENT hTxEvent; 164 R3PTRTYPE(PPDMTHREAD) pTxThread; 165 #endif /* !VNET_TX_DELAY */ 157 166 158 167 /** Indicates transmission in progress -- only one thread is allowed. */ … … 1476 1485 } 1477 1486 1487 inline int vnetCreateTxThreadAndEvent(PPDMDEVINS pDevIns, PVNETSTATE pThis) 1488 { 1489 RT_NOREF(pDevIns, pThis); 1490 return VINF_SUCCESS; 1491 } 1492 1493 inline void vnetDestroyTxThreadAndEvent(PVNETSTATE pThis) 1494 { 1495 RT_NOREF(pThis); 1496 } 1478 1497 #else /* !VNET_TX_DELAY */ 1479 1498 1499 static DECLCALLBACK(int) vnetTxThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 1500 { 1501 RT_NOREF(pDevIns); 1502 PVNETSTATE pThis = (PVNETSTATE)pThread->pvUser; 1503 int rc = VINF_SUCCESS; 1504 1505 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 1506 return VINF_SUCCESS; 1507 1508 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 1509 { 1510 rc = SUPSemEventWaitNoResume(pThis->pSupDrvSession, pThis->hTxEvent, RT_INDEFINITE_WAIT); 1511 if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING)) 1512 break; 1513 vnetTransmitPendingPackets(pThis, pThis->pTxQueue, false /*fOnWorkerThread*/); // @todo: shouldn't it be true instead? 1514 Log(("vnetTxThread: enable kicking and get to sleep\n")); 1515 vringSetNotification(&pThis->VPCI, &pThis->pTxQueue->VRing, true); 1516 } 1517 1518 return rc; 1519 } 1520 1521 /** 1522 * Unblock TX thread so it can respond to a state change. 1523 * 1524 * @returns VBox status code. 1525 * @param pDevIns The device instance. 1526 * @param pThread The send thread. 1527 */ 1528 static DECLCALLBACK(int) vnetTxThreadWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 1529 { 1530 RT_NOREF(pDevIns); 1531 PVNETSTATE pThis = (PVNETSTATE)pThread->pvUser; 1532 return SUPSemEventSignal(pThis->pSupDrvSession, pThis->hTxEvent); 1533 } 1534 1535 static int vnetCreateTxThreadAndEvent(PPDMDEVINS pDevIns, PVNETSTATE pThis) 1536 { 1537 int rc = SUPSemEventCreate(pThis->pSupDrvSession, &pThis->hTxEvent); 1538 if (RT_FAILURE(rc)) 1539 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 1540 N_("VNET: Failed to create SUP event semaphore")); 1541 rc = PDMDevHlpThreadCreate(pDevIns, &pThis->pTxThread, pThis, vnetTxThread, 1542 vnetTxThreadWakeUp, 0, RTTHREADTYPE_IO, INSTANCE(pThis)); 1543 if (RT_FAILURE(rc)) 1544 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 1545 N_("VNET: Failed to create worker thread %s"), INSTANCE(pThis)); 1546 return VINF_SUCCESS; 1547 } 1548 1549 static void vnetDestroyTxThreadAndEvent(PVNETSTATE pThis) 1550 { 1551 if (pThis->pTxThread) 1552 { 1553 int rcThread; 1554 /* Destroy the thread. */ 1555 int rc = PDMR3ThreadDestroy(pThis->pTxThread, &rcThread); 1556 if (RT_FAILURE(rc) || RT_FAILURE(rcThread)) 1557 AssertMsgFailed(("%s Failed to destroy async IO thread rc=%Rrc rcThread=%Rrc\n", __FUNCTION__, rc, rcThread)); 1558 pThis->pTxThread = NULL; 1559 } 1560 if (pThis->hTxEvent != NIL_SUPSEMEVENT) 1561 { 1562 SUPSemEventClose(pThis->pSupDrvSession, pThis->hTxEvent); 1563 pThis->hTxEvent = NIL_SUPSEMEVENT; 1564 } 1565 } 1566 1480 1567 static DECLCALLBACK(void) vnetQueueTransmit(void *pvState, PVQUEUE pQueue) 1481 1568 { 1482 1569 PVNETSTATE pThis = (PVNETSTATE)pvState; 1483 1570 1484 vnetTransmitPendingPackets(pThis, pQueue, false /*fOnWorkerThread*/); 1571 Log(("vnetQueueTransmit: disable kicking and wake up TX thread\n")); 1572 vringSetNotification(&pThis->VPCI, &pQueue->VRing, false); 1573 SUPSemEventSignal(pThis->pSupDrvSession, pThis->hTxEvent); 1485 1574 } 1486 1575 … … 1919 2008 } 1920 2009 2010 vnetDestroyTxThreadAndEvent(pThis); 1921 2011 /* 1922 2012 * Zero some important members. … … 1966 2056 AssertMsgStmt(pThis->pDrv, ("Failed to obtain the PDMINETWORKUP interface!\n"), 1967 2057 rc = VERR_PDM_MISSING_INTERFACE_BELOW); 2058 2059 vnetCreateTxThreadAndEvent(pDevIns, pThis); 1968 2060 } 1969 2061 else if ( rc == VERR_PDM_NO_ATTACHED_DRIVER … … 2032 2124 PVNETSTATE pThis = PDMINS_2_DATA(pDevIns, PVNETSTATE); 2033 2125 2126 #ifdef VNET_TX_DELAY 2034 2127 LogRel(("TxTimer stats (avg/min/max): %7d usec %7d usec %7d usec\n", 2035 2128 pThis->u32AvgDiff, pThis->u32MinDiff, pThis->u32MaxDiff)); 2129 #endif /* VNET_TX_DELAY */ 2036 2130 Log(("%s Destroying instance\n", INSTANCE(pThis))); 2037 2131 if (pThis->hEventMoreRxDescAvail != NIL_RTSEMEVENT) … … 2163 2257 return rc; 2164 2258 2165 #ifdef VNET_TX_DELAY 2259 #ifndef VNET_TX_DELAY 2260 pThis->pSupDrvSession = PDMDevHlpGetSupDrvSession(pDevIns); 2261 pThis->hTxEvent = NIL_SUPSEMEVENT; 2262 pThis->pTxThread = NULL; 2263 #else /* VNET_TX_DELAY */ 2166 2264 /* Create Transmit Delay Timer */ 2167 2265 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetTxTimer, pThis, … … 2188 2286 AssertMsgReturn(pThis->pDrv, ("Failed to obtain the PDMINETWORKUP interface!\n"), 2189 2287 VERR_PDM_MISSING_INTERFACE_BELOW); 2288 2289 vnetCreateTxThreadAndEvent(pDevIns, pThis); 2190 2290 } 2191 2291 else if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
Note:
See TracChangeset
for help on using the changeset viewer.