Changeset 83058 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Feb 12, 2020 12:10:49 PM (5 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
r83028 r83058 1056 1056 static int virtioNetR3IsRxQueuePrimed(PPDMDEVINS pDevIns, PVIRTIONET pThis, uint16_t idxQueue) 1057 1057 { 1058 int rc; 1059 1060 LogFunc(("%s %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue))); 1058 #define LOGPARAMS INSTANCE(pThis), VIRTQNAME(idxQueue) 1061 1059 1062 1060 if (!pThis->fVirtioReady) 1063 rc = VERR_NET_NO_BUFFER_SPACE; 1064 1061 { 1062 LogFunc(("%s %s VirtIO not ready (rc = VERR_NET_NO_BUFFER_SPACE)\n", LOGPARAMS)); 1063 } 1065 1064 else if (!virtioCoreIsQueueEnabled(&pThis->Virtio, RXQIDX_QPAIR(idxQueue))) 1066 rc = VERR_NET_NO_BUFFER_SPACE; 1067 1065 { 1066 LogFunc(("%s %s queue not enabled (rc = VERR_NET_NO_BUFFER_SPACE)\n", LOGPARAMS)); 1067 } 1068 1068 else if (virtioCoreQueueIsEmpty(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue))) 1069 1069 { 1070 LogFunc(("%s %s queue is empty (rc = VERR_NET_NO_BUFFER_SPACE)\n", LOGPARAMS)); 1070 1071 virtioCoreQueueSetNotify(&pThis->Virtio, RXQIDX_QPAIR(idxQueue), true); 1071 rc = VERR_NET_NO_BUFFER_SPACE;1072 1072 } 1073 1073 else 1074 1074 { 1075 LogFunc(("%s %s ready with available buffers\n", LOGPARAMS)); 1075 1076 virtioCoreQueueSetNotify(&pThis->Virtio, RXQIDX_QPAIR(idxQueue), false); 1076 rc = VINF_SUCCESS; 1077 } 1078 1079 LogFlowFunc(("%s idxQueue = %d -> %Rrc\n", INSTANCE(pThis), idxQueue, rc)); 1080 return rc; 1081 } 1082 1077 return VINF_SUCCESS; 1078 } 1079 return VERR_NET_NO_BUFFER_SPACE; 1080 } 1081 1082 1083 static bool virtioNetR3AreRxBufsAvail(PPDMDEVINS pDevIns, PVIRTIONET pThis) 1084 { 1085 /** @todo If we ever start using more than one Rx/Tx queue pair, is a random queue 1086 selection algorithm feasible or even necessary to prevent starvation? */ 1087 for (int idxQueue = 0; idxQueue < pThis->cVirtQueues; idxQueue += 2) /* Skip odd queue #'s because Rx queues only! */ 1088 { 1089 if (!IS_RX_QUEUE(idxQueue)) 1090 continue; 1091 1092 if (RT_SUCCESS(virtioNetR3IsRxQueuePrimed(pDevIns, pThis, idxQueue))) 1093 return true; 1094 } 1095 return false; 1096 } 1083 1097 /* 1084 1098 * Returns true if VirtIO core and device are in a running and operational state … … 1108 1122 PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET); 1109 1123 1110 if (!virtioNetAllSystemsGo(pThis, pDevIns)) 1111 { 1112 LogFunc(("%s VirtIO not ready\n", INSTANCE(pThis))); 1113 return VERR_NET_NO_BUFFER_SPACE; 1114 } 1115 1124 if (virtioNetR3AreRxBufsAvail(pDevIns, pThis)) 1125 { 1126 LogFunc(("%s Rx bufs now available, releasing waiter...\n", INSTANCE(pThis))); 1127 return VINF_SUCCESS; 1128 } 1116 1129 if (!timeoutMs) 1117 1130 return VERR_NET_NO_BUFFER_SPACE; … … 1121 1134 ASMAtomicXchgBool(&pThis->fLeafWantsRxBuffers, true); 1122 1135 1123 /** @todo If we ever start using more than one Rx/Tx queue pair, is a random queue1124 selection algorithm feasible or even necessary to prevent starvation? */1125 1136 do { 1126 for (int idxQueue = 0; idxQueue < pThis->cVirtQueues; idxQueue += 2) /* Skip odd queue #'s because Rx queues only! */1137 if (virtioNetR3AreRxBufsAvail(pDevIns, pThis)) 1127 1138 { 1128 if (!IS_RX_QUEUE(idxQueue)) 1129 continue; 1130 1131 if (RT_SUCCESS(virtioNetR3IsRxQueuePrimed(pDevIns, pThis, idxQueue))) 1132 { 1133 LogFunc(("%s Rx bufs now available, releasing waiter...", INSTANCE(pThis))); 1139 LogFunc(("%s Rx bufs now available, releasing waiter...\n", INSTANCE(pThis))); 1134 1140 return VINF_SUCCESS; 1135 }1136 1141 } 1137 1142 LogFunc(("%s Starved for guest Rx bufs, waiting %u ms ...\n", 1138 1143 INSTANCE(pThis), timeoutMs)); 1139 1144 1140 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, 1141 pThis->hEventRxDescAvail, timeoutMs); 1145 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->hEventRxDescAvail, timeoutMs); 1142 1146 1143 1147 if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED) … … 1455 1459 size_t cb, PCPDMNETWORKGSO pGso) 1456 1460 { 1461 LogFunc(("\n")); 1457 1462 PVIRTIONETCC pThisCC = RT_FROM_MEMBER(pInterface, VIRTIONETCC, INetworkDown); 1458 1463 PPDMDEVINS pDevIns = pThisCC->pDevIns; 1459 1464 PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET); 1460 1461 LogFunc(("%s\n", pThis));1462 1465 1463 1466 if (!pThis->fVirtioReady) … … 2068 2071 /** @todo If we ever start using more than one Rx/Tx queue pair, is a random queue 2069 2072 selection algorithm feasible or even necessary */ 2070 2073 LogFunc(("\n")); 2071 2074 virtioNetR3TransmitPendingPackets(pDevIns, pThis, pThisCC, TXQIDX_QPAIR(0), false /*fOnWorkerThread*/); 2072 2075 } … … 2625 2628 /* Initialize the generic Virtio core: */ 2626 2629 pThisCC->Virtio.pfnStatusChanged = virtioNetR3StatusChanged; 2627 pThisCC->Virtio.pfnQueueNotified = virtioNetR3QueueNotified 2628 ; 2630 pThisCC->Virtio.pfnQueueNotified = virtioNetR3QueueNotified; 2629 2631 pThisCC->Virtio.pfnDevCapRead = virtioNetR3DevCapRead; 2630 2632 pThisCC->Virtio.pfnDevCapWrite = virtioNetR3DevCapWrite; -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r83028 r83058 226 226 } 227 227 228 DECLINLINE(void) virtioWriteUsed Flags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue, uint16_t fFlags)228 DECLINLINE(void) virtioWriteUsedRingFlags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue, uint16_t fFlags) 229 229 { 230 230 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); … … 256 256 #endif 257 257 258 DECLINLINE(uint16_t) virtioReadUsed Flags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue)258 DECLINLINE(uint16_t) virtioReadUsedRingFlags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue) 259 259 { 260 260 uint16_t fFlags = 0; … … 681 681 if (pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK) 682 682 { 683 uint16_t fFlags = virtioReadUsed Flags(pVirtio->pDevIns, pVirtio, idxQueue);683 uint16_t fFlags = virtioReadUsedRingFlags(pVirtio->pDevIns, pVirtio, idxQueue); 684 684 685 685 if (fEnabled) … … 688 688 fFlags |= VIRTQ_USED_F_NO_NOTIFY; 689 689 690 virtioWriteUsed Flags(pVirtio->pDevIns, pVirtio, idxQueue, fFlags);690 virtioWriteUsedRingFlags(pVirtio->pDevIns, pVirtio, idxQueue, fFlags); 691 691 } 692 692 } … … 1014 1014 { 1015 1015 /** If guest driver hasn't suppressed interrupts, interrupt */ 1016 if (fForce || !(virtioReadUsed Flags(pDevIns, pVirtio, idxQueue) & VIRTQ_AVAIL_F_NO_INTERRUPT))1016 if (fForce || !(virtioReadUsedRingFlags(pDevIns, pVirtio, idxQueue) & VIRTQ_AVAIL_F_NO_INTERRUPT)) 1017 1017 { 1018 1018 virtioKick(pDevIns, pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uQueueMsixVector[idxQueue], fForce);
Note:
See TracChangeset
for help on using the changeset viewer.