Changeset 23404 in vbox for trunk/src/VBox
- Timestamp:
- Sep 29, 2009 10:18:37 AM (15 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h
r22851 r23404 331 331 /** Global cache data. */ 332 332 PDMACFILECACHEGLOBAL Cache; 333 /** Flag whether the out of resources warning was printed already. */ 334 bool fOutOfResourcesWarningPrinted; 333 335 } PDMASYNCCOMPLETIONEPCLASSFILE; 334 336 /** Pointer to the endpoint class data. */ -
trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp
r23213 r23404 287 287 } 288 288 289 /** 290 * Put a list of tasks in the pending request list of an endpoint. 291 */ 292 DECLINLINE(void) pdmacFileAioMgrEpAddTaskList(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTaskHead) 293 { 294 /* Add the rest of the tasks to the pending list */ 295 if (!pEndpoint->AioMgr.pReqsPendingHead) 296 { 297 Assert(!pEndpoint->AioMgr.pReqsPendingTail); 298 pEndpoint->AioMgr.pReqsPendingHead = pTaskHead; 299 } 300 else 301 { 302 Assert(pEndpoint->AioMgr.pReqsPendingTail); 303 pEndpoint->AioMgr.pReqsPendingTail->pNext = pTaskHead; 304 } 305 306 /* Update the tail. */ 307 while (pTaskHead->pNext) 308 pTaskHead = pTaskHead->pNext; 309 310 pEndpoint->AioMgr.pReqsPendingTail = pTaskHead; 311 } 312 313 /** 314 * Put one task in the pending request list of an endpoint. 315 */ 316 DECLINLINE(void) pdmacFileAioMgrEpAddTask(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTask) 317 { 318 /* Add the rest of the tasks to the pending list */ 319 if (!pEndpoint->AioMgr.pReqsPendingHead) 320 { 321 Assert(!pEndpoint->AioMgr.pReqsPendingTail); 322 pEndpoint->AioMgr.pReqsPendingHead = pTask; 323 } 324 else 325 { 326 Assert(pEndpoint->AioMgr.pReqsPendingTail); 327 pEndpoint->AioMgr.pReqsPendingTail->pNext = pTask; 328 } 329 330 pEndpoint->AioMgr.pReqsPendingTail = pTask; 331 } 332 333 /** 334 * Wrapper around RTFIleAioCtxSubmit() which is also doing error handling. 335 */ 336 static int pdmacFileAioMgrNormalReqsEnqueue(PPDMACEPFILEMGR pAioMgr, 337 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, 338 PRTFILEAIOREQ pahReqs, size_t cReqs) 339 { 340 int rc; 341 342 pAioMgr->cRequestsActive += cReqs; 343 pEndpoint->AioMgr.cRequestsActive += cReqs; 344 345 rc = RTFileAioCtxSubmit(pAioMgr->hAioCtx, pahReqs, cReqs); 346 if (RT_FAILURE(rc)) 347 { 348 if (rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES) 349 { 350 PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEndpoint->Core.pEpClass; 351 352 /* 353 * We run out of resources. 354 * Need to check which requests got queued 355 * and put the rest on the pending list again. 356 */ 357 if (RT_UNLIKELY(!pEpClass->fOutOfResourcesWarningPrinted)) 358 { 359 pEpClass->fOutOfResourcesWarningPrinted = true; 360 LogRel(("AIOMgr: The operating system doesn't have enough resources " 361 "to handle the I/O load of the VM. Expect reduced I/O performance\n")); 362 } 363 364 for (size_t i = 0; i < cReqs; i++) 365 { 366 int rcReq = RTFileAioReqGetRC(pahReqs[i], NULL); 367 368 if (rcReq != VERR_FILE_AIO_IN_PROGRESS) 369 { 370 AssertMsg(rcReq == VERR_FILE_AIO_NOT_SUBMITTED, 371 ("Request returned unexpected return code: rc=%Rrc\n", rcReq)); 372 373 PPDMACTASKFILE pTask = (PPDMACTASKFILE)RTFileAioReqGetUser(pahReqs[i]); 374 375 /* Put the entry on the free array */ 376 pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = pahReqs[i]; 377 pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) % pAioMgr->cReqEntries; 378 379 pdmacFileAioMgrEpAddTask(pEndpoint, pTask); 380 pAioMgr->cRequestsActive--; 381 pEndpoint->AioMgr.cRequestsActive--; 382 } 383 } 384 } 385 else 386 AssertMsgFailed(("Unexpected return code rc=%Rrc\n", rc)); 387 } 388 389 return rc; 390 } 391 289 392 static int pdmacFileAioMgrNormalProcessTaskList(PPDMACTASKFILE pTaskHead, 290 393 PPDMACEPFILEMGR pAioMgr, … … 307 410 pTaskHead = pTaskHead->pNext; 308 411 412 pCurr->pNext = NULL; 413 309 414 AssertMsg(VALID_PTR(pCurr->pEndpoint) && (pCurr->pEndpoint == pEndpoint), 310 415 ("Endpoints do not match\n")); … … 324 429 pEndpoint->pFlushReq = pCurr; 325 430 326 if (pTaskHead) 327 { 328 /* Add the rest of the tasks to the pending list */ 329 if (!pEndpoint->AioMgr.pReqsPendingHead) 330 { 331 Assert(!pEndpoint->AioMgr.pReqsPendingTail); 332 pEndpoint->AioMgr.pReqsPendingHead = pTaskHead; 333 } 334 else 335 { 336 Assert(pEndpoint->AioMgr.pReqsPendingTail); 337 pEndpoint->AioMgr.pReqsPendingTail->pNext = pTaskHead; 338 } 339 340 /* Update the tail. */ 341 while (pTaskHead->pNext) 342 pTaskHead = pTaskHead->pNext; 343 344 pEndpoint->AioMgr.pReqsPendingTail = pTaskHead; 345 } 431 /* Do not process the task list further until the flush finished. */ 432 pdmacFileAioMgrEpAddTaskList(pEndpoint, pTaskHead); 346 433 } 347 434 break; … … 444 531 if (cRequests == RT_ELEMENTS(apReqs)) 445 532 { 446 pAioMgr->cRequestsActive += cRequests; 447 pEndpoint->AioMgr.cRequestsActive += cRequests; 448 rc = RTFileAioCtxSubmit(pAioMgr->hAioCtx, apReqs, cRequests); 533 rc = pdmacFileAioMgrNormalReqsEnqueue(pAioMgr, pEndpoint, apReqs, cRequests); 534 cRequests = 0; 449 535 if (RT_FAILURE(rc)) 450 536 { 451 /* @todo implement */452 AssertMsgFailed(("Implement\n"));537 AssertMsg(rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES, ("Unexpected return code\n")); 538 break; 453 539 } 454 455 cRequests = 0;456 540 } 457 541 break; … … 464 548 if (cRequests) 465 549 { 466 pAioMgr->cRequestsActive += cRequests; 467 pEndpoint->AioMgr.cRequestsActive += cRequests; 468 rc = RTFileAioCtxSubmit(pAioMgr->hAioCtx, apReqs, cRequests); 469 AssertMsgReturn(RT_SUCCESS(rc), ("Could not submit %u requests %Rrc\n", cRequests, rc), rc); 470 } 471 472 if (RT_UNLIKELY(!cMaxRequests && pTaskHead && !pEndpoint->pFlushReq)) 473 { 474 /* 475 * The I/O manager has no room left for more requests 476 * but there are still requests to process. 477 * Create a new I/O manager and let it handle some endpoints. 478 */ 479 480 /* Add the rest of the tasks to the pending list first */ 481 if (!pEndpoint->AioMgr.pReqsPendingHead) 482 { 483 Assert(!pEndpoint->AioMgr.pReqsPendingTail); 484 pEndpoint->AioMgr.pReqsPendingHead = pTaskHead; 485 } 486 else 487 { 488 Assert(pEndpoint->AioMgr.pReqsPendingTail); 489 pEndpoint->AioMgr.pReqsPendingTail->pNext = pTaskHead; 490 } 491 492 /* Update the tail. */ 493 while (pTaskHead->pNext) 494 pTaskHead = pTaskHead->pNext; 495 496 pEndpoint->AioMgr.pReqsPendingTail = pTaskHead; 497 498 pdmacFileAioMgrNormalBalanceLoad(pAioMgr); 499 } 550 rc = pdmacFileAioMgrNormalReqsEnqueue(pAioMgr, pEndpoint, apReqs, cRequests); 551 AssertMsg(RT_SUCCESS(rc) || (rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES), 552 ("Unexpected return code rc=%Rrc\n", rc)); 553 } 554 555 if (pTaskHead) 556 { 557 /* Add the rest of the tasks to the pending list */ 558 pdmacFileAioMgrEpAddTaskList(pEndpoint, pTaskHead); 559 560 561 if (RT_UNLIKELY(!cMaxRequests && !pEndpoint->pFlushReq)) 562 { 563 /* 564 * The I/O manager has no room left for more requests 565 * but there are still requests to process. 566 * Create a new I/O manager and let it handle some endpoints. 567 */ 568 pdmacFileAioMgrNormalBalanceLoad(pAioMgr); 569 } 570 } 571 572 /* Insufficient resources are not fatal. */ 573 if (rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES) 574 rc = VINF_SUCCESS; 500 575 501 576 return rc; … … 536 611 } 537 612 538 if (!pEndpoint->pFlushReq )613 if (!pEndpoint->pFlushReq && !pEndpoint->AioMgr.pReqsPendingHead) 539 614 { 540 615 /* Now the request queue. */ … … 764 839 /* Put the entry on the free array */ 765 840 pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = apReqs[i]; 766 pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) % pAioMgr->cReqEntries;841 pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) % pAioMgr->cReqEntries; 767 842 768 843 pAioMgr->cRequestsActive--; -
trunk/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp
r20429 r23404 55 55 */ 56 56 #define NR_TASKS 80 57 #define BUFFER_SIZE 4096 /* 4K */57 #define BUFFER_SIZE (64*_1K) 58 58 59 59 /* Buffers to store data in .*/
Note:
See TracChangeset
for help on using the changeset viewer.