fix: pass ReadOnly flag only for page-misaligned input ptr

Related-To: NEO-12986
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2025-02-06 12:52:06 +00:00
committed by Compute-Runtime-Automation
parent 1f1e066f90
commit d25237c104
13 changed files with 244 additions and 25 deletions

View File

@@ -12,7 +12,10 @@ namespace NEO {
NTSTATUS Wddm::createNTHandle(const D3DKMT_HANDLE *resourceHandle, HANDLE *ntHandle) {
return getGdi()->shareObjects(1, resourceHandle, nullptr, SHARED_ALLOCATION_WRITE, ntHandle);
}
bool Wddm::getReadOnlyFlagValue(const void *alignedCpuPtr) const {
bool Wddm::getReadOnlyFlagValue(const void *cpuPtr) const {
return false;
}
bool Wddm::isReadOnlyFlagFallbackSupported() const {
return false;
}
} // namespace NEO

View File

@@ -17,7 +17,10 @@ NTSTATUS Wddm::createNTHandle(const D3DKMT_HANDLE *resourceHandle, HANDLE *ntHan
return getGdi()->shareObjects(1, resourceHandle, &objAttr, SHARED_ALLOCATION_WRITE, ntHandle);
}
bool Wddm::getReadOnlyFlagValue(const void *alignedCpuPtr) const {
return alignedCpuPtr != nullptr;
bool Wddm::getReadOnlyFlagValue(const void *cpuPtr) const {
return !isAligned<MemoryConstants::pageSize>(cpuPtr);
}
bool Wddm::isReadOnlyFlagFallbackSupported() const {
return true;
}
} // namespace NEO

View File

@@ -650,7 +650,11 @@ bool Wddm::freeGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size)
return status == STATUS_SUCCESS;
}
NTSTATUS Wddm::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, uint64_t *outSharedHandle) {
bool Wddm::isReadOnlyFlagFallbackAvailable(const D3DKMT_CREATEALLOCATION &createAllocation) const {
return isReadOnlyFlagFallbackSupported() && createAllocation.pAllocationInfo2->pSystemMem && !createAllocation.Flags.ReadOnly;
}
NTSTATUS Wddm::createAllocation(const void *cpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, uint64_t *outSharedHandle) {
NTSTATUS status = STATUS_UNSUCCESSFUL;
D3DDDI_ALLOCATIONINFO2 allocationInfo = {};
D3DKMT_CREATEALLOCATION createAllocation = {};
@@ -658,14 +662,14 @@ NTSTATUS Wddm::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKM
if (gmm == nullptr)
return false;
allocationInfo.pSystemMem = alignedCpuPtr;
allocationInfo.pSystemMem = gmm->gmmResourceInfo->getSystemMemPointer();
allocationInfo.pPrivateDriverData = gmm->gmmResourceInfo->peekHandle();
allocationInfo.PrivateDriverDataSize = static_cast<uint32_t>(gmm->gmmResourceInfo->peekHandleSize());
createAllocation.NumAllocations = 1;
createAllocation.Flags.CreateShared = outSharedHandle ? TRUE : FALSE;
createAllocation.Flags.NtSecuritySharing = outSharedHandle ? TRUE : FALSE;
createAllocation.Flags.CreateResource = outSharedHandle ? TRUE : FALSE;
createAllocation.Flags.ReadOnly = getReadOnlyFlagValue(alignedCpuPtr);
createAllocation.Flags.ReadOnly = getReadOnlyFlagValue(cpuPtr);
createAllocation.pAllocationInfo2 = &allocationInfo;
createAllocation.hDevice = device;
@@ -678,6 +682,10 @@ NTSTATUS Wddm::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKM
}
status = getGdi()->createAllocation2(&createAllocation);
if (status != STATUS_SUCCESS && isReadOnlyFlagFallbackAvailable(createAllocation)) {
createAllocation.Flags.ReadOnly = TRUE;
status = getGdi()->createAllocation2(&createAllocation);
}
if (status != STATUS_SUCCESS) {
DEBUG_BREAK_IF(true);
return status;
@@ -778,6 +786,10 @@ NTSTATUS Wddm::createAllocationsAndMapGpuVa(OsHandleStorage &osHandles) {
while (status == STATUS_UNSUCCESSFUL) {
status = getGdi()->createAllocation2(&createAllocation);
if (status != STATUS_SUCCESS && isReadOnlyFlagFallbackAvailable(createAllocation)) {
createAllocation.Flags.ReadOnly = TRUE;
status = getGdi()->createAllocation2(&createAllocation);
}
if (status != STATUS_SUCCESS) {
PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "%s status: %d", __FUNCTION__, status);

View File

@@ -73,7 +73,7 @@ class Wddm : public DriverModel {
MOCKABLE_VIRTUAL void applyAdditionalMapGPUVAFields(D3DDDI_MAPGPUVIRTUALADDRESS &mapGPUVA, Gmm *gmm, AllocationType type);
MOCKABLE_VIRTUAL uint64_t freeGmmGpuVirtualAddress(Gmm *gmm, D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size);
MOCKABLE_VIRTUAL bool freeGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size);
MOCKABLE_VIRTUAL NTSTATUS createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, uint64_t *outSharedHandle);
MOCKABLE_VIRTUAL NTSTATUS createAllocation(const void *cpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, uint64_t *outSharedHandle);
MOCKABLE_VIRTUAL bool createAllocation(const Gmm *gmm, D3DKMT_HANDLE &outHandle);
MOCKABLE_VIRTUAL NTSTATUS createAllocationsAndMapGpuVa(OsHandleStorage &osHandles);
MOCKABLE_VIRTUAL bool destroyAllocations(const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle);
@@ -257,7 +257,9 @@ class Wddm : public DriverModel {
void setNewResourceBoundToPageTable();
void setProcessPowerThrottling();
void setThreadPriority();
bool getReadOnlyFlagValue(const void *alignedCpuPtr) const;
bool getReadOnlyFlagValue(const void *cpuPtr) const;
bool isReadOnlyFlagFallbackSupported() const;
bool isReadOnlyFlagFallbackAvailable(const D3DKMT_CREATEALLOCATION &createAllocation) const;
GMM_GFX_PARTITIONING gfxPartition{};
ADAPTER_BDF adapterBDF{};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -1132,10 +1132,10 @@ bool WddmMemoryManager::mapMultiHandleAllocationWithRetry(WddmAllocation *alloca
bool WddmMemoryManager::createGpuAllocationsWithRetry(WddmAllocation *allocation) {
for (auto handleId = 0u; handleId < allocation->getNumGmms(); handleId++) {
auto gmm = allocation->getGmm(handleId);
auto status = getWddm(allocation->getRootDeviceIndex()).createAllocation(gmm->gmmResourceInfo->getSystemMemPointer(), gmm, allocation->getHandleToModify(handleId), allocation->getResourceHandleToModify(), allocation->getSharedHandleToModify());
auto status = getWddm(allocation->getRootDeviceIndex()).createAllocation(allocation->getUnderlyingBuffer(), gmm, allocation->getHandleToModify(handleId), allocation->getResourceHandleToModify(), allocation->getSharedHandleToModify());
if (status == STATUS_GRAPHICS_NO_VIDEO_MEMORY && deferredDeleter) {
deferredDeleter->drain(true, false);
status = getWddm(allocation->getRootDeviceIndex()).createAllocation(gmm->gmmResourceInfo->getSystemMemPointer(), gmm, allocation->getHandleToModify(handleId), allocation->getResourceHandleToModify(), allocation->getSharedHandleToModify());
status = getWddm(allocation->getRootDeviceIndex()).createAllocation(allocation->getUnderlyingBuffer(), gmm, allocation->getHandleToModify(handleId), allocation->getResourceHandleToModify(), allocation->getSharedHandleToModify());
}
if (status != STATUS_SUCCESS) {
getWddm(allocation->getRootDeviceIndex()).destroyAllocations(&allocation->getHandles()[0], handleId, allocation->getResourceHandle());