mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-12 17:33:00 +08:00
fix: update completion data after makeResident
Completion data can't be updated when makeResident fails Resources could have updated state but paging fence remains the same. Wait on paging fence during freeing these resources might result in hang. Signed-off-by: Szymon Morek <szymon.morek@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
c934877790
commit
13ec7ad32a
@@ -61,23 +61,25 @@ void WddmResidencyController::resetMonitoredFenceParams(D3DKMT_HANDLE &handle, u
|
||||
* @return returns true if all allocations either succeeded or are pending to be resident
|
||||
*/
|
||||
bool WddmResidencyController::makeResidentResidencyAllocations(ResidencyContainer &allocationsForResidency, bool &requiresBlockingResidencyHandling) {
|
||||
const size_t residencyCount = allocationsForResidency.size();
|
||||
constexpr uint32_t stackAllocations = 64;
|
||||
constexpr uint32_t stackHandlesCount = NEO::maxFragmentsCount * EngineLimits::maxHandleCount * stackAllocations;
|
||||
StackVec<D3DKMT_HANDLE, stackHandlesCount> handlesForResidency;
|
||||
uint32_t totalHandlesCount = 0;
|
||||
size_t totalSize = 0;
|
||||
const auto currentFence = this->getMonitoredFence().currentFenceValue;
|
||||
|
||||
requiresBlockingResidencyHandling = false;
|
||||
if (debugManager.flags.WaitForPagingFenceInController.get() != -1) {
|
||||
requiresBlockingResidencyHandling = !debugManager.flags.WaitForPagingFenceInController.get();
|
||||
}
|
||||
|
||||
auto lock = this->acquireLock();
|
||||
const auto currentFence = this->getMonitoredFence().currentFenceValue;
|
||||
filteredResidencyContainer.clear();
|
||||
filteredResidencyContainer.reserve(residencyCount);
|
||||
|
||||
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "currentFenceValue =", this->getMonitoredFence().currentFenceValue);
|
||||
auto iter = allocationsForResidency.begin();
|
||||
while (iter != allocationsForResidency.end()) {
|
||||
WddmAllocation *allocation = static_cast<WddmAllocation *>(*iter);
|
||||
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "currentFenceValue =", currentFence);
|
||||
for (uint32_t i = 0; i < residencyCount; i++) {
|
||||
WddmAllocation *allocation = static_cast<WddmAllocation *>(allocationsForResidency[i]);
|
||||
ResidencyData &residencyData = allocation->getResidencyData();
|
||||
static constexpr int maxFragments = 3;
|
||||
bool fragmentResidency[maxFragments] = {false, false, false};
|
||||
@@ -89,15 +91,11 @@ bool WddmResidencyController::makeResidentResidencyAllocations(ResidencyContaine
|
||||
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "allocation, gpu address = ", std::hex, allocation->getGpuAddress(), residencyData.resident[osContextId] ? "resident" : "not resident");
|
||||
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "allocation, gpu address = ", std::hex, allocation->getGpuAddress(), "fence value to reach for eviction = ", currentFence);
|
||||
|
||||
allocation->getResidencyData().updateCompletionData(currentFence, this->osContextId);
|
||||
bool isAlreadyResident = true;
|
||||
if (fragmentCount > 0) {
|
||||
for (uint32_t allocationId = 0; allocationId < fragmentCount; allocationId++) {
|
||||
auto residencyData = allocation->fragmentsStorage.fragmentStorageData[allocationId].residency;
|
||||
residencyData->updateCompletionData(currentFence, this->osContextId);
|
||||
if (!fragmentResidency[allocationId]) {
|
||||
handlesForResidency.push_back(static_cast<OsHandleWin *>(allocation->fragmentsStorage.fragmentStorageData[allocationId].osHandleStorage)->handle);
|
||||
totalHandlesCount++;
|
||||
requiresBlockingResidencyHandling |= (allocation->getAllocationType() != AllocationType::buffer && allocation->getAllocationType() != AllocationType::bufferHostMemory);
|
||||
isAlreadyResident = false;
|
||||
}
|
||||
@@ -105,23 +103,20 @@ bool WddmResidencyController::makeResidentResidencyAllocations(ResidencyContaine
|
||||
} else if (!residencyData.resident[osContextId]) {
|
||||
for (uint32_t gmmId = 0; gmmId < allocation->getNumGmms(); ++gmmId) {
|
||||
handlesForResidency.push_back(allocation->getHandle(gmmId));
|
||||
totalHandlesCount++;
|
||||
requiresBlockingResidencyHandling |= (allocation->getAllocationType() != AllocationType::buffer && allocation->getAllocationType() != AllocationType::bufferHostMemory);
|
||||
isAlreadyResident = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isAlreadyResident) {
|
||||
iter = allocationsForResidency.erase(iter);
|
||||
} else {
|
||||
iter++;
|
||||
if (!isAlreadyResident) {
|
||||
filteredResidencyContainer.push_back(allocation);
|
||||
}
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
if (totalHandlesCount) {
|
||||
if (!handlesForResidency.empty()) {
|
||||
uint64_t bytesToTrim = 0;
|
||||
while ((result = wddm.makeResident(&handlesForResidency[0], totalHandlesCount, false, &bytesToTrim, totalSize)) == false) {
|
||||
while ((result = wddm.makeResident(&handlesForResidency[0], static_cast<uint32_t>(handlesForResidency.size()), false, &bytesToTrim, totalSize)) == false) {
|
||||
this->setMemoryBudgetExhausted();
|
||||
const bool trimmingDone = this->trimResidencyToBudget(bytesToTrim, lock);
|
||||
if (!trimmingDone) {
|
||||
@@ -131,7 +126,7 @@ bool WddmResidencyController::makeResidentResidencyAllocations(ResidencyContaine
|
||||
}
|
||||
DEBUG_BREAK_IF(evictionStatus != MemoryOperationsStatus::memoryNotFound);
|
||||
do {
|
||||
result = wddm.makeResident(&handlesForResidency[0], totalHandlesCount, true, &bytesToTrim, totalSize);
|
||||
result = wddm.makeResident(&handlesForResidency[0], static_cast<uint32_t>(handlesForResidency.size()), true, &bytesToTrim, totalSize);
|
||||
} while (debugManager.flags.WaitForMemoryRelease.get() && result == false);
|
||||
break;
|
||||
}
|
||||
@@ -139,17 +134,19 @@ bool WddmResidencyController::makeResidentResidencyAllocations(ResidencyContaine
|
||||
}
|
||||
|
||||
if (result == true) {
|
||||
iter = allocationsForResidency.begin();
|
||||
while (iter != allocationsForResidency.end()) {
|
||||
WddmAllocation *allocation = static_cast<WddmAllocation *>(*iter);
|
||||
for (uint32_t i = 0; i < residencyCount; i++) {
|
||||
WddmAllocation *allocation = static_cast<WddmAllocation *>(allocationsForResidency[i]);
|
||||
allocation->getResidencyData().resident[osContextId] = true;
|
||||
allocation->getResidencyData().updateCompletionData(currentFence, this->osContextId);
|
||||
for (uint32_t allocationId = 0; allocationId < allocation->fragmentsStorage.fragmentCount; allocationId++) {
|
||||
auto residencyData = allocation->fragmentsStorage.fragmentStorageData[allocationId].residency;
|
||||
residencyData->resident[osContextId] = true;
|
||||
residencyData->updateCompletionData(currentFence, this->osContextId);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
// Remove already resident allocations from the container
|
||||
allocationsForResidency = std::move(filteredResidencyContainer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -76,5 +76,6 @@ class WddmResidencyController {
|
||||
bool memoryBudgetExhausted = false;
|
||||
|
||||
CommandStreamReceiver *csr;
|
||||
ResidencyContainer filteredResidencyContainer;
|
||||
};
|
||||
} // namespace NEO
|
||||
|
||||
@@ -894,6 +894,8 @@ TEST_F(WddmResidencyControllerWithMockWddmTest, givenMakeResidentFailsWhenCallin
|
||||
|
||||
TEST_F(WddmResidencyControllerWithMockWddmTest, givenMakeResidentFailsWhenCallingMakeResidentResidencyAllocationsThenCallItAgainWithCantTrimFurtherSetToTrue) {
|
||||
MockWddmAllocation allocation1(gmmHelper);
|
||||
allocation1.getResidencyData().updateCompletionData(0, osContextId);
|
||||
residencyController->getMonitoredFence().currentFenceValue = 10;
|
||||
|
||||
wddm->makeResidentNumberOfBytesToTrim = 4 * 4096;
|
||||
wddm->makeResidentStatus = false;
|
||||
@@ -905,6 +907,7 @@ TEST_F(WddmResidencyControllerWithMockWddmTest, givenMakeResidentFailsWhenCallin
|
||||
EXPECT_FALSE(result);
|
||||
EXPECT_NE(wddm->makeResidentParamsPassed[0].cantTrimFurther, wddm->makeResidentParamsPassed[1].cantTrimFurther);
|
||||
EXPECT_EQ(2u, wddm->makeResidentResult.called);
|
||||
EXPECT_EQ(0u, allocation1.getResidencyData().getFenceValueForContextId(osContextId));
|
||||
}
|
||||
|
||||
TEST_F(WddmResidencyControllerWithMockWddmTest, givenAllocationPackPassedWhenCallingMakeResidentResidencyAllocationsThenItIsUsed) {
|
||||
|
||||
Reference in New Issue
Block a user