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);
}
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) {
init();
auto createContextParams = this->getCreateContextDataFcn();

View File

@ -419,3 +419,4 @@ UseContextEndOffsetForEventCompletion = -1
DirectSubmissionInsertExtraMiMemFenceCommands = -1
DirectSubmissionInsertSfenceInstructionPriorToSubmission = -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, 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, 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")
/*LOGGING FLAGS*/
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
*
@ -77,6 +77,7 @@ bool Gdi::getAllProcAddresses() {
registerTrimNotification = gdiDll->getProcAddress("D3DKMTRegisterTrimNotification");
unregisterTrimNotification = gdiDll->getProcAddress("D3DKMTUnregisterTrimNotification");
setAllocationPriority = gdiDll->getProcAddress("D3DKMTSetAllocationPriority");
setSchedulingPriority = gdiDll->getProcAddress("D3DKMTSetContextSchedulingPriority");
// For debug purposes
getDeviceState = gdiDll->getProcAddress("D3DKMTGetDeviceState");
@ -93,7 +94,7 @@ bool Gdi::getAllProcAddresses() {
&& signalSynchronizationObjectFromGpu && createPagingQueue && destroyPagingQueue
&& lock2 && unlock2 && mapGpuVirtualAddress && reserveGpuVirtualAddress
&& freeGpuVirtualAddress && updateGpuVirtualAddress &&submitCommand
&& makeResident && evict){
&& makeResident && evict && setSchedulingPriority){
if (NEO::OSInterface::requiresSupportForWddmTrimNotification) {
if(registerTrimNotification && unregisterTrimNotification){
return true;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -62,6 +62,7 @@ class Gdi {
ThkWrapper<IN D3DKMT_REGISTERTRIMNOTIFICATION *> registerTrimNotification{};
ThkWrapper<IN D3DKMT_UNREGISTERTRIMNOTIFICATION *> unregisterTrimNotification{};
ThkWrapper<IN CONST D3DKMT_SETALLOCATIONPRIORITY *> setAllocationPriority{};
ThkWrapper<IN CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *> setSchedulingPriority{};
// HW queue
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
*
@ -71,6 +71,7 @@ GET_ID(D3DKMT_CREATEHWQUEUE *, SYSTIMER_ID_CREATEHWQUEUE)
GET_ID(CONST D3DKMT_DESTROYHWQUEUE *, SYSTIMER_ID_DESTROYHWQUEUE)
GET_ID(CONST D3DKMT_SUBMITCOMMANDTOHWQUEUE *, SYSTIMER_ID_SUBMITCOMMANDTOHWQUEUE)
GET_ID(CONST D3DKMT_SETALLOCATIONPRIORITY *, SYSTIMER_ID_SETALLOCATIONPRIORITY)
GET_ID(CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *, SYSTIMER_ID_SETCONTEXTSCHEDULINGPRIORITY)
template <typename Param>
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);
}
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) {
NTSTATUS status = STATUS_UNSUCCESSFUL;
D3DKMT_CREATECONTEXTVIRTUAL CreateContext = {};
@ -838,7 +857,15 @@ bool Wddm::createContext(OsContextWin &osContext) {
"\nCreated Wddm context. Status: :%lu, engine: %u, contextId: %u, deviceBitfield: %lu \n",
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) {

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -122,6 +122,19 @@ NTSTATUS __stdcall D3DKMTCreateContextVirtual(IN D3DKMT_CREATECONTEXTVIRTUAL *cr
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) {
if (destroyContext == nullptr || destroyContext->hContext != CONTEXT_HANDLE) {
return STATUS_INVALID_PARAMETER;
@ -567,3 +580,11 @@ uint32_t getLastPriority() {
void setAdapterBDF(ADAPTER_BDF &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
*
@ -78,6 +78,8 @@ D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *getDestroySynchronizationObjectData();
void InitGfxPartition();
VOID *getMonitorFenceCpuFenceAddress();
bool *getCreateSynchronizationObject2FailCall();
bool *getFailOnSetContextSchedulingPriorityCall();
D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *getSetContextSchedulingPriorityDataCall();
bool *getRegisterTrimNotificationFailCall();
uint32_t getLastPriority();
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
*
@ -47,6 +47,10 @@ struct GdiDllFixture {
reinterpret_cast<decltype(&getMonitorFenceCpuFenceAddress)>(mockGdiDll->getProcAddress("getMonitorFenceCpuFenceAddress"));
getCreateSynchronizationObject2FailCallFcn =
reinterpret_cast<decltype(&getCreateSynchronizationObject2FailCall)>(mockGdiDll->getProcAddress("getCreateSynchronizationObject2FailCall"));
getFailOnSetContextSchedulingPriorityCallFcn =
reinterpret_cast<decltype(&getFailOnSetContextSchedulingPriorityCall)>(mockGdiDll->getProcAddress("getFailOnSetContextSchedulingPriorityCall"));
getSetContextSchedulingPriorityDataCallFcn =
reinterpret_cast<decltype(&getSetContextSchedulingPriorityDataCall)>(mockGdiDll->getProcAddress("getSetContextSchedulingPriorityDataCall"));
getRegisterTrimNotificationFailCallFcn =
reinterpret_cast<decltype(&getRegisterTrimNotificationFailCall)>(mockGdiDll->getProcAddress("getRegisterTrimNotificationFailCall"));
getLastPriorityFcn =
@ -56,6 +60,8 @@ struct GdiDllFixture {
setMockLastDestroyedResHandleFcn((D3DKMT_HANDLE)0);
*getDestroySynchronizationObjectDataFcn() = {};
*getCreateSynchronizationObject2FailCallFcn() = false;
*getFailOnSetContextSchedulingPriorityCallFcn() = false;
*getSetContextSchedulingPriorityDataCallFcn() = {};
*getRegisterTrimNotificationFailCallFcn() = false;
}
@ -66,6 +72,8 @@ struct GdiDllFixture {
*getDestroySynchronizationObjectDataFcn() = {};
setMapGpuVaFailConfigFcn(0, 0);
*getCreateSynchronizationObject2FailCallFcn() = false;
*getFailOnSetContextSchedulingPriorityCallFcn() = false;
*getSetContextSchedulingPriorityDataCallFcn() = {};
*getRegisterTrimNotificationFailCallFcn() = false;
}
@ -89,6 +97,8 @@ struct GdiDllFixture {
decltype(&getDestroySynchronizationObjectData) getDestroySynchronizationObjectDataFcn = nullptr;
decltype(&getMonitorFenceCpuFenceAddress) getMonitorFenceCpuFenceAddressFcn = nullptr;
decltype(&getCreateSynchronizationObject2FailCall) getCreateSynchronizationObject2FailCallFcn = nullptr;
decltype(&getFailOnSetContextSchedulingPriorityCall) getFailOnSetContextSchedulingPriorityCallFcn = nullptr;
decltype(&getSetContextSchedulingPriorityDataCall) getSetContextSchedulingPriorityDataCallFcn = nullptr;
decltype(&getRegisterTrimNotificationFailCall) getRegisterTrimNotificationFailCallFcn = nullptr;
decltype(&getLastPriority) getLastPriorityFcn = nullptr;
decltype(&setAdapterBDF) setAdapterBDFFcn = nullptr;