Changeset 38877 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Sep 27, 2011 9:04:46 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
r37933 r38877 1271 1271 PFNPDMBLKCACHEXFERCOMPLETEDRV pfnXferComplete, 1272 1272 PFNPDMBLKCACHEXFERENQUEUEDRV pfnXferEnqueue, 1273 PFNPDMBLKCACHEXFERENQUEUEDISCARDDRV pfnXferEnqueueDiscard, 1273 1274 const char *pcszId) 1274 1275 { … … 1279 1280 if (RT_SUCCESS(rc)) 1280 1281 { 1281 pBlkCache->enmType = PDMBLKCACHETYPE_DRV; 1282 pBlkCache->u.Drv.pfnXferComplete = pfnXferComplete; 1283 pBlkCache->u.Drv.pfnXferEnqueue = pfnXferEnqueue; 1284 pBlkCache->u.Drv.pDrvIns = pDrvIns; 1282 pBlkCache->enmType = PDMBLKCACHETYPE_DRV; 1283 pBlkCache->u.Drv.pfnXferComplete = pfnXferComplete; 1284 pBlkCache->u.Drv.pfnXferEnqueue = pfnXferEnqueue; 1285 pBlkCache->u.Drv.pfnXferEnqueueDiscard = pfnXferEnqueueDiscard; 1286 pBlkCache->u.Drv.pDrvIns = pDrvIns; 1285 1287 *ppBlkCache = pBlkCache; 1286 1288 } … … 1293 1295 PFNPDMBLKCACHEXFERCOMPLETEDEV pfnXferComplete, 1294 1296 PFNPDMBLKCACHEXFERENQUEUEDEV pfnXferEnqueue, 1297 PFNPDMBLKCACHEXFERENQUEUEDISCARDDEV pfnXferEnqueueDiscard, 1295 1298 const char *pcszId) 1296 1299 { … … 1301 1304 if (RT_SUCCESS(rc)) 1302 1305 { 1303 pBlkCache->enmType = PDMBLKCACHETYPE_DEV; 1304 pBlkCache->u.Dev.pfnXferComplete = pfnXferComplete; 1305 pBlkCache->u.Dev.pfnXferEnqueue = pfnXferEnqueue; 1306 pBlkCache->u.Dev.pDevIns = pDevIns; 1306 pBlkCache->enmType = PDMBLKCACHETYPE_DEV; 1307 pBlkCache->u.Dev.pfnXferComplete = pfnXferComplete; 1308 pBlkCache->u.Dev.pfnXferEnqueue = pfnXferEnqueue; 1309 pBlkCache->u.Dev.pfnXferEnqueueDiscard = pfnXferEnqueueDiscard; 1310 pBlkCache->u.Dev.pDevIns = pDevIns; 1307 1311 *ppBlkCache = pBlkCache; 1308 1312 } … … 1316 1320 PFNPDMBLKCACHEXFERCOMPLETEUSB pfnXferComplete, 1317 1321 PFNPDMBLKCACHEXFERENQUEUEUSB pfnXferEnqueue, 1322 PFNPDMBLKCACHEXFERENQUEUEDISCARDUSB pfnXferEnqueueDiscard, 1318 1323 const char *pcszId) 1319 1324 { … … 1324 1329 if (RT_SUCCESS(rc)) 1325 1330 { 1326 pBlkCache->enmType = PDMBLKCACHETYPE_USB; 1327 pBlkCache->u.Usb.pfnXferComplete = pfnXferComplete; 1328 pBlkCache->u.Usb.pfnXferEnqueue = pfnXferEnqueue; 1329 pBlkCache->u.Usb.pUsbIns = pUsbIns; 1331 pBlkCache->enmType = PDMBLKCACHETYPE_USB; 1332 pBlkCache->u.Usb.pfnXferComplete = pfnXferComplete; 1333 pBlkCache->u.Usb.pfnXferEnqueue = pfnXferEnqueue; 1334 pBlkCache->u.Usb.pfnXferEnqueueDiscard = pfnXferEnqueueDiscard; 1335 pBlkCache->u.Usb.pUsbIns = pUsbIns; 1330 1336 *ppBlkCache = pBlkCache; 1331 1337 } … … 1339 1345 PFNPDMBLKCACHEXFERCOMPLETEINT pfnXferComplete, 1340 1346 PFNPDMBLKCACHEXFERENQUEUEINT pfnXferEnqueue, 1347 PFNPDMBLKCACHEXFERENQUEUEDISCARDINT pfnXferEnqueueDiscard, 1341 1348 const char *pcszId) 1342 1349 { … … 1347 1354 if (RT_SUCCESS(rc)) 1348 1355 { 1349 pBlkCache->enmType = PDMBLKCACHETYPE_INTERNAL; 1350 pBlkCache->u.Int.pfnXferComplete = pfnXferComplete; 1351 pBlkCache->u.Int.pfnXferEnqueue = pfnXferEnqueue; 1352 pBlkCache->u.Int.pvUser = pvUser; 1356 pBlkCache->enmType = PDMBLKCACHETYPE_INTERNAL; 1357 pBlkCache->u.Int.pfnXferComplete = pfnXferComplete; 1358 pBlkCache->u.Int.pfnXferEnqueue = pfnXferEnqueue; 1359 pBlkCache->u.Int.pfnXferEnqueueDiscard = pfnXferEnqueueDiscard; 1360 pBlkCache->u.Int.pvUser = pvUser; 1353 1361 *ppBlkCache = pBlkCache; 1354 1362 } … … 2408 2416 } 2409 2417 2418 VMMR3DECL(int) PDMR3BlkCacheDiscard(PPDMBLKCACHE pBlkCache, PCRTRANGE paRanges, 2419 unsigned cRanges, void *pvUser) 2420 { 2421 int rc = VINF_SUCCESS; 2422 PPDMBLKCACHEGLOBAL pCache = pBlkCache->pCache; 2423 PPDMBLKCACHEENTRY pEntry; 2424 PPDMBLKCACHEREQ pReq; 2425 2426 LogFlowFunc((": pBlkCache=%#p{%s} paRanges=%#p cRanges=%u pvUser=%#p\n", 2427 pBlkCache, pBlkCache->pszId, paRanges, cRanges, pvUser)); 2428 2429 AssertPtrReturn(pBlkCache, VERR_INVALID_POINTER); 2430 AssertReturn(!pBlkCache->fSuspended, VERR_INVALID_STATE); 2431 2432 /* Allocate new request structure. */ 2433 pReq = pdmBlkCacheReqAlloc(pvUser); 2434 if (RT_UNLIKELY(!pReq)) 2435 return VERR_NO_MEMORY; 2436 2437 /* Increment data transfer counter to keep the request valid while we access it. */ 2438 ASMAtomicIncU32(&pReq->cXfersPending); 2439 2440 for (unsigned i = 0; i < cRanges; i++) 2441 { 2442 uint64_t offCur = paRanges[i].offStart; 2443 size_t cbLeft = paRanges[i].cbRange; 2444 2445 while (cbLeft) 2446 { 2447 size_t cbThisDiscard; 2448 2449 pEntry = pdmBlkCacheGetCacheEntryByOffset(pBlkCache, offCur); 2450 2451 if (pEntry) 2452 { 2453 /* Write the data into the entry and mark it as dirty */ 2454 AssertPtr(pEntry->pList); 2455 2456 uint64_t offDiff = offCur - pEntry->Core.Key; 2457 2458 AssertMsg(offCur >= pEntry->Core.Key, 2459 ("Overflow in calculation offCur=%llu OffsetAligned=%llu\n", 2460 offCur, pEntry->Core.Key)); 2461 2462 cbThisDiscard = RT_MIN(pEntry->cbData - offDiff, cbLeft); 2463 2464 /* Ghost lists contain no data. */ 2465 if ( (pEntry->pList == &pCache->LruRecentlyUsedIn) 2466 || (pEntry->pList == &pCache->LruFrequentlyUsed)) 2467 { 2468 /* Check if the entry is dirty. */ 2469 if (pdmBlkCacheEntryFlagIsSetClearAcquireLock(pBlkCache, pEntry, 2470 PDMBLKCACHE_ENTRY_IS_DIRTY, 2471 0)) 2472 { 2473 /* If it is dirty but not yet in progress remove it. */ 2474 if (!(pEntry->fFlags & PDMBLKCACHE_ENTRY_IO_IN_PROGRESS)) 2475 { 2476 pdmBlkCacheLockEnter(pCache); 2477 pdmBlkCacheEntryRemoveFromList(pEntry); 2478 2479 STAM_PROFILE_ADV_START(&pCache->StatTreeRemove, Cache); 2480 RTAvlrU64Remove(pBlkCache->pTree, pEntry->Core.Key); 2481 STAM_PROFILE_ADV_STOP(&pCache->StatTreeRemove, Cache); 2482 2483 pdmBlkCacheLockLeave(pCache); 2484 2485 RTMemFree(pEntry); 2486 } 2487 else 2488 { 2489 #if 0 2490 /* The data isn't written to the file yet */ 2491 pdmBlkCacheEntryWaitersAdd(pEntry, pReq, 2492 &SgBuf, offDiff, cbToWrite, 2493 true /* fWrite */); 2494 STAM_COUNTER_INC(&pBlkCache->StatWriteDeferred); 2495 #endif 2496 } 2497 2498 RTSemRWReleaseWrite(pBlkCache->SemRWEntries); 2499 pdmBlkCacheEntryRelease(pEntry); 2500 } 2501 else /* Dirty bit not set */ 2502 { 2503 /* 2504 * Check if a read is in progress for this entry. 2505 * We have to defer processing in that case. 2506 */ 2507 if(pdmBlkCacheEntryFlagIsSetClearAcquireLock(pBlkCache, pEntry, 2508 PDMBLKCACHE_ENTRY_IO_IN_PROGRESS, 2509 0)) 2510 { 2511 #if 0 2512 pdmBlkCacheEntryWaitersAdd(pEntry, pReq, 2513 &SgBuf, offDiff, cbToWrite, 2514 true /* fWrite */); 2515 #endif 2516 STAM_COUNTER_INC(&pBlkCache->StatWriteDeferred); 2517 RTSemRWReleaseWrite(pBlkCache->SemRWEntries); 2518 pdmBlkCacheEntryRelease(pEntry); 2519 } 2520 else /* I/O in progress flag not set */ 2521 { 2522 pdmBlkCacheLockEnter(pCache); 2523 pdmBlkCacheEntryRemoveFromList(pEntry); 2524 2525 RTSemRWRequestWrite(pBlkCache->SemRWEntries, RT_INDEFINITE_WAIT); 2526 STAM_PROFILE_ADV_START(&pCache->StatTreeRemove, Cache); 2527 RTAvlrU64Remove(pBlkCache->pTree, pEntry->Core.Key); 2528 STAM_PROFILE_ADV_STOP(&pCache->StatTreeRemove, Cache); 2529 RTSemRWReleaseWrite(pBlkCache->SemRWEntries); 2530 2531 pdmBlkCacheLockLeave(pCache); 2532 2533 RTMemFree(pEntry); 2534 } 2535 } /* Dirty bit not set */ 2536 } 2537 else /* Entry is on the ghost list just remove cache entry. */ 2538 { 2539 pdmBlkCacheLockEnter(pCache); 2540 pdmBlkCacheEntryRemoveFromList(pEntry); 2541 2542 RTSemRWRequestWrite(pBlkCache->SemRWEntries, RT_INDEFINITE_WAIT); 2543 STAM_PROFILE_ADV_START(&pCache->StatTreeRemove, Cache); 2544 RTAvlrU64Remove(pBlkCache->pTree, pEntry->Core.Key); 2545 STAM_PROFILE_ADV_STOP(&pCache->StatTreeRemove, Cache); 2546 RTSemRWReleaseWrite(pBlkCache->SemRWEntries); 2547 2548 pdmBlkCacheLockLeave(pCache); 2549 2550 RTMemFree(pEntry); 2551 } 2552 } 2553 /* else: no entry found. */ 2554 2555 offCur += cbThisDiscard; 2556 cbLeft -= cbThisDiscard; 2557 } 2558 } 2559 2560 if (!pdmBlkCacheReqUpdate(pBlkCache, pReq, rc, false)) 2561 rc = VINF_AIO_TASK_PENDING; 2562 2563 LogFlowFunc((": Leave rc=%Rrc\n", rc)); 2564 2565 return rc; 2566 } 2567 2410 2568 /** 2411 2569 * Completes a task segment freeing all resources and completes the task handle
Note:
See TracChangeset
for help on using the changeset viewer.