Changeset 92202 in vbox
- Timestamp:
- Nov 3, 2021 10:46:49 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/GMMR0.cpp
r91540 r92202 429 429 /** The number of mappings. (Chunk mtx.) */ 430 430 uint16_t cMappingsX; 431 /** The mapping lock this chunk is using using. UINT 16_MAX if nobody is432 * mappingor freeing anything. (Giant mtx.) */431 /** The mapping lock this chunk is using using. UINT8_MAX if nobody is mapping 432 * or freeing anything. (Giant mtx.) */ 433 433 uint8_t volatile iChunkMtx; 434 434 /** GMM_CHUNK_FLAGS_XXX. (Giant mtx.) */ … … 451 451 /** The number of shared pages. (Giant mtx.) */ 452 452 uint16_t cShared; 453 /** The UID this chunk is associated with. */ 454 RTUID uidOwner; 455 uint32_t u32Padding; 453 456 /** The pages. (Giant mtx.) */ 454 457 GMMPAGE aPages[GMM_CHUNK_SIZE >> PAGE_SHIFT]; … … 2219 2222 * @param hGVM The affinity of the chunk. NIL_GVM_HANDLE for no 2220 2223 * affinity. 2224 * @param pSession Same as @a hGVM. 2221 2225 * @param fChunkFlags The chunk flags, GMM_CHUNK_FLAGS_XXX. 2222 2226 * @param ppChunk Chunk address (out). Optional. … … 2226 2230 * the success path. On failure, no locks will be held. 2227 2231 */ 2228 static int gmmR0RegisterChunk(PGMM pGMM, PGMMCHUNKFREESET pSet, RTR0MEMOBJ hMemObj, uint16_t hGVM, uint16_t fChunkFlags,2229 PGMMCHUNK *ppChunk)2232 static int gmmR0RegisterChunk(PGMM pGMM, PGMMCHUNKFREESET pSet, RTR0MEMOBJ hMemObj, uint16_t hGVM, PSUPDRVSESSION pSession, 2233 uint16_t fChunkFlags, PGMMCHUNK *ppChunk) 2230 2234 { 2231 2235 Assert(pGMM->hMtxOwner != RTThreadNativeSelf()); … … 2278 2282 pChunk->iChunkMtx = UINT8_MAX; 2279 2283 pChunk->fFlags = fChunkFlags; 2284 pChunk->uidOwner = pSession ? SUPR0GetSessionUid(pSession) : NIL_RTUID; 2280 2285 for (unsigned iPage = 0; iPage < RT_ELEMENTS(pChunk->aPages) - 1; iPage++) 2281 2286 { … … 2372 2377 * do as much work as possible without holding the giant lock. */ 2373 2378 PGMMCHUNK pChunk; 2374 rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, 0 /*fChunkFlags*/, &pChunk);2379 rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, pGVM->pSession, 0 /*fChunkFlags*/, &pChunk); 2375 2380 if (RT_SUCCESS(rc)) 2376 2381 { … … 2396 2401 * @param pSet The set to pick from. 2397 2402 * @param pGVM Pointer to the global VM structure. 2403 * @param uidSelf The UID of the caller. 2398 2404 * @param iPage The current page descriptor table index. 2399 2405 * @param cPages The total number of pages to allocate. 2400 2406 * @param paPages The page descriptor table (input + ouput). 2401 2407 */ 2402 static uint32_t gmmR0AllocatePagesIndiscriminately(PGMMCHUNKFREESET pSet, PGVM pGVM, 2408 static uint32_t gmmR0AllocatePagesIndiscriminately(PGMMCHUNKFREESET pSet, PGVM pGVM, RTUID uidSelf, 2403 2409 uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages) 2404 2410 { … … 2410 2416 { 2411 2417 PGMMCHUNK pNext = pChunk->pFreeNext; 2412 2413 iPage = gmmR0AllocatePagesFromChunk(pChunk, pGVM->hSelf, iPage, cPages, paPages); 2414 if (iPage >= cPages) 2415 return iPage; 2418 if ( pChunk->uidOwner == uidSelf 2419 || ( pChunk->cMappingsX == 0 2420 && pChunk->cFree == (GMM_CHUNK_SIZE >> PAGE_SHIFT))) 2421 { 2422 iPage = gmmR0AllocatePagesFromChunk(pChunk, pGVM->hSelf, iPage, cPages, paPages); 2423 if (iPage >= cPages) 2424 return iPage; 2425 } 2416 2426 2417 2427 pChunk = pNext; … … 2428 2438 * @param pSet The set to pick from. 2429 2439 * @param pGVM Pointer to the global VM structure. 2440 * @param uidSelf The UID of the caller. 2430 2441 * @param iPage The current page descriptor table index. 2431 2442 * @param cPages The total number of pages to allocate. 2432 2443 * @param paPages The page descriptor table (input + ouput). 2433 2444 */ 2434 static uint32_t gmmR0AllocatePagesFromEmptyChunksOnSameNode(PGMMCHUNKFREESET pSet, PGVM pGVM, 2445 static uint32_t gmmR0AllocatePagesFromEmptyChunksOnSameNode(PGMMCHUNKFREESET pSet, PGVM pGVM, RTUID uidSelf, 2435 2446 uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages) 2436 2447 { … … 2443 2454 PGMMCHUNK pNext = pChunk->pFreeNext; 2444 2455 2445 if (pChunk->idNumaNode == idNumaNode) 2456 if ( pChunk->idNumaNode == idNumaNode 2457 && ( pChunk->uidOwner == uidSelf 2458 || pChunk->cMappingsX == 0)) 2446 2459 { 2447 pChunk->hGVM = pGVM->hSelf; 2460 pChunk->hGVM = pGVM->hSelf; 2461 pChunk->uidOwner = uidSelf; 2448 2462 iPage = gmmR0AllocatePagesFromChunk(pChunk, pGVM->hSelf, iPage, cPages, paPages); 2449 2463 if (iPage >= cPages) … … 2467 2481 * @param pSet The set to pick from. 2468 2482 * @param pGVM Pointer to the global VM structure. 2483 * @param uidSelf The UID of the caller. 2469 2484 * @param iPage The current page descriptor table index. 2470 2485 * @param cPages The total number of pages to allocate. 2471 2486 * @param paPages The page descriptor table (input + ouput). 2472 2487 */ 2473 static uint32_t gmmR0AllocatePagesFromSameNode(PGMMCHUNKFREESET pSet, PGVM pGVM, 2488 static uint32_t gmmR0AllocatePagesFromSameNode(PGMMCHUNKFREESET pSet, PGVM pGVM, RTUID const uidSelf, 2474 2489 uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages) 2475 2490 { … … 2484 2499 PGMMCHUNK pNext = pChunk->pFreeNext; 2485 2500 2486 if (pChunk->idNumaNode == idNumaNode) 2501 if ( pChunk->idNumaNode == idNumaNode 2502 && pChunk->uidOwner == uidSelf) 2487 2503 { 2488 2504 iPage = gmmR0AllocatePagesFromChunk(pChunk, pGVM->hSelf, iPage, cPages, paPages); … … 2765 2781 else 2766 2782 { 2783 RTUID const uidSelf = SUPR0GetSessionUid(pGVM->pSession); 2784 2767 2785 /* Pick the most optimal pages first. */ 2768 2786 iPage = gmmR0AllocatePagesAssociatedWithVM(pGMM, pGVM, &pGMM->PrivateX, iPage, cPages, paPages); … … 2774 2792 if (gmmR0ShouldAllocatePagesInOtherChunksBecauseOfLimits(pGVM)) 2775 2793 { 2776 iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);2794 iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, uidSelf, iPage, cPages, paPages); 2777 2795 fTriedOnSameAlready = true; 2778 2796 } … … 2780 2798 /* Allocate memory from empty chunks. */ 2781 2799 if (iPage < cPages) 2782 iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);2800 iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(&pGMM->PrivateX, pGVM, uidSelf, iPage, cPages, paPages); 2783 2801 2784 2802 /* Grab empty shared chunks. */ 2785 2803 if (iPage < cPages) 2786 iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(&pGMM->Shared, pGVM, iPage, cPages, paPages);2804 iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(&pGMM->Shared, pGVM, uidSelf, iPage, cPages, paPages); 2787 2805 2788 2806 /* If there is a lof of free pages spread around, try not waste … … 2791 2809 && gmmR0ShouldAllocatePagesInOtherChunksBecauseOfLotsFree(pGMM)) 2792 2810 { 2793 iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);2811 iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, uidSelf, iPage, cPages, paPages); 2794 2812 if (iPage < cPages) 2795 iPage = gmmR0AllocatePagesIndiscriminately(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);2813 iPage = gmmR0AllocatePagesIndiscriminately(&pGMM->PrivateX, pGVM, uidSelf, iPage, cPages, paPages); 2796 2814 } 2797 2815 … … 2805 2823 while (iPage < cPages && RT_SUCCESS(rc)); 2806 2824 2825 #if 0 /* We cannot mix chunks with different UIDs. */ 2807 2826 /* If the host is out of memory, take whatever we can get. */ 2808 2827 if ( (rc == VERR_NO_MEMORY || rc == VERR_NO_PHYS_MEMORY) … … 2815 2834 rc = VINF_SUCCESS; 2816 2835 } 2836 #endif 2817 2837 } 2818 2838 } … … 3245 3265 PGMMCHUNKFREESET pSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX; 3246 3266 PGMMCHUNK pChunk; 3247 rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, GMM_CHUNK_FLAGS_LARGE_PAGE, &pChunk);3267 rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, pGVM->pSession, GMM_CHUNK_FLAGS_LARGE_PAGE, &pChunk); 3248 3268 if (RT_SUCCESS(rc)) 3249 3269 { … … 4520 4540 if (RT_SUCCESS(rc)) 4521 4541 { 4522 rc = gmmR0RegisterChunk(pGMM, &pGVM->gmm.s.Private, hMemObj, pGVM->hSelf, GMM_CHUNK_FLAGS_SEEDED, NULL);4542 rc = gmmR0RegisterChunk(pGMM, &pGVM->gmm.s.Private, hMemObj, pGVM->hSelf, pGVM->pSession, GMM_CHUNK_FLAGS_SEEDED, NULL); 4523 4543 if (RT_SUCCESS(rc)) 4524 4544 gmmR0MutexRelease(pGMM);
Note:
See TracChangeset
for help on using the changeset viewer.