Changeset 81660 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- Nov 4, 2019 9:46:54 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r81658 r81660 81 81 82 82 #define VIRTIOSCSI_REQ_QUEUE_CNT 1 /**< T.B.D. Consider increasing */ 83 #define VIRTIOSCSI_QUEUE_CNT VIRTIOSCSI_REQ_QUEUE_CNT + 283 #define VIRTIOSCSI_QUEUE_CNT (VIRTIOSCSI_REQ_QUEUE_CNT + 2) 84 84 #define VIRTIOSCSI_MAX_LUN 256 /**< VirtIO specification, section 5.6.4 */ 85 85 #define VIRTIOSCSI_MAX_COMMANDS_PER_LUN 128 /**< T.B.D. What is a good value for this? */ … … 394 394 } VIRTIOSCSITARGET, *PVIRTIOSCSITARGET; 395 395 396 397 /** Why we're quiescing. */ 398 typedef enum VIRTIOSCSIQUIESCINGFOR 399 { 400 kvirtIoScsiQuiescingForInvalid = 0, 401 kvirtIoScsiQuiescingForReset, 402 kvirtIoScsiQuiescingForSuspend, 403 kvirtIoScsiQuiescingForPowerOff, 404 kvirtIoScsiQuiescingFor32BitHack = 0x7fffffff 405 } VIRTIOSCSIQUIESCINGFOR; 406 407 396 408 /** 397 409 * PDM instance data (state) for VirtIO Host SCSI device … … 492 504 /** True if in the process of quiescing I/O */ 493 505 uint32_t fQuiescing; 506 /** For which purpose we're quiescing. */ 507 VIRTIOSCSIQUIESCINGFOR enmQuiescingFor; 494 508 495 509 } VIRTIOSCSI, *PVIRTIOSCSI; … … 663 677 664 678 PVIRTIO_DESC_CHAIN_T pDescChain; 665 virtio QueueGet(&pThis->Virtio, EVENTQ_IDX, &pDescChain, true);679 virtioR3QueueGet(&pThis->Virtio, EVENTQ_IDX, &pDescChain, true); 666 680 667 681 RTSGBUF reqSegBuf; … … 669 683 RTSgBufInit(&reqSegBuf, aReqSegs, RT_ELEMENTS(aReqSegs)); 670 684 671 virtio QueuePut( &pThis->Virtio, EVENTQ_IDX, &reqSegBuf, pDescChain, true);685 virtioR3QueuePut( &pThis->Virtio, EVENTQ_IDX, &reqSegBuf, pDescChain, true); 672 686 virtioQueueSync(&pThis->Virtio, EVENTQ_IDX); 673 687 … … 719 733 pRespHdr->uResponse = VIRTIOSCSI_S_RESET; 720 734 721 virtio QueuePut(&pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true /* fFence */);735 virtioR3QueuePut(&pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true /* fFence */); 722 736 virtioQueueSync(&pThis->Virtio, qIdx); 723 737 … … 875 889 876 890 877 virtio QueuePut(&pThis->Virtio, pReq->qIdx, &reqSegBuf, pReq->pDescChain, true /* fFence TBD */);891 virtioR3QueuePut(&pThis->Virtio, pReq->qIdx, &reqSegBuf, pReq->pDescChain, true /* fFence TBD */); 878 892 virtioQueueSync(&pThis->Virtio, pReq->qIdx); 879 893 … … 1417 1431 1418 1432 LogFunc(("Response code: %s\n", virtioGetReqRespText(bResponse))); 1419 virtio QueuePut( &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true);1433 virtioR3QueuePut( &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true); 1420 1434 virtioQueueSync(&pThis->Virtio, qIdx); 1421 1435 … … 1476 1490 Log6Func(("fetching next descriptor chain from %s\n", QUEUENAME(qIdx))); 1477 1491 PVIRTIO_DESC_CHAIN_T pDescChain; 1478 int rc = virtio QueueGet(&pThis->Virtio, qIdx, &pDescChain, true);1492 int rc = virtioR3QueueGet(&pThis->Virtio, qIdx, &pDescChain, true); 1479 1493 if (rc == VERR_NOT_AVAILABLE) 1480 1494 { … … 2056 2070 static DECLCALLBACK(bool) virtioScsiR3DeviceQuiesced(PPDMDEVINS pDevIns) 2057 2071 { 2058 LogFunc(("Device I/O activity quiesced.\n"));2059 2072 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2060 2073 LogFunc(("Device I/O activity quiesced: enmQuiescingFor=%d\n", pThis->enmQuiescingFor)); 2074 2075 if (pThis->enmQuiescingFor == kvirtIoScsiQuiescingForReset) 2076 virtioR3PropagateResetNotification(&pThis->Virtio); 2077 /** @todo r=bird: Do we need other notifications here for suspend and/or poweroff? */ 2078 2079 pThis->enmQuiescingFor = kvirtIoScsiQuiescingForInvalid; 2061 2080 pThis->fQuiescing = false; 2062 2063 2081 return true; 2064 2082 } … … 2067 2085 * Worker for virtioScsiR3Reset() and virtioScsiR3SuspendOrPowerOff(). 2068 2086 */ 2069 static void virtioScsiR3QuiesceDevice(PPDMDEVINS pDevIns )2087 static void virtioScsiR3QuiesceDevice(PPDMDEVINS pDevIns, VIRTIOSCSIQUIESCINGFOR enmQuiscingFor) 2070 2088 { 2071 2089 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); … … 2073 2091 /* Prevent worker threads from removing/processing elements from virtq's */ 2074 2092 pThis->fQuiescing = true; 2093 pThis->enmQuiescingFor = enmQuiscingFor; 2075 2094 2076 2095 PDMDevHlpSetAsyncNotification(pDevIns, virtioScsiR3DeviceQuiesced); … … 2082 2101 2083 2102 /** 2084 * @interface_method_impl{PDMDEVREGR3,pfnResume} 2085 */ 2086 static DECLCALLBACK(void) virtioScsiR3Resume(PPDMDEVINS pDevIns) 2087 { 2088 LogFunc(("\n")); 2089 2103 * Common worker for suspend and power off. 2104 */ 2105 static void virtioScsiR3SuspendOrPowerOff(PPDMDEVINS pDevIns, VIRTIOSCSIQUIESCINGFOR enmQuiscingFor) 2106 { 2090 2107 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2091 2108 2092 pThis->fQuiescing = false; 2093 2094 /* Wake worker threads flagged to skip pulling queue entries during quiesce 2095 * to ensure they re-check their queues. Active request queues may already 2096 * be awake due to new reqs coming in. 2097 */ 2098 for (uint16_t qIdx = 0; qIdx < VIRTIOSCSI_REQ_QUEUE_CNT; qIdx++) 2099 { 2100 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx]; 2101 2102 if (ASMAtomicReadBool(&pWorker->fSleeping)) 2103 { 2104 Log6Func(("waking %s worker.\n", QUEUENAME(qIdx))); 2105 int rc = SUPSemEventSignal(pThis->pSupDrvSession, pWorker->hEvtProcess); 2106 AssertRC(rc); 2107 } 2108 } 2109 2110 /* Ensure guest is working the queues too. */ 2111 virtioPropagateResumeNotification(&pThis->Virtio); 2112 } 2113 2114 /** 2115 * @interface_method_impl{PDMDEVREGR3,pfnSuspend} 2116 */ 2117 static DECLCALLBACK(void) virtioScsiR3SuspendOrPowerOff(PPDMDEVINS pDevIns) 2118 { 2119 LogFunc(("\n")); 2120 2121 virtioScsiR3QuiesceDevice(pDevIns); 2122 2123 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2109 virtioScsiR3QuiesceDevice(pDevIns, enmQuiscingFor); 2110 2124 2111 2125 2112 /* VM is halted, thus no new I/O being dumped into queues by the guest. … … 2139 2126 2140 2127 /** 2128 * @interface_method_impl{PDMDEVREGR3,pfnPowerOff} 2129 */ 2130 static DECLCALLBACK(void) virtioScsiR3PowerOff(PPDMDEVINS pDevIns) 2131 { 2132 LogFunc(("\n")); 2133 virtioScsiR3SuspendOrPowerOff(pDevIns, kvirtIoScsiQuiescingForPowerOff); 2134 } 2135 2136 /** 2137 * @interface_method_impl{PDMDEVREGR3,pfnSuspend} 2138 */ 2139 static DECLCALLBACK(void) virtioScsiR3Suspend(PPDMDEVINS pDevIns) 2140 { 2141 LogFunc(("\n")); 2142 virtioScsiR3SuspendOrPowerOff(pDevIns, kvirtIoScsiQuiescingForSuspend); 2143 } 2144 2145 /** 2146 * @interface_method_impl{PDMDEVREGR3,pfnResume} 2147 */ 2148 static DECLCALLBACK(void) virtioScsiR3Resume(PPDMDEVINS pDevIns) 2149 { 2150 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2151 LogFunc(("\n")); 2152 2153 pThis->fQuiescing = false; 2154 2155 /* Wake worker threads flagged to skip pulling queue entries during quiesce 2156 * to ensure they re-check their queues. Active request queues may already 2157 * be awake due to new reqs coming in. 2158 */ 2159 for (uint16_t qIdx = 0; qIdx < VIRTIOSCSI_REQ_QUEUE_CNT; qIdx++) 2160 { 2161 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx]; 2162 2163 if (ASMAtomicReadBool(&pWorker->fSleeping)) 2164 { 2165 Log6Func(("waking %s worker.\n", QUEUENAME(qIdx))); 2166 int rc = SUPSemEventSignal(pThis->pSupDrvSession, pWorker->hEvtProcess); 2167 AssertRC(rc); 2168 } 2169 } 2170 2171 /* Ensure guest is working the queues too. */ 2172 virtioR3PropagateResumeNotification(&pThis->Virtio); 2173 } 2174 2175 /** 2141 2176 * @interface_method_impl{PDMDEVREGR3,pfnReset} 2142 2177 */ … … 2146 2181 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2147 2182 pThis->fResetting = true; 2148 virtioScsiR3QuiesceDevice(pDevIns); 2183 virtioScsiR3QuiesceDevice(pDevIns, kvirtIoScsiQuiescingForReset); 2184 2185 /** @todo r=bird: Shouldn't you reset the device here?!? */ 2149 2186 } 2150 2187 … … 2154 2191 static DECLCALLBACK(int) virtioScsiR3Destruct(PPDMDEVINS pDevIns) 2155 2192 { 2156 /*2157 * Check the versions here as well since the destructor is *always* called.2158 */2159 2160 2193 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns); 2161 2162 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2194 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2163 2195 2164 2196 RTMemFree(pThis->paTargetInstances); … … 2173 2205 } 2174 2206 } 2175 return VINF_SUCCESS; 2207 2208 virtioR3Term(&pThis->Virtio, pDevIns); 2209 return VINF_SUCCESS; 2176 2210 } 2177 2211 … … 2265 2299 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi: failed to initialize VirtIO")); 2266 2300 2301 /* Name the queues: */ 2267 2302 RTStrCopy(pThis->aszQueueNames[CONTROLQ_IDX], VIRTIO_MAX_QUEUE_NAME_SIZE, "controlq"); 2268 2303 RTStrCopy(pThis->aszQueueNames[EVENTQ_IDX], VIRTIO_MAX_QUEUE_NAME_SIZE, "eventq"); … … 2271 2306 "requestq<%d>", qIdx - VIRTQ_REQ_BASE); 2272 2307 2308 /* Attach the queues and create worker threads for them: */ 2273 2309 for (uint16_t qIdx = 0; qIdx < VIRTIOSCSI_QUEUE_CNT; qIdx++) 2274 2310 { 2275 rc = virtio QueueAttach(&pThis->Virtio, qIdx, QUEUENAME(qIdx));2276 pThis->afQueueAttached[qIdx] = (rc == VINF_SUCCESS); 2311 rc = virtioR3QueueAttach(&pThis->Virtio, qIdx, QUEUENAME(qIdx)); 2312 pThis->afQueueAttached[qIdx] = (rc == VINF_SUCCESS); /** @todo r=bird: This looks a bit fishy, esp. giving the following. */ 2277 2313 2278 2314 if (qIdx == CONTROLQ_IDX || IS_REQ_QUEUE(qIdx)) … … 2437 2473 /* .pfnPowerOn = */ NULL, 2438 2474 /* .pfnReset = */ virtioScsiR3Reset, 2439 /* .pfnSuspend = */ virtioScsiR3Suspend OrPowerOff,2475 /* .pfnSuspend = */ virtioScsiR3Suspend, 2440 2476 /* .pfnResume = */ virtioScsiR3Resume, 2441 2477 /* .pfnAttach = */ virtioScsiR3Attach, … … 2443 2479 /* .pfnQueryInterface = */ NULL, 2444 2480 /* .pfnInitComplete = */ NULL, 2445 /* .pfnPowerOff = */ virtioScsiR3 SuspendOrPowerOff,2481 /* .pfnPowerOff = */ virtioScsiR3PowerOff, 2446 2482 /* .pfnSoftReset = */ NULL, 2447 2483 /* .pfnReserved0 = */ NULL,
Note:
See TracChangeset
for help on using the changeset viewer.