Changeset 34386 in vbox
- Timestamp:
- Nov 25, 2010 5:10:52 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PDMBlkCache.cpp
r34347 r34386 1013 1013 { 1014 1014 /* Arm the timer if this is the first endpoint. */ 1015 if ( pBlkCacheGlobal->cRefs == 11015 if ( !pBlkCacheGlobal->cRefs 1016 1016 && pBlkCacheGlobal->u32CommitTimeoutMs > 0) 1017 1017 rc = TMTimerSetMillies(pBlkCacheGlobal->pTimerCommit, pBlkCacheGlobal->u32CommitTimeoutMs); … … 1208 1208 PPDMBLKCACHEGLOBAL pCache = pBlkCache->pCache; 1209 1209 1210 /* 1211 * Commit all dirty entries now (they are waited on for completion during the 1212 * destruction of the AVL tree below). 1213 * The exception is if the VM was paused because of an I/O error before. 1214 */ 1215 if (!ASMAtomicReadBool(&pCache->fIoErrorVmSuspended)) 1216 pdmBlkCacheCommit(pBlkCache); 1217 1210 1218 /* Make sure nobody is accessing the cache while we delete the tree. */ 1211 1219 pdmBlkCacheLockEnter(pCache); … … 1351 1359 * @param pEntryAbove Where to store the pointer to the best fit entry above the 1352 1360 * the given offset. NULL if not required. 1353 * @param pEntryBelow Where to store the pointer to the best fit entry below the1354 * the given offset. NULL if not required.1355 1361 */ 1356 1362 static void pdmBlkCacheGetCacheBestFitEntryByOffset(PPDMBLKCACHE pBlkCache, uint64_t off, 1357 PPDMBLKCACHEENTRY *ppEntryAbove, 1358 PPDMBLKCACHEENTRY *ppEntryBelow) 1363 PPDMBLKCACHEENTRY *ppEntryAbove) 1359 1364 { 1360 1365 PPDMBLKCACHEGLOBAL pCache = pBlkCache->pCache; … … 1370 1375 } 1371 1376 1372 if (ppEntryBelow)1373 {1374 *ppEntryBelow = (PPDMBLKCACHEENTRY)RTAvlrU64GetBestFit(pBlkCache->pTree, off, false /*fAbove*/);1375 if (*ppEntryBelow)1376 pdmBlkCacheEntryRef(*ppEntryBelow);1377 }1378 1377 RTSemRWReleaseRead(pBlkCache->SemRWEntries); 1379 1378 … … 1517 1516 static int pdmBlkCacheEntryWaitersAdd(PPDMBLKCACHEENTRY pEntry, 1518 1517 PPDMBLKCACHEREQ pReq, 1519 P CRTSGBUF pSgBuf, uint64_t offDiff,1518 PRTSGBUF pSgBuf, uint64_t offDiff, 1520 1519 size_t cbData, bool fWrite) 1521 1520 { … … 1530 1529 pWaiter->fWrite = fWrite; 1531 1530 RTSgBufClone(&pWaiter->SgBuf, pSgBuf); 1531 RTSgBufAdvance(pSgBuf, cbData); 1532 1532 1533 1533 pdmBlkCacheEntryAddWaiter(pEntry, pWaiter); … … 1560 1560 uint64_t offAligned; 1561 1561 PPDMBLKCACHEENTRY pEntryAbove = NULL; 1562 PPDMBLKCACHEENTRY pEntryBelow = NULL;1563 1562 1564 1563 /* Get the best fit entries around the offset */ 1565 pdmBlkCacheGetCacheBestFitEntryByOffset(pBlkCache, off, &pEntryAbove , &pEntryBelow);1564 pdmBlkCacheGetCacheBestFitEntryByOffset(pBlkCache, off, &pEntryAbove); 1566 1565 1567 1566 /* Log the info */ 1568 LogFlow(("%sest fit entry below off=%llu (BestFit=%llu BestFitEnd=%llu BestFitSize=%u)\n",1569 pEntryBelow ? "B" : "No b",1570 off,1571 pEntryBelow ? pEntryBelow->Core.Key : 0,1572 pEntryBelow ? pEntryBelow->Core.KeyLast : 0,1573 pEntryBelow ? pEntryBelow->cbData : 0));1574 1575 1567 LogFlow(("%sest fit entry above off=%llu (BestFit=%llu BestFitEnd=%llu BestFitSize=%u)\n", 1576 1568 pEntryAbove ? "B" : "No b", … … 1580 1572 pEntryAbove ? pEntryAbove->cbData : 0)); 1581 1573 1582 /* Align the offset first. */ 1583 offAligned = off & ~(uint64_t)(512-1); 1584 if ( pEntryBelow 1585 && offAligned <= pEntryBelow->Core.KeyLast) 1586 offAligned = pEntryBelow->Core.KeyLast; 1574 offAligned = off; 1587 1575 1588 1576 if ( pEntryAbove … … 1599 1587 1600 1588 /* A few sanity checks */ 1601 AssertMsg(!pEntryBelow || pEntryBelow->Core.KeyLast < offAligned,1602 ("Aligned start offset intersects with another cache entry\n"));1603 1589 AssertMsg(!pEntryAbove || (offAligned + cbAligned) <= pEntryAbove->Core.Key, 1604 1590 ("Aligned size intersects with another cache entry\n")); 1605 1591 Assert(cbInEntry <= cbAligned); 1606 1592 1607 if (pEntryBelow)1608 pdmBlkCacheEntryRelease(pEntryBelow);1609 1593 if (pEntryAbove) 1610 1594 pdmBlkCacheEntryRelease(pEntryAbove); … … 1933 1917 /* Clip read size if necessary. */ 1934 1918 PPDMBLKCACHEENTRY pEntryAbove; 1935 pdmBlkCacheGetCacheBestFitEntryByOffset(pBlkCache, off, 1936 &pEntryAbove, NULL); 1919 pdmBlkCacheGetCacheBestFitEntryByOffset(pBlkCache, off, &pEntryAbove); 1937 1920 1938 1921 if (pEntryAbove) … … 2019 2002 { 2020 2003 /* Check if the entry is dirty. */ 2021 if (pdmBlkCacheEntryFlagIsSetClearAcquireLock(pBlkCache, pEntry,2022 PDMBLKCACHE_ENTRY_IS_DIRTY,2023 0))2004 if (pdmBlkCacheEntryFlagIsSetClearAcquireLock(pBlkCache, pEntry, 2005 PDMBLKCACHE_ENTRY_IS_DIRTY, 2006 0)) 2024 2007 { 2025 2008 /* If it is already dirty but not in progress just update the data. */ … … 2272 2255 * the user fixed the problem and the next write succeeds. 2273 2256 */ 2274 /** @todo r=aeichner: This solution doesn't work2275 * The user will get the message but the VM will hang afterwards2276 * VMR3Suspend() returns when the VM is suspended but suspending2277 * the VM will reopen the images readonly in DrvVD. They are closed first2278 * which will close the endpoints. This will block EMT while the2279 * I/O manager processes the close request but the IO manager is stuck2280 * in the VMR3Suspend call and can't process the request.2281 * Another problem is that closing the VM means flushing the cache2282 * but the entry failed and will probably fail again.2283 * No idea so far how to solve this problem... but the user gets informed2284 * at least.2285 */2286 2257 if (RT_FAILURE(rcIoXfer)) 2287 2258 {
Note:
See TracChangeset
for help on using the changeset viewer.