Changeset 78673 in vbox for trunk/src/VBox
- Timestamp:
- May 22, 2019 5:43:36 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp
r78535 r78673 325 325 kCmdOpt_MMap, 326 326 kCmdOpt_NoMMap, 327 kCmdOpt_MMapCoherency, 328 kCmdOpt_NoMMapCoherency, 329 kCmdOpt_MMapPlacement, 327 330 kCmdOpt_IgnoreNoCache, 328 331 kCmdOpt_NoIgnoreNoCache, … … 344 347 kCmdOpt_ManyTreeDepth, 345 348 349 kCmdOpt_MaxBufferSize, 350 346 351 kCmdOpt_End 347 352 }; … … 369 374 { "--subdirs-per-dir", kCmdOpt_ManyTreeSubdirsPerDir, RTGETOPT_REQ_UINT32 }, 370 375 { "--tree-depth", kCmdOpt_ManyTreeDepth, RTGETOPT_REQ_UINT32 }, 376 { "--max-buffer-size", kCmdOpt_MaxBufferSize, RTGETOPT_REQ_UINT32 }, 377 { "--mmap-placement", kCmdOpt_MMapPlacement, RTGETOPT_REQ_STRING }, 371 378 372 379 { "--open", kCmdOpt_Open, RTGETOPT_REQ_NOTHING }, … … 426 433 { "--mmap", kCmdOpt_MMap, RTGETOPT_REQ_NOTHING }, 427 434 { "--no-mmap", kCmdOpt_NoMMap, RTGETOPT_REQ_NOTHING }, 435 { "--mmap-coherency", kCmdOpt_MMapCoherency, RTGETOPT_REQ_NOTHING }, 436 { "--no-mmap-coherency", kCmdOpt_NoMMapCoherency, RTGETOPT_REQ_NOTHING }, 428 437 { "--ignore-no-cache", kCmdOpt_IgnoreNoCache, RTGETOPT_REQ_NOTHING }, 429 438 { "--no-ignore-no-cache", kCmdOpt_NoIgnoreNoCache, RTGETOPT_REQ_NOTHING }, … … 460 469 /** Verbosity level. */ 461 470 static uint32_t g_uVerbosity = 0; 471 /** Max buffer size, UINT32_MAX for unlimited. 472 * This is for making sure we don't run into the MDL limit on windows, which 473 * a bit less than 64 MiB. */ 474 #if defined(RT_OS_WINDOWS) 475 static uint32_t g_cbMaxBuffer = _32M; 476 #else 477 static uint32_t g_cbMaxBuffer = UINT32_MAX; 478 #endif 479 /** When to place the mmap test. */ 480 static int g_iMMapPlacement = 0; 462 481 463 482 /** @name Selected subtest … … 495 514 static bool g_fFSync = true; 496 515 static bool g_fMMap = true; 516 static bool g_fMMapCoherency = true; 497 517 static bool g_fCopy = true; 498 518 static bool g_fRemote = true; … … 1306 1326 * Allocate a suitable buffer. 1307 1327 */ 1308 size_t cbBuf = cbToWrite >= _2M ? _2M : RT_ALIGN_Z((size_t)cbToWrite, 512); 1309 uint8_t *pbBuf = (uint8_t *)RTMemTmpAlloc(cbBuf); 1328 size_t cbMaxBuf = RT_MIN(_2M, g_cbMaxBuffer); 1329 size_t cbBuf = cbToWrite >= cbMaxBuf ? cbMaxBuf : RT_ALIGN_Z((size_t)cbToWrite, 512); 1330 uint8_t *pbBuf = (uint8_t *)RTMemTmpAlloc(cbBuf); 1310 1331 if (!pbBuf) 1311 1332 { … … 2201 2222 void fsPerfNtQueryInfoFileWorker(HANDLE hNtFile1, uint32_t fType) 2202 2223 { 2224 char const chType = fType == RTFS_TYPE_DIRECTORY ? 'd' : 'r'; 2225 2203 2226 /** @todo may run out of buffer for really long paths? */ 2204 2227 union … … 2363 2386 { 2364 2387 if (rcNt != STATUS_INVALID_INFO_CLASS) 2365 RTTestIFailed("%s/%#x : %#x, expected STATUS_INVALID_INFO_CLASS", pszClass, cbBuf, rcNt);2388 RTTestIFailed("%s/%#x/%c: %#x, expected STATUS_INVALID_INFO_CLASS", pszClass, cbBuf, chType, rcNt); 2366 2389 } 2367 2390 else if ( rcNt != STATUS_INVALID_INFO_CLASS … … 2388 2411 || ( fType == RTFS_TYPE_DIRECTORY 2389 2412 && (enmClass == FileSfioReserveInformation || enmClass == FileStatLxInformation))) 2413 && !(rcNt == STATUS_INVALID_DEVICE_REQUEST && fType == RTFS_TYPE_FILE) 2390 2414 ) 2391 RTTestIFailed("%s/%#x : %#x", pszClass, cbBuf, rcNt);2415 RTTestIFailed("%s/%#x/%c: %#x", pszClass, cbBuf, chType, rcNt); 2392 2416 if ( (Ios.Status != VirginIos.Status || Ios.Information != VirginIos.Information) 2393 2417 && !( fType == RTFS_TYPE_DIRECTORY /* NTFS/W10-17763 */ 2394 2418 && Ios.Status == rcNt && Ios.Information == 0) ) 2395 RTTestIFailed("%s/%#x: I/O status block was modified: %#x %#zx", pszClass, cbBuf, Ios.Status, Ios.Information); 2419 RTTestIFailed("%s/%#x/%c: I/O status block was modified: %#x %#zx", 2420 pszClass, cbBuf, chType, Ios.Status, Ios.Information); 2396 2421 if (!ASMMemIsAllU8(&uBuf, sizeof(uBuf), 0xff)) 2397 RTTestIFailed("%s/%#x : Buffer was touched in failure case!", pszClass, cbBuf);2422 RTTestIFailed("%s/%#x/%c: Buffer was touched in failure case!", pszClass, cbBuf, chType); 2398 2423 } 2399 2424 } … … 3440 3465 3441 3466 3467 int fsPerfIoPrepFileWorker(RTFILE hFile1, uint64_t cbFile, uint8_t *pbBuf, size_t cbBuf) 3468 { 3469 /* 3470 * Fill the file with 0xf6 and insert offset markers with 1KB intervals. 3471 */ 3472 RTTESTI_CHECK_RC_RET(RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS, rcCheck); 3473 memset(pbBuf, 0xf6, cbBuf); 3474 uint64_t cbLeft = cbFile; 3475 uint64_t off = 0; 3476 while (cbLeft > 0) 3477 { 3478 Assert(!(off & (_1K - 1))); 3479 Assert(!(cbBuf & (_1K - 1))); 3480 for (size_t offBuf = 0; offBuf < cbBuf; offBuf += _1K, off += _1K) 3481 *(uint64_t *)&pbBuf[offBuf] = off; 3482 3483 size_t cbToWrite = cbBuf; 3484 if (cbToWrite > cbLeft) 3485 cbToWrite = (size_t)cbLeft; 3486 3487 RTTESTI_CHECK_RC_RET(RTFileWrite(hFile1, pbBuf, cbToWrite, NULL), VINF_SUCCESS, rcCheck); 3488 cbLeft -= cbToWrite; 3489 } 3490 return VINF_SUCCESS; 3491 } 3492 3442 3493 int fsPerfIoPrepFile(RTFILE hFile1, uint64_t cbFile, uint8_t **ppbFree) 3443 3494 { … … 3453 3504 */ 3454 3505 RTTESTI_CHECK_RC_RET(RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS, rcCheck); 3455 size_t cbBuf = _1M;3506 size_t cbBuf = RT_MIN(_1M, g_cbMaxBuffer); 3456 3507 uint8_t *pbBuf = *ppbFree = (uint8_t *)RTMemAlloc(cbBuf); 3457 3508 RTTESTI_CHECK_RET(pbBuf != NULL, VERR_NO_MEMORY); … … 3473 3524 * Fill the file with 0xf6 and insert offset markers with 1KB intervals. 3474 3525 */ 3475 RTTESTI_CHECK_RC_RET(RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS, rcCheck); 3476 memset(pbBuf, 0xf6, cbBuf); 3477 cbLeft = cbFile; 3478 uint64_t off = 0; 3479 while (cbLeft > 0) 3480 { 3481 Assert(!(off & (_1K - 1))); 3482 Assert(!(cbBuf & (_1K - 1))); 3483 for (size_t offBuf = 0; offBuf < cbBuf; offBuf += _1K, off += _1K) 3484 *(uint64_t *)&pbBuf[offBuf] = off; 3485 3486 size_t cbToWrite = cbBuf; 3487 if (cbToWrite > cbLeft) 3488 cbToWrite = (size_t)cbLeft; 3489 3490 RTTESTI_CHECK_RC_RET(RTFileWrite(hFile1, pbBuf, cbToWrite, NULL), VINF_SUCCESS, rcCheck); 3491 3492 cbLeft -= cbToWrite; 3493 } 3494 3495 return VINF_SUCCESS; 3496 } 3497 3526 return fsPerfIoPrepFileWorker(hFile1, cbFile, pbBuf, cbBuf); 3527 } 3528 3529 /** 3530 * Used in relation to the mmap test when in non-default position. 3531 */ 3532 int fsPerfReinitFile(RTFILE hFile1, uint64_t cbFile) 3533 { 3534 size_t cbBuf = RT_MIN(_1M, g_cbMaxBuffer); 3535 uint8_t *pbBuf = (uint8_t *)RTMemAlloc(cbBuf); 3536 RTTESTI_CHECK_RET(pbBuf != NULL, VERR_NO_MEMORY); 3537 3538 int rc = fsPerfIoPrepFileWorker(hFile1, cbFile, pbBuf, cbBuf); 3539 3540 RTMemFree(pbBuf); 3541 return rc; 3542 } 3498 3543 3499 3544 /** … … 3849 3894 */ 3850 3895 FSPERFSENDFILEARGS Args; 3851 Args.cbBuf = RT_MIN( cbFileMax, _16M);3896 Args.cbBuf = RT_MIN(RT_MIN(cbFileMax, _16M), g_cbMaxBuffer); 3852 3897 Args.pbBuf = (uint8_t *)RTMemAlloc(Args.cbBuf); 3853 3898 while (!Args.pbBuf) … … 4106 4151 */ 4107 4152 FSPERFSPLICEARGS Args; 4108 Args.cbBuf = RT_MIN( cbFileMax, _16M);4153 Args.cbBuf = RT_MIN(RT_MIN(cbFileMax, _16M), g_cbMaxBuffer); 4109 4154 Args.pbBuf = (uint8_t *)RTMemAlloc(Args.cbBuf); 4110 4155 while (!Args.pbBuf) … … 4330 4375 */ 4331 4376 FSPERFSPLICEARGS Args; 4332 Args.cbBuf = RT_MIN( cbFileMax, _16M);4377 Args.cbBuf = RT_MIN(RT_MIN(cbFileMax, _16M), g_cbMaxBuffer); 4333 4378 Args.pbBuf = (uint8_t *)RTMemAlloc(Args.cbBuf); 4334 4379 while (!Args.pbBuf) … … 4523 4568 * Allocate a big buffer we can play around with. Min size is 1MB. 4524 4569 */ 4525 size_t cbBuf = cbFile < _64M ? (size_t)cbFile : _64M; 4526 uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(cbBuf); 4570 size_t cbMaxBuf = RT_MIN(_64M, g_cbMaxBuffer); 4571 size_t cbBuf = cbFile < cbMaxBuf ? (size_t)cbFile : cbMaxBuf; 4572 uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(cbBuf); 4527 4573 while (!pbBuf) 4528 4574 { … … 5014 5060 * Allocate a big buffer we can play around with. Min size is 1MB. 5015 5061 */ 5016 size_t cbBuf = cbFile < _64M ? (size_t)cbFile : _64M; 5017 uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(cbBuf); 5062 size_t cbMaxBuf = RT_MIN(_64M, g_cbMaxBuffer); 5063 size_t cbBuf = cbFile < cbMaxBuf ? (size_t)cbFile : cbMaxBuf; 5064 uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(cbBuf); 5018 5065 while (!pbBuf) 5019 5066 { … … 5412 5459 corruption of shared data during content checking of the RW iterations. */ 5413 5460 fsPerfFillWriteBuf(0, pbMapping, _2M, 0xf7); 5414 if (enmState == kMMap_ReadWrite )5461 if (enmState == kMMap_ReadWrite && g_fMMapCoherency) 5415 5462 { 5416 5463 /* For RW we can try read back from the file handle and check if we get … … 5427 5474 RTTESTI_CHECK(msync(pbMapping, _2M, MS_SYNC) == 0); 5428 5475 # endif 5429 5430 /* 5431 * Time modifying and flushing a few different number of pages. 5432 */ 5476 } 5477 5478 /* 5479 * Time modifying and flushing a few different number of pages. 5480 */ 5481 if (enmState == kMMap_ReadWrite) 5482 { 5433 5483 static size_t const s_acbFlush[] = { PAGE_SIZE, PAGE_SIZE * 2, PAGE_SIZE * 3, PAGE_SIZE * 8, PAGE_SIZE * 16, _2M }; 5434 5484 for (unsigned iFlushSize = 0 ; iFlushSize < RT_ELEMENTS(s_acbFlush); iFlushSize++) … … 5451 5501 if (!g_fIgnoreNoCache || hFileNoCache != NIL_RTFILE) 5452 5502 { 5453 size_t cbBuf = _2M;5503 size_t cbBuf = RT_MIN(_2M, g_cbMaxBuffer); 5454 5504 uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(cbBuf); 5455 5505 if (!pbBuf) … … 5505 5555 * when not performed thru an no-cache handle. 5506 5556 */ 5507 if (enmState == kMMap_ReadOnly || enmState == kMMap_ReadWrite) 5508 { 5509 size_t cbBuf = RT_MIN(_2M, cbMapping / 2); 5557 if ( (enmState == kMMap_ReadOnly || enmState == kMMap_ReadWrite) 5558 && g_fMMapCoherency) 5559 { 5560 size_t cbBuf = RT_MIN(RT_MIN(_2M, cbMapping / 2), g_cbMaxBuffer); 5510 5561 uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(cbBuf); 5511 5562 if (!pbBuf) … … 5737 5788 fsPerfIoSeek(hFile1, cbFile); 5738 5789 5790 if (g_fMMap && g_iMMapPlacement < 0) 5791 { 5792 fsPerfMMap(hFile1, hFileNoCache, cbFile); 5793 fsPerfReinitFile(hFile1, cbFile); 5794 } 5795 5739 5796 if (g_fReadTests) 5740 5797 fsPerfRead(hFile1, hFileNoCache, cbFile); … … 5750 5807 fsPerfSpliceToPipe(hFile1, cbFile); 5751 5808 #endif 5752 if (g_fMMap )5809 if (g_fMMap && g_iMMapPlacement == 0) 5753 5810 fsPerfMMap(hFile1, hFileNoCache, cbFile); 5754 5811 … … 5765 5822 if (g_fFSync) 5766 5823 fsPerfFSync(hFile1, cbFile); 5824 5825 if (g_fMMap && g_iMMapPlacement > 0) 5826 { 5827 fsPerfReinitFile(hFile1, cbFile); 5828 fsPerfMMap(hFile1, hFileNoCache, cbFile); 5829 } 5767 5830 } 5768 5831 … … 6232 6295 case kCmdOpt_ManyTreeSubdirsPerDir: pszHelp = "Count of subdirs per directory in test tree. default: 16"; break; 6233 6296 case kCmdOpt_ManyTreeDepth: pszHelp = "Depth of test tree (not counting root). default: 1"; break; 6297 #if defined(RT_OS_WINDOWS) 6298 case kCmdOpt_MaxBufferSize: pszHelp = "For avoiding the MDL limit on windows. default: 32MiB"; break; 6299 #else 6300 case kCmdOpt_MaxBufferSize: pszHelp = "For avoiding the MDL limit on windows. default: 0"; break; 6301 #endif 6302 case kCmdOpt_MMapPlacement: pszHelp = "When to do mmap testing (caching effects): first, between (default), last "; break; 6234 6303 case kCmdOpt_IgnoreNoCache: pszHelp = "Ignore error wrt no-cache handle. default: --no-ignore-no-cache"; break; 6235 6304 case kCmdOpt_NoIgnoreNoCache: pszHelp = "Do not ignore error wrt no-cache handle. default: --no-ignore-no-cache"; break; … … 6381 6450 g_fFSync = true; 6382 6451 g_fMMap = true; 6452 g_fMMapCoherency = true; 6383 6453 g_fCopy = true; 6384 6454 g_fRemote = true; … … 6418 6488 g_fFSync = false; 6419 6489 g_fMMap = false; 6490 g_fMMapCoherency = false; 6420 6491 g_fCopy = false; 6421 6492 g_fRemote = false; … … 6456 6527 CASE_OPT(FSync); 6457 6528 CASE_OPT(MMap); 6529 CASE_OPT(MMapCoherency); 6458 6530 CASE_OPT(IgnoreNoCache); 6459 6531 CASE_OPT(Copy); … … 6502 6574 RTTestFailed(g_hTest, "Out of range --tree-depth value: %u (%#x)\n", ValueUnion.u32, ValueUnion.u32); 6503 6575 return RTTestSummaryAndDestroy(g_hTest); 6576 6577 case kCmdOpt_MaxBufferSize: 6578 if (ValueUnion.u32 >= 4096) 6579 g_cbMaxBuffer = ValueUnion.u32; 6580 else if (ValueUnion.u32 == 0) 6581 g_cbMaxBuffer = UINT32_MAX; 6582 else 6583 { 6584 RTTestFailed(g_hTest, "max buffer size is less than 4KB: %#x\n", ValueUnion.u32); 6585 return RTTestSummaryAndDestroy(g_hTest); 6586 } 6587 break; 6504 6588 6505 6589 case kCmdOpt_IoFileSize: … … 6534 6618 } 6535 6619 return RTTestSummaryAndDestroy(g_hTest); 6620 6621 case kCmdOpt_MMapPlacement: 6622 if (strcmp(ValueUnion.psz, "first") == 0) 6623 g_iMMapPlacement = -1; 6624 else if ( strcmp(ValueUnion.psz, "between") == 0 6625 || strcmp(ValueUnion.psz, "default") == 0) 6626 g_iMMapPlacement = 0; 6627 else if (strcmp(ValueUnion.psz, "last") == 0) 6628 g_iMMapPlacement = 1; 6629 else 6630 { 6631 RTTestFailed(g_hTest, 6632 "Invalid --mmap-placment directive '%s'! Expected 'first', 'last', 'between' or 'default'.\n", 6633 ValueUnion.psz); 6634 return RTTestSummaryAndDestroy(g_hTest); 6635 } 6636 break; 6536 6637 6537 6638 case 'q':
Note:
See TracChangeset
for help on using the changeset viewer.