Skip to content

Commit 1638554

Browse files
Add direct submission termination mechanism
Signed-off-by: Lukasz Jobczyk <lukasz.jobczyk@intel.com>
1 parent 49ebcb1 commit 1638554

19 files changed

+444
-42
lines changed

opencl/test/unit_test/command_stream/command_stream_receiver_tests.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "shared/test/common/mocks/ult_device_factory.h"
2929
#include "shared/test/common/test_macros/matchers.h"
3030
#include "shared/test/common/test_macros/test_checks_shared.h"
31+
#include "shared/test/unit_test/direct_submission/direct_submission_controller_mock.h"
3132

3233
#include "opencl/source/command_stream/definitions/command_stream_receiver_simulated_hw.h"
3334
#include "opencl/source/mem_obj/buffer.h"
@@ -393,6 +394,37 @@ struct InitDirectSubmissionFixture {
393394

394395
using InitDirectSubmissionTest = Test<InitDirectSubmissionFixture>;
395396

397+
HWTEST_F(InitDirectSubmissionTest, givenDirectSubmissionControllerEnabledWhenInitDirectSubmissionThenCsrIsRegistered) {
398+
DebugManagerStateRestore restorer;
399+
DebugManager.flags.EnableDirectSubmissionController.set(1);
400+
401+
auto csr = std::make_unique<CommandStreamReceiverHw<FamilyType>>(*device->executionEnvironment, device->getRootDeviceIndex(), device->getDeviceBitfield());
402+
std::unique_ptr<OsContext> osContext(OsContext::create(device->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.get(), 0,
403+
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::Regular},
404+
PreemptionMode::ThreadGroup, device->getDeviceBitfield())));
405+
406+
auto controller = static_cast<DirectSubmissionControllerMock *>(device->executionEnvironment->getDirectSubmissionController());
407+
controller->keepControlling.store(false);
408+
EXPECT_EQ(controller->directSubmissions.size(), 0u);
409+
410+
osContext->ensureContextInitialized();
411+
osContext->setDefaultContext(true);
412+
auto hwInfo = device->getRootDeviceEnvironment().getMutableHardwareInfo();
413+
hwInfo->capabilityTable.directSubmissionEngines.data[aub_stream::ENGINE_RCS].engineSupported = true;
414+
hwInfo->capabilityTable.directSubmissionEngines.data[aub_stream::ENGINE_RCS].submitOnInit = false;
415+
416+
bool ret = csr->initDirectSubmission(*device, *osContext.get());
417+
EXPECT_TRUE(ret);
418+
EXPECT_TRUE(csr->isDirectSubmissionEnabled());
419+
EXPECT_FALSE(csr->isBlitterDirectSubmissionEnabled());
420+
421+
EXPECT_EQ(controller->directSubmissions.size(), 1u);
422+
EXPECT_TRUE(controller->directSubmissions.find(csr.get()) != controller->directSubmissions.end());
423+
424+
csr.reset();
425+
EXPECT_EQ(controller->directSubmissions.size(), 0u);
426+
}
427+
396428
HWTEST_F(InitDirectSubmissionTest, whenDirectSubmissionEnabledOnRcsThenExpectFeatureAvailable) {
397429
auto csr = std::make_unique<CommandStreamReceiverHw<FamilyType>>(*device->executionEnvironment, device->getRootDeviceIndex(), device->getDeviceBitfield());
398430
std::unique_ptr<OsContext> osContext(OsContext::create(device->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.get(), 0,

opencl/test/unit_test/execution_environment/execution_environment_tests.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "shared/source/command_stream/preemption.h"
1212
#include "shared/source/compiler_interface/compiler_interface.h"
1313
#include "shared/source/device/device.h"
14+
#include "shared/source/direct_submission/direct_submission_controller.h"
1415
#include "shared/source/execution_environment/execution_environment.h"
1516
#include "shared/source/gmm_helper/gmm_helper.h"
1617
#include "shared/source/helpers/hw_helper.h"
@@ -159,6 +160,24 @@ TEST(ExecutionEnvironment, givenExecutionEnvironmentWhenInitializeMemoryManagerI
159160
EXPECT_EQ(enableLocalMemory, executionEnvironment->memoryManager->isLocalMemorySupported(device->getRootDeviceIndex()));
160161
}
161162

163+
TEST(ExecutionEnvironment, givenEnableDirectSubmissionControllerSetWhenGetDirectSubmissionControllerThenNotNull) {
164+
DebugManagerStateRestore restorer;
165+
DebugManager.flags.EnableDirectSubmissionController.set(1);
166+
167+
auto controller = platform()->peekExecutionEnvironment()->getDirectSubmissionController();
168+
169+
EXPECT_NE(controller, nullptr);
170+
}
171+
172+
TEST(ExecutionEnvironment, givenEnableDirectSubmissionControllerSetZeroWhenGetDirectSubmissionControllerThenNull) {
173+
DebugManagerStateRestore restorer;
174+
DebugManager.flags.EnableDirectSubmissionController.set(0);
175+
176+
auto controller = platform()->peekExecutionEnvironment()->getDirectSubmissionController();
177+
178+
EXPECT_EQ(controller, nullptr);
179+
}
180+
162181
TEST(ExecutionEnvironment, givenExecutionEnvironmentWhenInitializeMemoryManagerIsCalledThenItIsInitalized) {
163182
ExecutionEnvironment *executionEnvironment = platform()->peekExecutionEnvironment();
164183
executionEnvironment->initializeMemoryManager();
@@ -167,16 +186,20 @@ TEST(ExecutionEnvironment, givenExecutionEnvironmentWhenInitializeMemoryManagerI
167186
static_assert(sizeof(ExecutionEnvironment) == sizeof(std::unique_ptr<HardwareInfo>) +
168187
sizeof(std::vector<RootDeviceEnvironment>) +
169188
sizeof(std::unique_ptr<OsEnvironment>) +
189+
sizeof(std::unique_ptr<DirectSubmissionController>) +
170190
sizeof(bool) +
171191
(is64bit ? 23 : 15),
172192
"New members detected in ExecutionEnvironment, please ensure that destruction sequence of objects is correct");
173193

174194
TEST(ExecutionEnvironment, givenExecutionEnvironmentWithVariousMembersWhenItIsDestroyedThenDeleteSequenceIsSpecified) {
175195
uint32_t destructorId = 0u;
176196

177-
struct MemoryMangerMock : public DestructorCounted<MockMemoryManager, 7> {
197+
struct MemoryMangerMock : public DestructorCounted<MockMemoryManager, 8> {
178198
MemoryMangerMock(uint32_t &destructorId, ExecutionEnvironment &executionEnvironment) : DestructorCounted(destructorId, executionEnvironment) {}
179199
};
200+
struct DirectSubmissionControllerMock : public DestructorCounted<DirectSubmissionController, 7> {
201+
DirectSubmissionControllerMock(uint32_t &destructorId) : DestructorCounted(destructorId) {}
202+
};
180203
struct GmmHelperMock : public DestructorCounted<GmmHelper, 6> {
181204
GmmHelperMock(uint32_t &destructorId, const HardwareInfo *hwInfo) : DestructorCounted(destructorId, nullptr, hwInfo) {}
182205
};
@@ -212,9 +235,10 @@ TEST(ExecutionEnvironment, givenExecutionEnvironmentWithVariousMembersWhenItIsDe
212235
executionEnvironment->rootDeviceEnvironments[0]->builtins = std::make_unique<BuiltinsMock>(destructorId);
213236
executionEnvironment->rootDeviceEnvironments[0]->compilerInterface = std::make_unique<CompilerInterfaceMock>(destructorId);
214237
executionEnvironment->rootDeviceEnvironments[0]->debugger = std::make_unique<SourceLevelDebuggerMock>(destructorId);
238+
executionEnvironment->directSubmissionController = std::make_unique<DirectSubmissionControllerMock>(destructorId);
215239

216240
executionEnvironment.reset(nullptr);
217-
EXPECT_EQ(8u, destructorId);
241+
EXPECT_EQ(9u, destructorId);
218242
}
219243

220244
TEST(ExecutionEnvironment, givenMultipleRootDevicesWhenTheyAreCreatedThenReuseMemoryManager) {

opencl/test/unit_test/test_files/igdrcl.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ DirectSubmissionNewResourceTlbFlush = -1
9898
DirectSubmissionDisableCacheFlush = -1
9999
DirectSubmissionDisableMonitorFence = -1
100100
USMEvictAfterMigration = 1
101+
EnableDirectSubmissionController = -1
102+
DirectSubmissionControllerTimeout = -1
101103
UseVmBind = -1
102104
PassBoundBOToExec = -1
103105
EnableNullHardware = 0

shared/source/command_stream/command_stream_receiver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ class CommandStreamReceiver {
241241
return false;
242242
}
243243

244+
virtual void stopDirectSubmission() {}
245+
244246
bool isStaticWorkPartitioningEnabled() const {
245247
return staticWorkPartitioningEnabled;
246248
}

shared/source/command_stream/command_stream_receiver_hw.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ class CommandStreamReceiverHw : public CommandStreamReceiver {
5353
static void addBatchBufferEnd(LinearStream &commandStream, void **patchLocation);
5454
void programEndingCmd(LinearStream &commandStream, Device &device, void **patchLocation, bool directSubmissionEnabled);
5555
void addBatchBufferStart(MI_BATCH_BUFFER_START *commandBufferMemory, uint64_t startAddress, bool secondary);
56+
5657
static void alignToCacheLine(LinearStream &commandStream);
58+
static void emitNoop(LinearStream &commandStream, size_t bytesToUpdate);
5759

5860
size_t getRequiredStateBaseAddressSize(const Device &device) const;
5961
size_t getRequiredCmdStreamSize(const DispatchFlags &dispatchFlags, Device &device);
@@ -119,6 +121,8 @@ class CommandStreamReceiverHw : public CommandStreamReceiver {
119121
return blitterDirectSubmission.get() != nullptr;
120122
}
121123

124+
void stopDirectSubmission() override;
125+
122126
virtual bool isKmdWaitModeActive() { return true; }
123127

124128
bool initDirectSubmission(Device &device, OsContext &osContext) override;
@@ -157,8 +161,6 @@ class CommandStreamReceiverHw : public CommandStreamReceiver {
157161
uint64_t getScratchPatchAddress();
158162
void createScratchSpaceController();
159163

160-
static void emitNoop(LinearStream &commandStream, size_t bytesToUpdate);
161-
162164
bool detectInitProgrammingFlagsRequired(const DispatchFlags &dispatchFlags) const;
163165
bool checkPlatformSupportsNewResourceImplicitFlush() const;
164166
bool checkPlatformSupportsGpuIdleImplicitFlush() const;

shared/source/command_stream/command_stream_receiver_hw_base.inl

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "shared/source/command_stream/stream_properties.h"
1414
#include "shared/source/debug_settings/debug_settings_manager.h"
1515
#include "shared/source/device/device.h"
16+
#include "shared/source/direct_submission/direct_submission_controller.h"
1617
#include "shared/source/direct_submission/direct_submission_hw.h"
1718
#include "shared/source/execution_environment/root_device_environment.h"
1819
#include "shared/source/gmm_helper/page_table_mngr.h"
@@ -38,7 +39,12 @@
3839
namespace NEO {
3940

4041
template <typename GfxFamily>
41-
CommandStreamReceiverHw<GfxFamily>::~CommandStreamReceiverHw() = default;
42+
CommandStreamReceiverHw<GfxFamily>::~CommandStreamReceiverHw() {
43+
auto directSubmissionController = executionEnvironment.getDirectSubmissionController();
44+
if (directSubmissionController) {
45+
directSubmissionController->unregisterDirectSubmission(this);
46+
}
47+
}
4248

4349
template <typename GfxFamily>
4450
CommandStreamReceiverHw<GfxFamily>::CommandStreamReceiverHw(ExecutionEnvironment &executionEnvironment,
@@ -1390,6 +1396,15 @@ inline size_t CommandStreamReceiverHw<GfxFamily>::getCmdSizeForPrologue() const
13901396
return 0u;
13911397
}
13921398

1399+
template <typename GfxFamily>
1400+
inline void CommandStreamReceiverHw<GfxFamily>::stopDirectSubmission() {
1401+
if (EngineHelpers::isBcs(this->osContext->getEngineType())) {
1402+
this->blitterDirectSubmission->stopRingBuffer();
1403+
} else {
1404+
this->directSubmission->stopRingBuffer();
1405+
}
1406+
}
1407+
13931408
template <typename GfxFamily>
13941409
inline bool CommandStreamReceiverHw<GfxFamily>::initDirectSubmission(Device &device, OsContext &osContext) {
13951410
bool ret = true;
@@ -1398,16 +1413,19 @@ inline bool CommandStreamReceiverHw<GfxFamily>::initDirectSubmission(Device &dev
13981413
auto startDirect = osContext.isDirectSubmissionAvailable(device.getHardwareInfo(), submitOnInit);
13991414

14001415
if (startDirect) {
1401-
if (EngineHelpers::isBcs(osContext.getEngineType())) {
1402-
if (!this->isBlitterDirectSubmissionEnabled()) {
1416+
if (!this->isBlitterDirectSubmissionEnabled() && !this->isDirectSubmissionEnabled()) {
1417+
if (EngineHelpers::isBcs(osContext.getEngineType())) {
14031418
blitterDirectSubmission = DirectSubmissionHw<GfxFamily, BlitterDispatcher<GfxFamily>>::create(device, osContext);
14041419
ret = blitterDirectSubmission->initialize(submitOnInit);
1405-
}
1406-
} else {
1407-
if (!this->isDirectSubmissionEnabled()) {
1420+
1421+
} else {
14081422
directSubmission = DirectSubmissionHw<GfxFamily, RenderDispatcher<GfxFamily>>::create(device, osContext);
14091423
ret = directSubmission->initialize(submitOnInit);
14101424
}
1425+
auto directSubmissionController = executionEnvironment.getDirectSubmissionController();
1426+
if (directSubmissionController) {
1427+
directSubmissionController->registerDirectSubmission(this);
1428+
}
14111429
}
14121430
osContext.setDirectSubmissionActive();
14131431
}

shared/source/debug_settings/debug_variables_base.inl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionDisableCacheFlush, -1, "-1: driv
235235
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionNewResourceTlbFlush, -1, "-1: driver default - flush when new resource is bound, 0: disabled, 1: enabled")
236236
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionDisableMonitorFence, -1, "Disable dispatching monitor fence commands")
237237
DECLARE_DEBUG_VARIABLE(bool, USMEvictAfterMigration, true, "Evict USM allocation after implicit migration to GPU")
238+
DECLARE_DEBUG_VARIABLE(int32_t, EnableDirectSubmissionController, -1, "Enable direct submission terminating after given timeout, -1: default, 0: disabled, 1: enabled")
239+
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionControllerTimeout, -1, "Set direct submission controller timeout, -1: default 5 ms, >=0: timeout in ms")
238240

239241
/*FEATURE FLAGS*/
240242
DECLARE_DEBUG_VARIABLE(bool, EnableNV12, true, "Enables NV12 extension")

shared/source/direct_submission/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#
2-
# Copyright (C) 2020 Intel Corporation
2+
# Copyright (C) 2020-2021 Intel Corporation
33
#
44
# SPDX-License-Identifier: MIT
55
#
66

77
set(NEO_CORE_DIRECT_SUBMISSION
88
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
9+
${CMAKE_CURRENT_SOURCE_DIR}/direct_submission_controller.cpp
10+
${CMAKE_CURRENT_SOURCE_DIR}/direct_submission_controller.h
911
${CMAKE_CURRENT_SOURCE_DIR}/direct_submission_hw.h
1012
${CMAKE_CURRENT_SOURCE_DIR}/direct_submission_hw.inl
1113
${CMAKE_CURRENT_SOURCE_DIR}/direct_submission_hw_diagnostic_mode.cpp
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (C) 2019-2021 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include "shared/source/direct_submission/direct_submission_controller.h"
9+
10+
#include "shared/source/command_stream/command_stream_receiver.h"
11+
12+
#include <chrono>
13+
14+
namespace NEO {
15+
16+
DirectSubmissionController::DirectSubmissionController() {
17+
timeout = 5;
18+
19+
if (DebugManager.flags.DirectSubmissionControllerTimeout.get() != -1) {
20+
timeout = DebugManager.flags.DirectSubmissionControllerTimeout.get();
21+
}
22+
23+
directSubmissionControllingThread = std::thread(&DirectSubmissionController::controlDirectSubmissionsState, this);
24+
};
25+
26+
DirectSubmissionController::~DirectSubmissionController() {
27+
keepControlling.store(false);
28+
if (directSubmissionControllingThread.joinable()) {
29+
directSubmissionControllingThread.join();
30+
}
31+
}
32+
33+
void DirectSubmissionController::registerDirectSubmission(CommandStreamReceiver *csr) {
34+
std::lock_guard<std::mutex> lock(directSubmissionsMutex);
35+
directSubmissions.insert(std::make_pair(csr, DirectSubmissionState{}));
36+
}
37+
38+
void DirectSubmissionController::unregisterDirectSubmission(CommandStreamReceiver *csr) {
39+
std::lock_guard<std::mutex> lock(directSubmissionsMutex);
40+
directSubmissions.erase(csr);
41+
}
42+
43+
void DirectSubmissionController::controlDirectSubmissionsState() {
44+
while (true) {
45+
46+
auto start = std::chrono::steady_clock::now();
47+
int diff = 0u;
48+
do {
49+
if (!keepControlling.load()) {
50+
return;
51+
}
52+
53+
auto timestamp = std::chrono::steady_clock::now();
54+
diff = static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(timestamp - start).count());
55+
} while (diff <= timeout);
56+
57+
this->checkNewSubmissions();
58+
}
59+
}
60+
61+
void DirectSubmissionController::checkNewSubmissions() {
62+
std::lock_guard<std::mutex> lock(this->directSubmissionsMutex);
63+
64+
for (auto &directSubmission : this->directSubmissions) {
65+
auto csr = directSubmission.first;
66+
auto &state = directSubmission.second;
67+
68+
auto taskCount = csr->peekTaskCount();
69+
if (taskCount <= *csr->getTagAddress()) {
70+
if (taskCount == state.taskCount) {
71+
if (state.isStopped) {
72+
continue;
73+
} else {
74+
auto lock = csr->obtainUniqueOwnership();
75+
csr->stopDirectSubmission();
76+
state.isStopped = true;
77+
}
78+
} else {
79+
state.isStopped = false;
80+
state.taskCount = taskCount;
81+
}
82+
} else {
83+
state.isStopped = false;
84+
}
85+
}
86+
}
87+
88+
} // namespace NEO
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (C) 2019-2021 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#pragma once
9+
10+
#include <atomic>
11+
#include <mutex>
12+
#include <thread>
13+
#include <unordered_map>
14+
15+
namespace NEO {
16+
class MemoryManager;
17+
class CommandStreamReceiver;
18+
19+
class DirectSubmissionController {
20+
public:
21+
DirectSubmissionController();
22+
virtual ~DirectSubmissionController();
23+
24+
void registerDirectSubmission(CommandStreamReceiver *csr);
25+
void unregisterDirectSubmission(CommandStreamReceiver *csr);
26+
27+
protected:
28+
struct DirectSubmissionState {
29+
bool isStopped = false;
30+
uint32_t taskCount = 0u;
31+
};
32+
33+
void controlDirectSubmissionsState();
34+
void checkNewSubmissions();
35+
36+
std::unordered_map<CommandStreamReceiver *, DirectSubmissionState> directSubmissions;
37+
std::mutex directSubmissionsMutex;
38+
39+
std::thread directSubmissionControllingThread;
40+
std::atomic_bool keepControlling = true;
41+
42+
int timeout = 5;
43+
};
44+
} // namespace NEO

0 commit comments

Comments
 (0)