Defer OsContext initialization

Signed-off-by: Maciej Dziuban <maciej.dziuban@intel.com>
Related-To: NEO-5610
This commit is contained in:
Maciej Dziuban
2021-04-15 16:14:04 +00:00
committed by Compute-Runtime-Automation
parent b01b8ba5ac
commit 5318ff1872
35 changed files with 366 additions and 46 deletions

View File

@@ -1009,6 +1009,8 @@ uint32_t CommandStreamReceiverHw<GfxFamily>::blitBuffer(const BlitPropertiesCont
auto newTaskCount = taskCount + 1;
latestSentTaskCount = newTaskCount;
getOsContext().ensureContextInitialized();
if (PauseOnGpuProperties::pauseModeAllowed(DebugManager.flags.PauseOnBlitCopy.get(), taskCount, PauseOnGpuProperties::PauseMode::BeforeWorkload)) {
BlitCommandsHelper<GfxFamily>::dispatchDebugPauseCommands(commandStream, getDebugPauseStateGPUAddress(), DebugPauseState::waitingForUserStartConfirmation, DebugPauseState::hasUserStartConfirmation);
}

View File

@@ -242,6 +242,7 @@ DECLARE_DEBUG_VARIABLE(int32_t, UseVmBind, -1, "Use new residency model on Linux
DECLARE_DEBUG_VARIABLE(int32_t, PassBoundBOToExec, -1, "Pass bound BOs to exec call to keep dependencies")
DECLARE_DEBUG_VARIABLE(int32_t, EnableStaticPartitioning, -1, "Divide workload into partitions during dispatch, -1: default, 0: disabled, 1: enabled")
DECLARE_DEBUG_VARIABLE(int32_t, UpdateTaskCountFromWait, -1, " Do not update task count after each enqueue, but send update request while wait, -1: default(disabled), 0: disabled, 1: enabled")
DECLARE_DEBUG_VARIABLE(int32_t, DeferOsContextInitialization, -1, "-1: default, 0: create all contexts immediately, 1: defer, if possible")
DECLARE_DEBUG_VARIABLE(bool, UseMaxSimdSizeToDeduceMaxWorkgroupSize, false, "With this flag on, max workgroup size is deduced using SIMD32 instead of SIMD8, this causes the max wkg size to be 4 times bigger")
DECLARE_DEBUG_VARIABLE(bool, ReturnRawGpuTimestamps, false, "Driver returns raw GPU tiemstamps instead of calculated ones.")
DECLARE_DEBUG_VARIABLE(bool, ForcePerDssBackedBufferProgramming, false, "Always program per-DSS memory backed buffer in preamble")

View File

@@ -150,16 +150,17 @@ std::unique_ptr<CommandStreamReceiver> Device::createCommandStreamReceiver() con
}
bool Device::createEngine(uint32_t deviceCsrIndex, EngineTypeUsage engineTypeUsage) {
auto &hwInfo = getHardwareInfo();
auto defaultEngineType = getChosenEngineType(hwInfo);
const auto &hwInfo = getHardwareInfo();
const auto engineType = engineTypeUsage.first;
const auto engineUsage = engineTypeUsage.second;
const auto defaultEngineType = getChosenEngineType(hwInfo);
const bool isDefaultEngine = defaultEngineType == engineType && engineUsage == EngineUsage::Regular;
std::unique_ptr<CommandStreamReceiver> commandStreamReceiver = createCommandStreamReceiver();
if (!commandStreamReceiver) {
return false;
}
auto engineType = engineTypeUsage.first;
bool internalUsage = (engineTypeUsage.second == EngineUsage::Internal);
if (internalUsage) {
commandStreamReceiver->initializeDefaultsForInternalEngine();
@@ -175,6 +176,9 @@ bool Device::createEngine(uint32_t deviceCsrIndex, EngineTypeUsage engineTypeUsa
getDeviceBitfield(),
preemptionMode,
false);
if (osContext->isImmediateContextInitializationEnabled(isDefaultEngine)) {
osContext->ensureContextInitialized();
}
commandStreamReceiver->setupContext(*osContext);
if (!commandStreamReceiver->initializeTagAllocation()) {
@@ -185,7 +189,7 @@ bool Device::createEngine(uint32_t deviceCsrIndex, EngineTypeUsage engineTypeUsa
return false;
}
if (engineType == defaultEngineType && !lowPriority && !internalUsage) {
if (isDefaultEngine) {
defaultEngineIndex = deviceCsrIndex;
}

View File

@@ -30,7 +30,9 @@ OsContext *OsContext::create(OSInterface *osInterface, uint32_t contextId, Devic
OsContextLinux::OsContextLinux(Drm &drm, uint32_t contextId, DeviceBitfield deviceBitfield,
EngineTypeUsage typeUsage, PreemptionMode preemptionMode, bool rootDevice)
: OsContext(contextId, deviceBitfield, typeUsage, preemptionMode, rootDevice),
drm(drm) {
drm(drm) {}
void OsContextLinux::initializeContext() {
auto hwInfo = drm.getRootDeviceEnvironment().getHardwareInfo();
auto defaultEngineType = getChosenEngineType(*hwInfo);
@@ -96,8 +98,10 @@ void OsContextLinux::waitForPagingFence() {
}
OsContextLinux::~OsContextLinux() {
for (auto drmContextId : drmContextIds) {
drm.destroyDrmContext(drmContextId);
if (contextInitialized) {
for (auto drmContextId : drmContextIds) {
drm.destroyDrmContext(drmContextId);
}
}
}
} // namespace NEO

View File

@@ -29,6 +29,8 @@ class OsContextLinux : public OsContext {
void waitForPagingFence();
protected:
void initializeContext() override;
unsigned int engineFlag = 0;
std::vector<uint32_t> drmContextIds;
std::vector<uint32_t> drmVmIds;

View File

@@ -13,6 +13,38 @@
#include "shared/source/helpers/hw_info.h"
namespace NEO {
OsContext::OsContext(uint32_t contextId, DeviceBitfield deviceBitfield, EngineTypeUsage typeUsage, PreemptionMode preemptionMode, bool rootDevice)
: contextId(contextId),
deviceBitfield(deviceBitfield),
preemptionMode(preemptionMode),
numSupportedDevices(static_cast<uint32_t>(deviceBitfield.count())),
engineType(typeUsage.first),
engineUsage(typeUsage.second),
rootDevice(rootDevice) {}
bool OsContext::isImmediateContextInitializationEnabled(bool isDefaultEngine) const {
if (DebugManager.flags.DeferOsContextInitialization.get() == 0) {
return true;
}
if (engineUsage == EngineUsage::Internal) {
return true;
}
if (isDefaultEngine) {
return true;
}
return false;
}
void OsContext::ensureContextInitialized() {
std::call_once(contextInitializedFlag, [this] {
initializeContext();
contextInitialized = true;
});
}
bool OsContext::isDirectSubmissionAvailable(const HardwareInfo &hwInfo, bool &submitOnInit) {
bool enableDirectSubmission = this->isDirectSubmissionSupported(hwInfo);
@@ -85,4 +117,5 @@ bool OsContext::checkDirectSubmissionSupportsEngine(const DirectSubmissionProper
return supported;
}
} // namespace NEO
} // namespace NEO

View File

@@ -14,6 +14,7 @@
#include "engine_node.h"
#include <memory>
#include <mutex>
namespace NEO {
class OSInterface;
@@ -24,14 +25,19 @@ struct HardwareInfo;
class OsContext : public ReferenceTrackedObject<OsContext> {
public:
OsContext() = delete;
static OsContext *create(OSInterface *osInterface, uint32_t contextId, DeviceBitfield deviceBitfield,
EngineTypeUsage typeUsage, PreemptionMode preemptionMode, bool rootDevice);
bool isImmediateContextInitializationEnabled(bool isDefaultEngine) const;
bool isInitialized() const { return contextInitialized; }
void ensureContextInitialized();
uint32_t getContextId() const { return contextId; }
uint32_t getNumSupportedDevices() const { return numSupportedDevices; }
DeviceBitfield getDeviceBitfield() const { return deviceBitfield; }
PreemptionMode getPreemptionMode() const { return preemptionMode; }
aub_stream::EngineType &getEngineType() { return engineType; }
bool isRegular() const { return engineUsage == EngineUsage::Regular; }
bool isLowPriority() const { return engineUsage == EngineUsage::LowPriority; }
bool isInternalEngine() const { return engineUsage == EngineUsage::Internal; }
bool isRootDevice() const { return rootDevice; }
@@ -48,14 +54,8 @@ class OsContext : public ReferenceTrackedObject<OsContext> {
bool &startInContext);
protected:
OsContext(uint32_t contextId, DeviceBitfield deviceBitfield, EngineTypeUsage typeUsage, PreemptionMode preemptionMode, bool rootDevice)
: contextId(contextId),
deviceBitfield(deviceBitfield),
preemptionMode(preemptionMode),
numSupportedDevices(static_cast<uint32_t>(deviceBitfield.count())),
engineType(typeUsage.first),
engineUsage(typeUsage.second),
rootDevice(rootDevice) {}
OsContext(uint32_t contextId, DeviceBitfield deviceBitfield, EngineTypeUsage typeUsage, PreemptionMode preemptionMode, bool rootDevice);
virtual void initializeContext() {}
const uint32_t contextId;
const DeviceBitfield deviceBitfield;
@@ -66,5 +66,7 @@ class OsContext : public ReferenceTrackedObject<OsContext> {
const bool rootDevice = false;
bool defaultContext = false;
bool directSubmissionActive = false;
std::once_flag contextInitializedFlag = {};
bool contextInitialized = false;
};
} // namespace NEO

View File

@@ -25,8 +25,9 @@ OsContextWin::OsContextWin(Wddm &wddm, uint32_t contextId, DeviceBitfield device
EngineTypeUsage typeUsage, PreemptionMode preemptionMode, bool rootDevice)
: OsContext(contextId, deviceBitfield, typeUsage, preemptionMode, rootDevice),
wddm(wddm),
residencyController(wddm, contextId) {
residencyController(wddm, contextId) {}
void OsContextWin::initializeContext() {
auto wddmInterface = wddm.getWddmInterface();
UNRECOVERABLE_IF(!wddm.createContext(*this));
@@ -40,9 +41,11 @@ OsContextWin::OsContextWin(Wddm &wddm, uint32_t contextId, DeviceBitfield device
};
OsContextWin::~OsContextWin() {
wddm.getWddmInterface()->destroyHwQueue(hardwareQueue.handle);
wddm.getWddmInterface()->destroyMonitorFence(residencyController.getMonitoredFence());
wddm.destroyContext(wddmContextHandle);
if (contextInitialized) {
wddm.getWddmInterface()->destroyHwQueue(hardwareQueue.handle);
wddm.getWddmInterface()->destroyMonitorFence(residencyController.getMonitoredFence());
wddm.destroyContext(wddmContextHandle);
}
}
} // namespace NEO

View File

@@ -36,6 +36,8 @@ class OsContextWin : public OsContext {
MOCKABLE_VIRTUAL WddmResidencyController &getResidencyController() { return residencyController; }
protected:
void initializeContext() override;
D3DKMT_HANDLE wddmContextHandle = 0;
HardwareQueue hardwareQueue;
Wddm &wddm;

View File

@@ -86,6 +86,7 @@ void MockDevice::resetCommandStreamReceiver(CommandStreamReceiver *newCsr, uint3
memoryManager->getRegisteredEngines().emplace_back(registeredEngine);
osContext->incRefInternal();
newCsr->setupContext(*osContext);
osContext->ensureContextInitialized();
commandStreamReceivers[engineIndex].reset(newCsr);
commandStreamReceivers[engineIndex]->initializeTagAllocation();
commandStreamReceivers[engineIndex]->createGlobalFenceAllocation();

View File

@@ -32,6 +32,7 @@ struct DrmDirectSubmissionTest : public DrmMemoryManagerBasic {
osContext = std::make_unique<OsContextLinux>(*executionEnvironment.rootDeviceEnvironments[0]->osInterface->get()->getDrm(),
0u, device->getDeviceBitfield(), EngineTypeUsage{aub_stream::ENGINE_RCS, EngineUsage::Regular}, PreemptionMode::ThreadGroup,
false);
osContext->ensureContextInitialized();
}
void TearDown() override {

View File

@@ -30,6 +30,7 @@ struct WddmDirectSubmissionFixture : public WddmFixture {
executionEnvironment->memoryManager.reset(new WddmMemoryManager{*executionEnvironment});
device.reset(MockDevice::create<MockDevice>(executionEnvironment.get(), 0u));
osContext = std::make_unique<OsContextWin>(*wddm, 0u, device->getDeviceBitfield(), EngineTypeUsage{aub_stream::ENGINE_RCS, EngineUsage::Regular}, PreemptionMode::ThreadGroup, false);
osContext->ensureContextInitialized();
device->setPreemptionMode(PreemptionMode::ThreadGroup);
}

View File

@@ -45,6 +45,7 @@ class WddmPreemptionTests : public Test<WddmFixtureWithMockGdiDll> {
ASSERT_NE(nullptr, hwInfo);
auto engine = HwHelper::get(defaultHwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*hwInfo)[0];
osContext = std::make_unique<OsContextWin>(*wddm, 0u, 1, engine, preemptionMode, false);
osContext->ensureContextInitialized();
}
DebugManagerStateRestore *dbgRestorer = nullptr;