Capability to set low scheduling priority for Wddm context

Signed-off-by: Bartosz Dunajski <bartosz.dunajski@intel.com>
This commit is contained in:
Bartosz Dunajski
2022-05-10 13:53:48 +00:00
committed by Compute-Runtime-Automation
parent 5507633d15
commit c4fcd7ed9b
12 changed files with 133 additions and 8 deletions

View File

@@ -665,6 +665,62 @@ TEST_F(Wddm20WithMockGdiDllTestsWithoutWddmInit, givenUseNoRingFlushesKmdModeDeb
EXPECT_FALSE(!!privateData->NoRingFlushes); EXPECT_FALSE(!!privateData->NoRingFlushes);
} }
struct WddmContextSchedulingPriorityTests : public Wddm20WithMockGdiDllTestsWithoutWddmInit {
void initContext(bool lowPriority) {
auto preemptionMode = PreemptionHelper::getDefaultPreemptionMode(*defaultHwInfo);
wddmMockInterface = static_cast<WddmMockInterface20 *>(wddm->wddmInterface.release());
wddm->init();
wddm->wddmInterface.reset(wddmMockInterface);
auto hwInfo = rootDeviceEnvironment->getHardwareInfo();
auto engine = HwHelper::get(defaultHwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*hwInfo)[0];
auto engineDescriptor = EngineDescriptorHelper::getDefaultDescriptor(engine, preemptionMode);
engineDescriptor.engineTypeUsage.second = lowPriority ? EngineUsage::LowPriority : EngineUsage::Regular;
osContext = std::make_unique<OsContextWin>(*osInterface->getDriverModel()->as<Wddm>(), 0u, engineDescriptor);
osContext->ensureContextInitialized();
}
};
TEST_F(WddmContextSchedulingPriorityTests, givenLowPriorityContextWhenInitializingThenCallSetPriority) {
initContext(true);
auto createContextParams = this->getSetContextSchedulingPriorityDataCallFcn();
EXPECT_EQ(osContext->getWddmContextHandle(), createContextParams->hContext);
EXPECT_EQ(1, createContextParams->Priority);
}
TEST_F(WddmContextSchedulingPriorityTests, givenLowPriorityContextWhenFailingDuringSetSchedulingPriorityThenThrow) {
*this->getFailOnSetContextSchedulingPriorityCallFcn() = true;
EXPECT_ANY_THROW(initContext(true));
}
TEST_F(WddmContextSchedulingPriorityTests, givenDebugFlagSetWhenInitializingLowPriorityContextThenSetPriorityValue) {
DebugManagerStateRestore dbgRestore;
constexpr int32_t newPriority = 3;
DebugManager.flags.ForceWddmLowPriorityContextValue.set(newPriority);
initContext(true);
auto createContextParams = this->getSetContextSchedulingPriorityDataCallFcn();
EXPECT_EQ(osContext->getWddmContextHandle(), createContextParams->hContext);
EXPECT_EQ(newPriority, createContextParams->Priority);
}
TEST_F(WddmContextSchedulingPriorityTests, givenRegularContextWhenInitializingThenDontCallSetPriority) {
initContext(false);
auto createContextParams = this->getSetContextSchedulingPriorityDataCallFcn();
EXPECT_EQ(0, createContextParams->hContext);
EXPECT_EQ(0, createContextParams->Priority);
}
TEST_F(Wddm20WithMockGdiDllTestsWithoutWddmInit, givenCreateContextCallWhenDriverHintsThenItPointsToOpenCL) { TEST_F(Wddm20WithMockGdiDllTestsWithoutWddmInit, givenCreateContextCallWhenDriverHintsThenItPointsToOpenCL) {
init(); init();
auto createContextParams = this->getCreateContextDataFcn(); auto createContextParams = this->getCreateContextDataFcn();

View File

@@ -419,3 +419,4 @@ UseContextEndOffsetForEventCompletion = -1
DirectSubmissionInsertExtraMiMemFenceCommands = -1 DirectSubmissionInsertExtraMiMemFenceCommands = -1
DirectSubmissionInsertSfenceInstructionPriorToSubmission = -1 DirectSubmissionInsertSfenceInstructionPriorToSubmission = -1
EnableTimestampWaitForEvents = -1 EnableTimestampWaitForEvents = -1
ForceWddmLowPriorityContextValue = -1

View File

@@ -202,6 +202,7 @@ DECLARE_DEBUG_VARIABLE(int32_t, BatchBufferStartPrepatchingWaEnabled, -1, "-1: d
DECLARE_DEBUG_VARIABLE(int32_t, SetVmAdviseAtomicAttribute, -1, "-1: default - atomic system, 0: atomic none, 1: atomic device, 2: atomic system)") DECLARE_DEBUG_VARIABLE(int32_t, SetVmAdviseAtomicAttribute, -1, "-1: default - atomic system, 0: atomic none, 1: atomic device, 2: atomic system)")
DECLARE_DEBUG_VARIABLE(int32_t, ReadBackCommandBufferAllocation, -1, "Read command buffer allocation back on the host side. -1: default, 0 - disabled, 1 - local memory only, 2 - local and system memory") DECLARE_DEBUG_VARIABLE(int32_t, ReadBackCommandBufferAllocation, -1, "Read command buffer allocation back on the host side. -1: default, 0 - disabled, 1 - local memory only, 2 - local and system memory")
DECLARE_DEBUG_VARIABLE(int32_t, UseContextEndOffsetForEventCompletion, -1, "Use Context End or Context Start for event completion signalling. -1: default: platform dependent, 0 - Use Context Start, 1 - Use Context End") DECLARE_DEBUG_VARIABLE(int32_t, UseContextEndOffsetForEventCompletion, -1, "Use Context End or Context Start for event completion signalling. -1: default: platform dependent, 0 - Use Context Start, 1 - Use Context End")
DECLARE_DEBUG_VARIABLE(int32_t, ForceWddmLowPriorityContextValue, -1, "Force scheduling priority value during Wddm low priority context creation. -1 - default.")
DECLARE_DEBUG_VARIABLE(bool, DisableScratchPages, false, "Disable scratch pages during VM creations") DECLARE_DEBUG_VARIABLE(bool, DisableScratchPages, false, "Disable scratch pages during VM creations")
/*LOGGING FLAGS*/ /*LOGGING FLAGS*/
DECLARE_DEBUG_VARIABLE(int32_t, PrintDriverDiagnostics, -1, "prints driver diagnostics messages to standard output, value corresponds to hint level") DECLARE_DEBUG_VARIABLE(int32_t, PrintDriverDiagnostics, -1, "prints driver diagnostics messages to standard output, value corresponds to hint level")

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2021 Intel Corporation * Copyright (C) 2018-2022 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -77,6 +77,7 @@ bool Gdi::getAllProcAddresses() {
registerTrimNotification = gdiDll->getProcAddress("D3DKMTRegisterTrimNotification"); registerTrimNotification = gdiDll->getProcAddress("D3DKMTRegisterTrimNotification");
unregisterTrimNotification = gdiDll->getProcAddress("D3DKMTUnregisterTrimNotification"); unregisterTrimNotification = gdiDll->getProcAddress("D3DKMTUnregisterTrimNotification");
setAllocationPriority = gdiDll->getProcAddress("D3DKMTSetAllocationPriority"); setAllocationPriority = gdiDll->getProcAddress("D3DKMTSetAllocationPriority");
setSchedulingPriority = gdiDll->getProcAddress("D3DKMTSetContextSchedulingPriority");
// For debug purposes // For debug purposes
getDeviceState = gdiDll->getProcAddress("D3DKMTGetDeviceState"); getDeviceState = gdiDll->getProcAddress("D3DKMTGetDeviceState");
@@ -93,7 +94,7 @@ bool Gdi::getAllProcAddresses() {
&& signalSynchronizationObjectFromGpu && createPagingQueue && destroyPagingQueue && signalSynchronizationObjectFromGpu && createPagingQueue && destroyPagingQueue
&& lock2 && unlock2 && mapGpuVirtualAddress && reserveGpuVirtualAddress && lock2 && unlock2 && mapGpuVirtualAddress && reserveGpuVirtualAddress
&& freeGpuVirtualAddress && updateGpuVirtualAddress &&submitCommand && freeGpuVirtualAddress && updateGpuVirtualAddress &&submitCommand
&& makeResident && evict){ && makeResident && evict && setSchedulingPriority){
if (NEO::OSInterface::requiresSupportForWddmTrimNotification) { if (NEO::OSInterface::requiresSupportForWddmTrimNotification) {
if(registerTrimNotification && unregisterTrimNotification){ if(registerTrimNotification && unregisterTrimNotification){
return true; return true;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2021 Intel Corporation * Copyright (C) 2018-2022 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -62,6 +62,7 @@ class Gdi {
ThkWrapper<IN D3DKMT_REGISTERTRIMNOTIFICATION *> registerTrimNotification{}; ThkWrapper<IN D3DKMT_REGISTERTRIMNOTIFICATION *> registerTrimNotification{};
ThkWrapper<IN D3DKMT_UNREGISTERTRIMNOTIFICATION *> unregisterTrimNotification{}; ThkWrapper<IN D3DKMT_UNREGISTERTRIMNOTIFICATION *> unregisterTrimNotification{};
ThkWrapper<IN CONST D3DKMT_SETALLOCATIONPRIORITY *> setAllocationPriority{}; ThkWrapper<IN CONST D3DKMT_SETALLOCATIONPRIORITY *> setAllocationPriority{};
ThkWrapper<IN CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *> setSchedulingPriority{};
// HW queue // HW queue
ThkWrapper<IN OUT D3DKMT_CREATEHWQUEUE *> createHwQueue{}; ThkWrapper<IN OUT D3DKMT_CREATEHWQUEUE *> createHwQueue{};

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2021 Intel Corporation * Copyright (C) 2018-2022 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -71,6 +71,7 @@ GET_ID(D3DKMT_CREATEHWQUEUE *, SYSTIMER_ID_CREATEHWQUEUE)
GET_ID(CONST D3DKMT_DESTROYHWQUEUE *, SYSTIMER_ID_DESTROYHWQUEUE) GET_ID(CONST D3DKMT_DESTROYHWQUEUE *, SYSTIMER_ID_DESTROYHWQUEUE)
GET_ID(CONST D3DKMT_SUBMITCOMMANDTOHWQUEUE *, SYSTIMER_ID_SUBMITCOMMANDTOHWQUEUE) GET_ID(CONST D3DKMT_SUBMITCOMMANDTOHWQUEUE *, SYSTIMER_ID_SUBMITCOMMANDTOHWQUEUE)
GET_ID(CONST D3DKMT_SETALLOCATIONPRIORITY *, SYSTIMER_ID_SETALLOCATIONPRIORITY) GET_ID(CONST D3DKMT_SETALLOCATIONPRIORITY *, SYSTIMER_ID_SETALLOCATIONPRIORITY)
GET_ID(CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *, SYSTIMER_ID_SETCONTEXTSCHEDULINGPRIORITY)
template <typename Param> template <typename Param>
class ThkWrapper { class ThkWrapper {

View File

@@ -792,6 +792,25 @@ void Wddm::kmDafLock(D3DKMT_HANDLE handle) {
kmDafListener->notifyLock(featureTable->flags.ftrKmdDaf, getAdapter(), device, handle, 0, getGdi()->escape); kmDafListener->notifyLock(featureTable->flags.ftrKmdDaf, getAdapter(), device, handle, 0, getGdi()->escape);
} }
bool Wddm::setLowPriorityContextParam(D3DKMT_HANDLE contextHandle) {
D3DKMT_SETCONTEXTSCHEDULINGPRIORITY contextPriority = {};
contextPriority.hContext = contextHandle;
contextPriority.Priority = 1;
if (DebugManager.flags.ForceWddmLowPriorityContextValue.get() != -1) {
contextPriority.Priority = static_cast<INT>(DebugManager.flags.ForceWddmLowPriorityContextValue.get());
}
auto status = getGdi()->setSchedulingPriority(&contextPriority);
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stdout,
"\nSet scheduling priority for Wddm context. Status: :%lu, context handle: %u, priority: %d \n",
status, contextHandle, contextPriority.Priority);
return (status == STATUS_SUCCESS);
}
bool Wddm::createContext(OsContextWin &osContext) { bool Wddm::createContext(OsContextWin &osContext) {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
D3DKMT_CREATECONTEXTVIRTUAL CreateContext = {}; D3DKMT_CREATECONTEXTVIRTUAL CreateContext = {};
@@ -838,7 +857,15 @@ bool Wddm::createContext(OsContextWin &osContext) {
"\nCreated Wddm context. Status: :%lu, engine: %u, contextId: %u, deviceBitfield: %lu \n", "\nCreated Wddm context. Status: :%lu, engine: %u, contextId: %u, deviceBitfield: %lu \n",
status, osContext.getEngineType(), osContext.getContextId(), osContext.getDeviceBitfield().to_ulong()); status, osContext.getEngineType(), osContext.getContextId(), osContext.getDeviceBitfield().to_ulong());
return status == STATUS_SUCCESS; if (status != STATUS_SUCCESS) {
return false;
}
if (osContext.isLowPriority()) {
return setLowPriorityContextParam(osContext.getWddmContextHandle());
}
return true;
} }
bool Wddm::destroyContext(D3DKMT_HANDLE context) { bool Wddm::destroyContext(D3DKMT_HANDLE context) {

View File

@@ -243,6 +243,7 @@ class Wddm : public DriverModel {
bool destroyDevice(); bool destroyDevice();
void getDeviceState(); void getDeviceState();
MOCKABLE_VIRTUAL void createPagingFenceLogger(); MOCKABLE_VIRTUAL void createPagingFenceLogger();
bool setLowPriorityContextParam(D3DKMT_HANDLE contextHandle);
static GetSystemInfoFcn getSystemInfo; static GetSystemInfoFcn getSystemInfo;

View File

@@ -54,6 +54,7 @@ D3DKMTCreateHwQueue
D3DKMTDestroyHwQueue D3DKMTDestroyHwQueue
D3DKMTSubmitCommandToHwQueue D3DKMTSubmitCommandToHwQueue
D3DKMTSetAllocationPriority D3DKMTSetAllocationPriority
D3DKMTSetContextSchedulingPriority
MockSetAdapterInfo MockSetAdapterInfo
MockSetSizes MockSetSizes
GetMockSizes GetMockSizes
@@ -73,6 +74,8 @@ getSubmitCommandToHwQueueData
getDestroySynchronizationObjectData getDestroySynchronizationObjectData
getMonitorFenceCpuFenceAddress getMonitorFenceCpuFenceAddress
getCreateSynchronizationObject2FailCall getCreateSynchronizationObject2FailCall
getFailOnSetContextSchedulingPriorityCall
getSetContextSchedulingPriorityDataCall
getRegisterTrimNotificationFailCall getRegisterTrimNotificationFailCall
getLastPriority getLastPriority
setAdapterBDF setAdapterBDF

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2021 Intel Corporation * Copyright (C) 2018-2022 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -122,6 +122,19 @@ NTSTATUS __stdcall D3DKMTCreateContextVirtual(IN D3DKMT_CREATECONTEXTVIRTUAL *cr
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static bool failOnSetContextSchedulingPriority = false;
static D3DKMT_SETCONTEXTSCHEDULINGPRIORITY setContextSchedulingPriorityData = {};
NTSTATUS __stdcall D3DKMTSetContextSchedulingPriority(_In_ CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *setContextSchedulingPriority) {
setContextSchedulingPriorityData = *setContextSchedulingPriority;
if (failOnSetContextSchedulingPriority) {
return STATUS_INVALID_PARAMETER;
}
return STATUS_SUCCESS;
}
NTSTATUS __stdcall D3DKMTDestroyContext(IN CONST D3DKMT_DESTROYCONTEXT *destroyContext) { NTSTATUS __stdcall D3DKMTDestroyContext(IN CONST D3DKMT_DESTROYCONTEXT *destroyContext) {
if (destroyContext == nullptr || destroyContext->hContext != CONTEXT_HANDLE) { if (destroyContext == nullptr || destroyContext->hContext != CONTEXT_HANDLE) {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
@@ -567,3 +580,11 @@ uint32_t getLastPriority() {
void setAdapterBDF(ADAPTER_BDF &adapterBDF) { void setAdapterBDF(ADAPTER_BDF &adapterBDF) {
gAdapterBDF = adapterBDF; gAdapterBDF = adapterBDF;
} }
bool *getFailOnSetContextSchedulingPriorityCall() {
return &failOnSetContextSchedulingPriority;
}
D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *getSetContextSchedulingPriorityDataCall() {
return &setContextSchedulingPriorityData;
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2021 Intel Corporation * Copyright (C) 2018-2022 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -78,6 +78,8 @@ D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *getDestroySynchronizationObjectData();
void InitGfxPartition(); void InitGfxPartition();
VOID *getMonitorFenceCpuFenceAddress(); VOID *getMonitorFenceCpuFenceAddress();
bool *getCreateSynchronizationObject2FailCall(); bool *getCreateSynchronizationObject2FailCall();
bool *getFailOnSetContextSchedulingPriorityCall();
D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *getSetContextSchedulingPriorityDataCall();
bool *getRegisterTrimNotificationFailCall(); bool *getRegisterTrimNotificationFailCall();
uint32_t getLastPriority(); uint32_t getLastPriority();
void setAdapterBDF(ADAPTER_BDF &adapterBDF); void setAdapterBDF(ADAPTER_BDF &adapterBDF);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2021 Intel Corporation * Copyright (C) 2018-2022 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -47,6 +47,10 @@ struct GdiDllFixture {
reinterpret_cast<decltype(&getMonitorFenceCpuFenceAddress)>(mockGdiDll->getProcAddress("getMonitorFenceCpuFenceAddress")); reinterpret_cast<decltype(&getMonitorFenceCpuFenceAddress)>(mockGdiDll->getProcAddress("getMonitorFenceCpuFenceAddress"));
getCreateSynchronizationObject2FailCallFcn = getCreateSynchronizationObject2FailCallFcn =
reinterpret_cast<decltype(&getCreateSynchronizationObject2FailCall)>(mockGdiDll->getProcAddress("getCreateSynchronizationObject2FailCall")); reinterpret_cast<decltype(&getCreateSynchronizationObject2FailCall)>(mockGdiDll->getProcAddress("getCreateSynchronizationObject2FailCall"));
getFailOnSetContextSchedulingPriorityCallFcn =
reinterpret_cast<decltype(&getFailOnSetContextSchedulingPriorityCall)>(mockGdiDll->getProcAddress("getFailOnSetContextSchedulingPriorityCall"));
getSetContextSchedulingPriorityDataCallFcn =
reinterpret_cast<decltype(&getSetContextSchedulingPriorityDataCall)>(mockGdiDll->getProcAddress("getSetContextSchedulingPriorityDataCall"));
getRegisterTrimNotificationFailCallFcn = getRegisterTrimNotificationFailCallFcn =
reinterpret_cast<decltype(&getRegisterTrimNotificationFailCall)>(mockGdiDll->getProcAddress("getRegisterTrimNotificationFailCall")); reinterpret_cast<decltype(&getRegisterTrimNotificationFailCall)>(mockGdiDll->getProcAddress("getRegisterTrimNotificationFailCall"));
getLastPriorityFcn = getLastPriorityFcn =
@@ -56,6 +60,8 @@ struct GdiDllFixture {
setMockLastDestroyedResHandleFcn((D3DKMT_HANDLE)0); setMockLastDestroyedResHandleFcn((D3DKMT_HANDLE)0);
*getDestroySynchronizationObjectDataFcn() = {}; *getDestroySynchronizationObjectDataFcn() = {};
*getCreateSynchronizationObject2FailCallFcn() = false; *getCreateSynchronizationObject2FailCallFcn() = false;
*getFailOnSetContextSchedulingPriorityCallFcn() = false;
*getSetContextSchedulingPriorityDataCallFcn() = {};
*getRegisterTrimNotificationFailCallFcn() = false; *getRegisterTrimNotificationFailCallFcn() = false;
} }
@@ -66,6 +72,8 @@ struct GdiDllFixture {
*getDestroySynchronizationObjectDataFcn() = {}; *getDestroySynchronizationObjectDataFcn() = {};
setMapGpuVaFailConfigFcn(0, 0); setMapGpuVaFailConfigFcn(0, 0);
*getCreateSynchronizationObject2FailCallFcn() = false; *getCreateSynchronizationObject2FailCallFcn() = false;
*getFailOnSetContextSchedulingPriorityCallFcn() = false;
*getSetContextSchedulingPriorityDataCallFcn() = {};
*getRegisterTrimNotificationFailCallFcn() = false; *getRegisterTrimNotificationFailCallFcn() = false;
} }
@@ -89,6 +97,8 @@ struct GdiDllFixture {
decltype(&getDestroySynchronizationObjectData) getDestroySynchronizationObjectDataFcn = nullptr; decltype(&getDestroySynchronizationObjectData) getDestroySynchronizationObjectDataFcn = nullptr;
decltype(&getMonitorFenceCpuFenceAddress) getMonitorFenceCpuFenceAddressFcn = nullptr; decltype(&getMonitorFenceCpuFenceAddress) getMonitorFenceCpuFenceAddressFcn = nullptr;
decltype(&getCreateSynchronizationObject2FailCall) getCreateSynchronizationObject2FailCallFcn = nullptr; decltype(&getCreateSynchronizationObject2FailCall) getCreateSynchronizationObject2FailCallFcn = nullptr;
decltype(&getFailOnSetContextSchedulingPriorityCall) getFailOnSetContextSchedulingPriorityCallFcn = nullptr;
decltype(&getSetContextSchedulingPriorityDataCall) getSetContextSchedulingPriorityDataCallFcn = nullptr;
decltype(&getRegisterTrimNotificationFailCall) getRegisterTrimNotificationFailCallFcn = nullptr; decltype(&getRegisterTrimNotificationFailCall) getRegisterTrimNotificationFailCallFcn = nullptr;
decltype(&getLastPriority) getLastPriorityFcn = nullptr; decltype(&getLastPriority) getLastPriorityFcn = nullptr;
decltype(&setAdapterBDF) setAdapterBDFFcn = nullptr; decltype(&setAdapterBDF) setAdapterBDFFcn = nullptr;