Revert "fix: use condition variables instead of busy waits in worker threads"

This reverts commit 4406889b39.

Signed-off-by: Compute-Runtime-Validation <compute-runtime-validation@intel.com>
This commit is contained in:
Compute-Runtime-Validation
2025-11-08 12:46:45 +01:00
committed by Compute-Runtime-Automation
parent 24055f553d
commit ff27bb12d1
23 changed files with 174 additions and 315 deletions

View File

@@ -673,6 +673,13 @@ void CommandStreamReceiver::downloadAllocation(GraphicsAllocation &gfxAllocation
} }
} }
void CommandStreamReceiver::startControllingDirectSubmissions() {
auto controller = this->executionEnvironment.directSubmissionController.get();
if (controller) {
controller->startControlling();
}
}
bool CommandStreamReceiver::enqueueWaitForPagingFence(uint64_t pagingFenceValue) { bool CommandStreamReceiver::enqueueWaitForPagingFence(uint64_t pagingFenceValue) {
auto controller = this->executionEnvironment.directSubmissionController.get(); auto controller = this->executionEnvironment.directSubmissionController.get();
if (this->isAnyDirectSubmissionEnabled() && controller) { if (this->isAnyDirectSubmissionEnabled() && controller) {

View File

@@ -352,6 +352,8 @@ class CommandStreamReceiver : NEO::NonCopyableAndNonMovableClass {
uint32_t getRootDeviceIndex() const { return rootDeviceIndex; } uint32_t getRootDeviceIndex() const { return rootDeviceIndex; }
MOCKABLE_VIRTUAL void startControllingDirectSubmissions();
MOCKABLE_VIRTUAL bool isAnyDirectSubmissionEnabled() const { MOCKABLE_VIRTUAL bool isAnyDirectSubmissionEnabled() const {
return this->isDirectSubmissionEnabled() || isBlitterDirectSubmissionEnabled(); return this->isDirectSubmissionEnabled() || isBlitterDirectSubmissionEnabled();
} }

View File

@@ -1304,7 +1304,7 @@ SubmissionStatus CommandStreamReceiverHw<GfxFamily>::flushSmallTask(LinearStream
this->latestSentTaskCount = taskCount + 1; this->latestSentTaskCount = taskCount + 1;
auto submissionStatus = flushHandler(batchBuffer, getResidencyAllocations()); auto submissionStatus = flushHandler(batchBuffer, getResidencyAllocations());
if (submissionStatus == SubmissionStatus::success) { if (submissionStatus == SubmissionStatus::success) {
++taskCount; taskCount++;
} }
return submissionStatus; return submissionStatus;
} }
@@ -1473,6 +1473,7 @@ inline bool CommandStreamReceiverHw<GfxFamily>::initDirectSubmission() {
if (directSubmissionController) { if (directSubmissionController) {
directSubmissionController->registerDirectSubmission(this); directSubmissionController->registerDirectSubmission(this);
} }
this->startControllingDirectSubmissions();
if (this->isUpdateTagFromWaitEnabled()) { if (this->isUpdateTagFromWaitEnabled()) {
this->overrideDispatchPolicy(DispatchMode::immediateDispatch); this->overrideDispatchPolicy(DispatchMode::immediateDispatch);
} }
@@ -1485,7 +1486,6 @@ inline bool CommandStreamReceiverHw<GfxFamily>::initDirectSubmission() {
} }
} }
} }
return ret; return ret;
} }

View File

@@ -66,40 +66,50 @@ void DirectSubmissionController::startThread() {
} }
void DirectSubmissionController::stopThread() { void DirectSubmissionController::stopThread() {
{ runControlling.store(false);
std::lock_guard<std::mutex> lock(condVarMutex); keepControlling.store(false);
keepControlling.store(false);
condVar.notify_one();
}
if (directSubmissionControllingThread) { if (directSubmissionControllingThread) {
directSubmissionControllingThread->join(); directSubmissionControllingThread->join();
directSubmissionControllingThread.reset(); directSubmissionControllingThread.reset();
} }
} }
void DirectSubmissionController::startControlling() {
this->runControlling.store(true);
}
void *DirectSubmissionController::controlDirectSubmissionsState(void *self) { void *DirectSubmissionController::controlDirectSubmissionsState(void *self) {
auto controller = reinterpret_cast<DirectSubmissionController *>(self); auto controller = reinterpret_cast<DirectSubmissionController *>(self);
while (!controller->runControlling.load()) {
if (!controller->keepControlling.load()) {
return nullptr;
}
std::unique_lock<std::mutex> lock(controller->condVarMutex);
controller->handlePagingFenceRequests(lock, false);
auto isControllerNotified = controller->sleep(lock);
if (isControllerNotified) {
controller->handlePagingFenceRequests(lock, false);
}
}
controller->timeSinceLastCheck = controller->getCpuTimestamp(); controller->timeSinceLastCheck = controller->getCpuTimestamp();
controller->lastHangCheckTime = std::chrono::high_resolution_clock::now(); controller->lastHangCheckTime = std::chrono::high_resolution_clock::now();
while (true) {
while (controller->keepControlling.load()) { if (!controller->keepControlling.load()) {
return nullptr;
}
std::unique_lock<std::mutex> lock(controller->condVarMutex); std::unique_lock<std::mutex> lock(controller->condVarMutex);
controller->wait(lock); controller->handlePagingFenceRequests(lock, true);
controller->handlePagingFenceRequests(lock);
controller->sleep(lock); auto isControllerNotified = controller->sleep(lock);
controller->handlePagingFenceRequests(lock); if (isControllerNotified) {
controller->handlePagingFenceRequests(lock, true);
}
lock.unlock(); lock.unlock();
controller->checkNewSubmissions(); controller->checkNewSubmissions();
} }
return nullptr;
}
void DirectSubmissionController::notifyNewSubmission(const CommandStreamReceiver *csr) {
++activeSubmissionsCount;
directSubmissions[const_cast<CommandStreamReceiver *>(csr)].isActive = true;
condVar.notify_one();
} }
void DirectSubmissionController::checkNewSubmissions() { void DirectSubmissionController::checkNewSubmissions() {
@@ -111,11 +121,9 @@ void DirectSubmissionController::checkNewSubmissions() {
std::lock_guard<std::mutex> lock(this->directSubmissionsMutex); std::lock_guard<std::mutex> lock(this->directSubmissionsMutex);
bool shouldRecalculateTimeout = false; bool shouldRecalculateTimeout = false;
std::optional<TaskCountType> bcsTaskCount{}; std::optional<TaskCountType> bcsTaskCount{};
for (auto &[csr, state] : directSubmissions) { for (auto &directSubmission : this->directSubmissions) {
if (!state.isActive) { auto csr = directSubmission.first;
continue; auto &state = directSubmission.second;
}
auto isBcs = EngineHelpers::isBcs(csr->getOsContext().getEngineType()); auto isBcs = EngineHelpers::isBcs(csr->getOsContext().getEngineType());
if (timeoutMode == TimeoutElapsedMode::bcsOnly && !isBcs) { if (timeoutMode == TimeoutElapsedMode::bcsOnly && !isBcs) {
continue; continue;
@@ -135,10 +143,8 @@ void DirectSubmissionController::checkNewSubmissions() {
auto lock = csr->obtainUniqueOwnership(); auto lock = csr->obtainUniqueOwnership();
if (!isCsrIdleDetectionEnabled || (isDirectSubmissionIdle(csr, lock) && isCopyEngineIdle)) { if (!isCsrIdleDetectionEnabled || (isDirectSubmissionIdle(csr, lock) && isCopyEngineIdle)) {
csr->stopDirectSubmission(false, false); csr->stopDirectSubmission(false, false);
state.isActive = false;
state.isStopped = true; state.isStopped = true;
shouldRecalculateTimeout = true; shouldRecalculateTimeout = true;
--activeSubmissionsCount;
} }
state.taskCount = csr->peekTaskCount(); state.taskCount = csr->peekTaskCount();
} else { } else {
@@ -276,13 +282,13 @@ void DirectSubmissionController::recalculateTimeout() {
} }
void DirectSubmissionController::enqueueWaitForPagingFence(CommandStreamReceiver *csr, uint64_t pagingFenceValue) { void DirectSubmissionController::enqueueWaitForPagingFence(CommandStreamReceiver *csr, uint64_t pagingFenceValue) {
std::lock_guard lock(condVarMutex); std::lock_guard lock(this->condVarMutex);
pagingFenceRequests.push({csr, pagingFenceValue}); pagingFenceRequests.push({csr, pagingFenceValue});
condVar.notify_one(); condVar.notify_one();
} }
void DirectSubmissionController::drainPagingFenceQueue() { void DirectSubmissionController::drainPagingFenceQueue() {
std::lock_guard lock(condVarMutex); std::lock_guard lock(this->condVarMutex);
while (!pagingFenceRequests.empty()) { while (!pagingFenceRequests.empty()) {
auto request = pagingFenceRequests.front(); auto request = pagingFenceRequests.front();
@@ -291,13 +297,18 @@ void DirectSubmissionController::drainPagingFenceQueue() {
} }
} }
void DirectSubmissionController::handlePagingFenceRequests(std::unique_lock<std::mutex> &lock) { void DirectSubmissionController::handlePagingFenceRequests(std::unique_lock<std::mutex> &lock, bool checkForNewSubmissions) {
UNRECOVERABLE_IF(!lock.owns_lock()) UNRECOVERABLE_IF(!lock.owns_lock())
while (!pagingFenceRequests.empty()) { while (!pagingFenceRequests.empty()) {
auto request = pagingFenceRequests.front(); auto request = pagingFenceRequests.front();
pagingFenceRequests.pop(); pagingFenceRequests.pop();
lock.unlock(); lock.unlock();
request.csr->unblockPagingFenceSemaphore(request.pagingFenceValue); request.csr->unblockPagingFenceSemaphore(request.pagingFenceValue);
if (checkForNewSubmissions) {
checkNewSubmissions();
}
lock.lock(); lock.lock();
} }
} }

View File

@@ -61,18 +61,17 @@ class DirectSubmissionController {
void unregisterDirectSubmission(CommandStreamReceiver *csr); void unregisterDirectSubmission(CommandStreamReceiver *csr);
void startThread(); void startThread();
void startControlling();
void stopThread(); void stopThread();
static bool isSupported(); static bool isSupported();
void enqueueWaitForPagingFence(CommandStreamReceiver *csr, uint64_t pagingFenceValue); void enqueueWaitForPagingFence(CommandStreamReceiver *csr, uint64_t pagingFenceValue);
void drainPagingFenceQueue(); void drainPagingFenceQueue();
void notifyNewSubmission(const CommandStreamReceiver *csr);
protected: protected:
struct DirectSubmissionState { struct DirectSubmissionState {
DirectSubmissionState(DirectSubmissionState &&other) noexcept { DirectSubmissionState(DirectSubmissionState &&other) noexcept {
isActive = other.isActive.load();
isStopped = other.isStopped.load(); isStopped = other.isStopped.load();
taskCount = other.taskCount.load(); taskCount = other.taskCount.load();
} }
@@ -80,7 +79,6 @@ class DirectSubmissionController {
if (this == &other) { if (this == &other) {
return *this; return *this;
} }
this->isActive = other.isActive.load();
this->isStopped = other.isStopped.load(); this->isStopped = other.isStopped.load();
this->taskCount = other.taskCount.load(); this->taskCount = other.taskCount.load();
return *this; return *this;
@@ -92,20 +90,15 @@ class DirectSubmissionController {
DirectSubmissionState(const DirectSubmissionState &other) = delete; DirectSubmissionState(const DirectSubmissionState &other) = delete;
DirectSubmissionState &operator=(DirectSubmissionState &&other) = delete; DirectSubmissionState &operator=(DirectSubmissionState &&other) = delete;
std::atomic_bool isActive{false};
std::atomic_bool isStopped{true}; std::atomic_bool isStopped{true};
std::atomic<TaskCountType> taskCount{0}; std::atomic<TaskCountType> taskCount{0};
}; };
static void *controlDirectSubmissionsState(void *self); static void *controlDirectSubmissionsState(void *self);
MOCKABLE_VIRTUAL void checkNewSubmissions(); void checkNewSubmissions();
bool isDirectSubmissionIdle(CommandStreamReceiver *csr, std::unique_lock<std::recursive_mutex> &csrLock); bool isDirectSubmissionIdle(CommandStreamReceiver *csr, std::unique_lock<std::recursive_mutex> &csrLock);
bool isCopyEngineOnDeviceIdle(uint32_t rootDeviceIndex, std::optional<TaskCountType> &bcsTaskCount); bool isCopyEngineOnDeviceIdle(uint32_t rootDeviceIndex, std::optional<TaskCountType> &bcsTaskCount);
MOCKABLE_VIRTUAL bool sleep(std::unique_lock<std::mutex> &lock); MOCKABLE_VIRTUAL bool sleep(std::unique_lock<std::mutex> &lock);
bool waitPredicate() { return !keepControlling || !pagingFenceRequests.empty() || activeSubmissionsCount; }
MOCKABLE_VIRTUAL void wait(std::unique_lock<std::mutex> &lock) {
condVar.wait(lock, [&]() { return waitPredicate(); });
}
MOCKABLE_VIRTUAL SteadyClock::time_point getCpuTimestamp(); MOCKABLE_VIRTUAL SteadyClock::time_point getCpuTimestamp();
MOCKABLE_VIRTUAL void overrideDirectSubmissionTimeouts(const ProductHelper &productHelper); MOCKABLE_VIRTUAL void overrideDirectSubmissionTimeouts(const ProductHelper &productHelper);
@@ -114,7 +107,7 @@ class DirectSubmissionController {
void updateLastSubmittedThrottle(QueueThrottle throttle); void updateLastSubmittedThrottle(QueueThrottle throttle);
size_t getTimeoutParamsMapKey(QueueThrottle throttle, bool acLineStatus); size_t getTimeoutParamsMapKey(QueueThrottle throttle, bool acLineStatus);
MOCKABLE_VIRTUAL void handlePagingFenceRequests(std::unique_lock<std::mutex> &lock); void handlePagingFenceRequests(std::unique_lock<std::mutex> &lock, bool checkForNewSubmissions);
MOCKABLE_VIRTUAL TimeoutElapsedMode timeoutElapsed(); MOCKABLE_VIRTUAL TimeoutElapsedMode timeoutElapsed();
std::chrono::microseconds getSleepValue() const { return std::chrono::microseconds(this->timeout / this->bcsTimeoutDivisor); } std::chrono::microseconds getSleepValue() const { return std::chrono::microseconds(this->timeout / this->bcsTimeoutDivisor); }
@@ -125,7 +118,7 @@ class DirectSubmissionController {
std::unique_ptr<Thread> directSubmissionControllingThread; std::unique_ptr<Thread> directSubmissionControllingThread;
std::atomic_bool keepControlling = true; std::atomic_bool keepControlling = true;
std::atomic_uint activeSubmissionsCount = 0; std::atomic_bool runControlling = false;
SteadyClock::time_point timeSinceLastCheck{}; SteadyClock::time_point timeSinceLastCheck{};
SteadyClock::time_point lastTerminateCpuTimestamp{}; SteadyClock::time_point lastTerminateCpuTimestamp{};
@@ -143,4 +136,4 @@ class DirectSubmissionController {
std::queue<WaitForPagingFenceRequest> pagingFenceRequests; std::queue<WaitForPagingFenceRequest> pagingFenceRequests;
}; };
} // namespace NEO } // namespace NEO

View File

@@ -10,7 +10,7 @@
#include "shared/source/command_stream/command_stream_receiver.h" #include "shared/source/command_stream/command_stream_receiver.h"
namespace NEO { namespace NEO {
DirectSubmissionInputParams::DirectSubmissionInputParams(const CommandStreamReceiver &commandStreamReceiver) : csr(commandStreamReceiver), osContext(commandStreamReceiver.getOsContext()), rootDeviceEnvironment(commandStreamReceiver.peekRootDeviceEnvironment()), rootDeviceIndex(commandStreamReceiver.getRootDeviceIndex()) { DirectSubmissionInputParams::DirectSubmissionInputParams(const CommandStreamReceiver &commandStreamReceiver) : osContext(commandStreamReceiver.getOsContext()), rootDeviceEnvironment(commandStreamReceiver.peekRootDeviceEnvironment()), rootDeviceIndex(commandStreamReceiver.getRootDeviceIndex()) {
memoryManager = commandStreamReceiver.getMemoryManager(); memoryManager = commandStreamReceiver.getMemoryManager();
globalFenceAllocation = commandStreamReceiver.getGlobalFenceAllocation(); globalFenceAllocation = commandStreamReceiver.getGlobalFenceAllocation();
workPartitionAllocation = commandStreamReceiver.getWorkPartitionAllocation(); workPartitionAllocation = commandStreamReceiver.getWorkPartitionAllocation();

View File

@@ -50,7 +50,6 @@ class MemoryOperationsHandler;
struct DirectSubmissionInputParams : NonCopyableClass { struct DirectSubmissionInputParams : NonCopyableClass {
DirectSubmissionInputParams(const CommandStreamReceiver &commandStreamReceiver); DirectSubmissionInputParams(const CommandStreamReceiver &commandStreamReceiver);
const CommandStreamReceiver &csr;
OsContext &osContext; OsContext &osContext;
const RootDeviceEnvironment &rootDeviceEnvironment; const RootDeviceEnvironment &rootDeviceEnvironment;
MemoryManager *memoryManager = nullptr; MemoryManager *memoryManager = nullptr;
@@ -223,7 +222,6 @@ class DirectSubmissionHw {
uint64_t gpuVaForPagingFenceSemaphore = 0u; uint64_t gpuVaForPagingFenceSemaphore = 0u;
uint64_t relaxedOrderingQueueSizeLimitValueVa = 0; uint64_t relaxedOrderingQueueSizeLimitValueVa = 0;
const CommandStreamReceiver &csr;
OsContext &osContext; OsContext &osContext;
const uint32_t rootDeviceIndex; const uint32_t rootDeviceIndex;
MemoryManager *memoryManager = nullptr; MemoryManager *memoryManager = nullptr;

View File

@@ -10,7 +10,6 @@
#include "shared/source/command_stream/submissions_aggregator.h" #include "shared/source/command_stream/submissions_aggregator.h"
#include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/device/device.h" #include "shared/source/device/device.h"
#include "shared/source/direct_submission/direct_submission_controller.h"
#include "shared/source/direct_submission/direct_submission_hw.h" #include "shared/source/direct_submission/direct_submission_hw.h"
#include "shared/source/direct_submission/relaxed_ordering_helper.h" #include "shared/source/direct_submission/relaxed_ordering_helper.h"
#include "shared/source/execution_environment/execution_environment.h" #include "shared/source/execution_environment/execution_environment.h"
@@ -41,7 +40,7 @@ namespace NEO {
template <typename GfxFamily, typename Dispatcher> template <typename GfxFamily, typename Dispatcher>
DirectSubmissionHw<GfxFamily, Dispatcher>::DirectSubmissionHw(const DirectSubmissionInputParams &inputParams) DirectSubmissionHw<GfxFamily, Dispatcher>::DirectSubmissionHw(const DirectSubmissionInputParams &inputParams)
: ringBuffers(RingBufferUse::initialRingBufferCount), csr(inputParams.csr), osContext(inputParams.osContext), rootDeviceIndex(inputParams.rootDeviceIndex), rootDeviceEnvironment(inputParams.rootDeviceEnvironment) { : ringBuffers(RingBufferUse::initialRingBufferCount), osContext(inputParams.osContext), rootDeviceIndex(inputParams.rootDeviceIndex), rootDeviceEnvironment(inputParams.rootDeviceEnvironment) {
memoryManager = inputParams.memoryManager; memoryManager = inputParams.memoryManager;
globalFenceAllocation = inputParams.globalFenceAllocation; globalFenceAllocation = inputParams.globalFenceAllocation;
hwInfo = inputParams.rootDeviceEnvironment.getHardwareInfo(); hwInfo = inputParams.rootDeviceEnvironment.getHardwareInfo();
@@ -589,9 +588,6 @@ template <typename GfxFamily, typename Dispatcher>
bool DirectSubmissionHw<GfxFamily, Dispatcher>::submitCommandBufferToGpu(bool needStart, uint64_t gpuAddress, size_t size, bool needWait, const ResidencyContainer *allocationsForResidency) { bool DirectSubmissionHw<GfxFamily, Dispatcher>::submitCommandBufferToGpu(bool needStart, uint64_t gpuAddress, size_t size, bool needWait, const ResidencyContainer *allocationsForResidency) {
if (needStart) { if (needStart) {
this->ringStart = this->submit(gpuAddress, size, allocationsForResidency); this->ringStart = this->submit(gpuAddress, size, allocationsForResidency);
if (auto controller = rootDeviceEnvironment.executionEnvironment.directSubmissionController.get()) {
controller->notifyNewSubmission(&csr);
}
return this->ringStart; return this->ringStart;
} else { } else {
if (needWait) { if (needWait) {

View File

@@ -68,7 +68,7 @@ bool SVMAllocsManager::SvmAllocationCache::insert(size_t size, void *ptr, SvmAll
return false; return false;
} }
std::unique_lock<std::mutex> lock(this->mtx); std::lock_guard<std::mutex> lock(this->mtx);
if (svmData->device ? svmData->device->shouldLimitAllocationsReuse() : memoryManager->shouldLimitAllocationsReuse()) { if (svmData->device ? svmData->device->shouldLimitAllocationsReuse() : memoryManager->shouldLimitAllocationsReuse()) {
return false; return false;
} }
@@ -100,11 +100,8 @@ bool SVMAllocsManager::SvmAllocationCache::insert(size_t size, void *ptr, SvmAll
} }
svmData->isSavedForReuse = true; svmData->isSavedForReuse = true;
allocations.emplace(std::lower_bound(allocations.begin(), allocations.end(), size), size, ptr, svmData, waitForCompletion); allocations.emplace(std::lower_bound(allocations.begin(), allocations.end(), size), size, ptr, svmData, waitForCompletion);
empty = false; if (memoryManager->peekExecutionEnvironment().unifiedMemoryReuseCleaner) {
if (auto usmReuseCleaner = this->memoryManager->peekExecutionEnvironment().unifiedMemoryReuseCleaner.get()) { memoryManager->peekExecutionEnvironment().unifiedMemoryReuseCleaner->startThread();
lock.unlock();
usmReuseCleaner->startThread();
usmReuseCleaner->notifySvmAllocationsCacheUpdate();
} }
} }
if (enablePerformanceLogging) { if (enablePerformanceLogging) {
@@ -114,7 +111,6 @@ bool SVMAllocsManager::SvmAllocationCache::insert(size_t size, void *ptr, SvmAll
.operationType = CacheOperationType::insert, .operationType = CacheOperationType::insert,
.isSuccess = isSuccess}); .isSuccess = isSuccess});
} }
return isSuccess; return isSuccess;
} }
@@ -186,7 +182,6 @@ void *SVMAllocsManager::SvmAllocationCache::get(size_t size, const UnifiedMemory
svmAllocsManager->reinsertToAllocsForIndirectAccess(*allocationIter->svmData); svmAllocsManager->reinsertToAllocsForIndirectAccess(*allocationIter->svmData);
} }
allocations.erase(allocationIter); allocations.erase(allocationIter);
empty = allocations.empty();
return allocationPtr; return allocationPtr;
} }
} }
@@ -221,7 +216,6 @@ void SVMAllocsManager::SvmAllocationCache::trim() {
svmAllocsManager->freeSVMAllocImpl(cachedAllocationInfo.allocation, FreePolicyType::blocking, cachedAllocationInfo.svmData); svmAllocsManager->freeSVMAllocImpl(cachedAllocationInfo.allocation, FreePolicyType::blocking, cachedAllocationInfo.svmData);
} }
this->allocations.clear(); this->allocations.clear();
empty = true;
} }
void SVMAllocsManager::SvmAllocationCache::cleanup() { void SVMAllocsManager::SvmAllocationCache::cleanup() {
@@ -306,7 +300,6 @@ void SVMAllocsManager::SvmAllocationCache::trimOldAllocs(std::chrono::high_resol
if (trimAll) { if (trimAll) {
std::erase_if(allocations, SvmCacheAllocationInfo::isMarkedForDelete); std::erase_if(allocations, SvmCacheAllocationInfo::isMarkedForDelete);
} }
empty = allocations.empty();
} }
SvmAllocationData *SVMAllocsManager::MapBasedAllocationTracker::get(const void *ptr) { SvmAllocationData *SVMAllocsManager::MapBasedAllocationTracker::get(const void *ptr) {

View File

@@ -221,7 +221,6 @@ class SVMAllocsManager {
static bool allocUtilizationAllows(size_t requestedSize, size_t reuseCandidateSize); static bool allocUtilizationAllows(size_t requestedSize, size_t reuseCandidateSize);
static bool alignmentAllows(void *ptr, size_t alignment); static bool alignmentAllows(void *ptr, size_t alignment);
bool isInUse(SvmCacheAllocationInfo &cacheAllocInfo); bool isInUse(SvmCacheAllocationInfo &cacheAllocInfo);
bool isEmpty() { return empty; };
void *get(size_t size, const UnifiedMemoryProperties &unifiedMemoryProperties); void *get(size_t size, const UnifiedMemoryProperties &unifiedMemoryProperties);
void trim(); void trim();
void trimOldAllocs(std::chrono::high_resolution_clock::time_point trimTimePoint, bool trimAll); void trimOldAllocs(std::chrono::high_resolution_clock::time_point trimTimePoint, bool trimAll);
@@ -235,7 +234,6 @@ class SVMAllocsManager {
MemoryManager *memoryManager = nullptr; MemoryManager *memoryManager = nullptr;
bool enablePerformanceLogging = false; bool enablePerformanceLogging = false;
bool requireUpdatingAllocsForIndirectAccess = false; bool requireUpdatingAllocsForIndirectAccess = false;
std::atomic_bool empty = true;
}; };
enum class FreePolicyType : uint32_t { enum class FreePolicyType : uint32_t {

View File

@@ -23,11 +23,8 @@ UnifiedMemoryReuseCleaner::~UnifiedMemoryReuseCleaner() {
} }
void UnifiedMemoryReuseCleaner::stopThread() { void UnifiedMemoryReuseCleaner::stopThread() {
{ keepCleaning.store(false);
std::lock_guard<std::mutex> lock(condVarMutex); runCleaning.store(false);
keepCleaning.store(false);
condVar.notify_one();
}
if (unifiedMemoryReuseCleanerThread) { if (unifiedMemoryReuseCleanerThread) {
unifiedMemoryReuseCleanerThread->join(); unifiedMemoryReuseCleanerThread->join();
unifiedMemoryReuseCleanerThread.reset(); unifiedMemoryReuseCleanerThread.reset();
@@ -36,24 +33,26 @@ void UnifiedMemoryReuseCleaner::stopThread() {
void *UnifiedMemoryReuseCleaner::cleanUnifiedMemoryReuse(void *self) { void *UnifiedMemoryReuseCleaner::cleanUnifiedMemoryReuse(void *self) {
auto cleaner = reinterpret_cast<UnifiedMemoryReuseCleaner *>(self); auto cleaner = reinterpret_cast<UnifiedMemoryReuseCleaner *>(self);
while (cleaner->keepCleaning.load()) { while (!cleaner->runCleaning.load()) {
std::unique_lock lock(cleaner->condVarMutex); if (!cleaner->keepCleaning.load()) {
cleaner->wait(lock); return nullptr;
lock.unlock(); }
cleaner->trimOldInCaches();
NEO::sleep(sleepTime); NEO::sleep(sleepTime);
} }
return nullptr;
}
void UnifiedMemoryReuseCleaner::notifySvmAllocationsCacheUpdate() { while (true) {
std::lock_guard<std::mutex> lock(condVarMutex); if (!cleaner->keepCleaning.load()) {
condVar.notify_one(); return nullptr;
}
NEO::sleep(sleepTime);
cleaner->trimOldInCaches();
}
} }
void UnifiedMemoryReuseCleaner::registerSvmAllocationCache(SvmAllocationCache *cache) { void UnifiedMemoryReuseCleaner::registerSvmAllocationCache(SvmAllocationCache *cache) {
std::lock_guard<std::mutex> lockSvmAllocationCaches(this->svmAllocationCachesMutex); std::lock_guard<std::mutex> lockSvmAllocationCaches(this->svmAllocationCachesMutex);
this->svmAllocationCaches.push_back(cache); this->svmAllocationCaches.push_back(cache);
this->startCleaning();
} }
void UnifiedMemoryReuseCleaner::unregisterSvmAllocationCache(SvmAllocationCache *cache) { void UnifiedMemoryReuseCleaner::unregisterSvmAllocationCache(SvmAllocationCache *cache) {
@@ -86,4 +85,4 @@ void UnifiedMemoryReuseCleaner::startThread() {
}); });
} }
} // namespace NEO } // namespace NEO

View File

@@ -11,7 +11,6 @@
#include "shared/source/memory_manager/unified_memory_manager.h" #include "shared/source/memory_manager/unified_memory_manager.h"
#include <chrono> #include <chrono>
#include <condition_variable>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
@@ -34,17 +33,9 @@ class UnifiedMemoryReuseCleaner : NEO::NonCopyableAndNonMovableClass {
void registerSvmAllocationCache(SvmAllocationCache *cache); void registerSvmAllocationCache(SvmAllocationCache *cache);
void unregisterSvmAllocationCache(SvmAllocationCache *cache); void unregisterSvmAllocationCache(SvmAllocationCache *cache);
bool waitPredicate() { return !keepCleaning || !isEmpty(); };
MOCKABLE_VIRTUAL void wait(std::unique_lock<std::mutex> &lock) {
condVar.wait(lock, [&]() { return waitPredicate(); });
}
MOCKABLE_VIRTUAL bool isEmpty() {
std::unique_lock<std::mutex> lock(svmAllocationCachesMutex);
return std::all_of(svmAllocationCaches.begin(), svmAllocationCaches.end(), [](const auto &it) { return it->isEmpty(); });
}
void notifySvmAllocationsCacheUpdate();
protected: protected:
void startCleaning() { runCleaning.store(true); };
static void *cleanUnifiedMemoryReuse(void *self); static void *cleanUnifiedMemoryReuse(void *self);
MOCKABLE_VIRTUAL void trimOldInCaches(); MOCKABLE_VIRTUAL void trimOldInCaches();
std::unique_ptr<Thread> unifiedMemoryReuseCleanerThread; std::unique_ptr<Thread> unifiedMemoryReuseCleanerThread;
@@ -53,8 +44,7 @@ class UnifiedMemoryReuseCleaner : NEO::NonCopyableAndNonMovableClass {
std::mutex svmAllocationCachesMutex; std::mutex svmAllocationCachesMutex;
std::once_flag startThreadOnce; std::once_flag startThreadOnce;
std::mutex condVarMutex; std::atomic_bool runCleaning = false;
std::condition_variable condVar;
std::atomic_bool keepCleaning = true; std::atomic_bool keepCleaning = true;
bool trimAllAllocations = false; bool trimAllAllocations = false;

View File

@@ -71,11 +71,7 @@ bool WddmResidencyController::makeResidentResidencyAllocations(ResidencyContaine
uint64_t bytesToTrim = 0; uint64_t bytesToTrim = 0;
while ((result = wddm.makeResident(handlesForResidency.data(), static_cast<uint32_t>(handlesForResidency.size()), false, &bytesToTrim, totalSize)) == false) { while ((result = wddm.makeResident(handlesForResidency.data(), static_cast<uint32_t>(handlesForResidency.size()), false, &bytesToTrim, totalSize)) == false) {
this->setMemoryBudgetExhausted(); this->setMemoryBudgetExhausted();
bool trimmingDone = this->trimResidencyToBudget(bytesToTrim); const bool trimmingDone = this->trimResidencyToBudget(bytesToTrim);
if (!trimmingDone && csr) {
csr->stopDirectSubmission(false, false);
trimmingDone = this->trimResidencyToBudget(bytesToTrim);
}
allocationsForResidency = backupResidencyContainer; allocationsForResidency = backupResidencyContainer;
if (!trimmingDone) { if (!trimmingDone) {
auto evictionStatus = wddm.getTemporaryResourcesContainer()->evictAllResources(); auto evictionStatus = wddm.getTemporaryResourcesContainer()->evictAllResources();

View File

@@ -40,7 +40,7 @@ class WddmResidencyController {
void registerCallback(); void registerCallback();
void trimResidency(const D3DDDI_TRIMRESIDENCYSET_FLAGS &flags, uint64_t bytes); void trimResidency(const D3DDDI_TRIMRESIDENCYSET_FLAGS &flags, uint64_t bytes);
MOCKABLE_VIRTUAL bool trimResidencyToBudget(uint64_t bytes); bool trimResidencyToBudget(uint64_t bytes);
bool isMemoryBudgetExhausted() const { return memoryBudgetExhausted; } bool isMemoryBudgetExhausted() const { return memoryBudgetExhausted; }
void setMemoryBudgetExhausted() { memoryBudgetExhausted = true; } void setMemoryBudgetExhausted() { memoryBudgetExhausted = true; }

View File

@@ -11,6 +11,7 @@ namespace NEO {
struct MockUnifiedMemoryReuseCleaner : public UnifiedMemoryReuseCleaner { struct MockUnifiedMemoryReuseCleaner : public UnifiedMemoryReuseCleaner {
public: public:
using UnifiedMemoryReuseCleaner::keepCleaning; using UnifiedMemoryReuseCleaner::keepCleaning;
using UnifiedMemoryReuseCleaner::runCleaning;
using UnifiedMemoryReuseCleaner::svmAllocationCaches; using UnifiedMemoryReuseCleaner::svmAllocationCaches;
using UnifiedMemoryReuseCleaner::UnifiedMemoryReuseCleaner; using UnifiedMemoryReuseCleaner::UnifiedMemoryReuseCleaner;
using UnifiedMemoryReuseCleaner::unifiedMemoryReuseCleanerThread; using UnifiedMemoryReuseCleaner::unifiedMemoryReuseCleanerThread;
@@ -19,8 +20,6 @@ struct MockUnifiedMemoryReuseCleaner : public UnifiedMemoryReuseCleaner {
trimOldInCachesCalled = true; trimOldInCachesCalled = true;
if (callBaseTrimOldInCaches) { if (callBaseTrimOldInCaches) {
UnifiedMemoryReuseCleaner::trimOldInCaches(); UnifiedMemoryReuseCleaner::trimOldInCaches();
} else {
clearCaches();
} }
} }
bool trimOldInCachesCalled = false; bool trimOldInCachesCalled = false;
@@ -32,21 +31,6 @@ struct MockUnifiedMemoryReuseCleaner : public UnifiedMemoryReuseCleaner {
UnifiedMemoryReuseCleaner::startThread(); UnifiedMemoryReuseCleaner::startThread();
} }
}; };
void wait(std::unique_lock<std::mutex> &lock) override {
waitOnConditionVar.store(!waitPredicate());
UnifiedMemoryReuseCleaner::wait(lock);
};
void waitTillSleep() {
do {
std::this_thread::yield();
std::lock_guard<std::mutex> lock(condVarMutex);
} while (!waitOnConditionVar.load());
}
void clearCaches() {
std::lock_guard<std::mutex> lock(svmAllocationCachesMutex);
svmAllocationCaches.clear();
}
std::atomic_bool waitOnConditionVar = false;
bool startThreadCalled = false; bool startThreadCalled = false;
bool callBaseStartThread = false; bool callBaseStartThread = false;
@@ -56,4 +40,4 @@ struct MockUnifiedMemoryReuseCleaner : public UnifiedMemoryReuseCleaner {
}; };
bool stopThreadCalled = false; bool stopThreadCalled = false;
}; };
} // namespace NEO } // namespace NEO

View File

@@ -24,12 +24,5 @@ class MockWddmResidencyController : public WddmResidencyController {
acquireLockCallCount++; acquireLockCallCount++;
return WddmResidencyController::acquireLock(); return WddmResidencyController::acquireLock();
} }
uint32_t trimResidencyToBudgetCallCount = 0;
bool trimResidencyToBudget(uint64_t bytes) override {
++trimResidencyToBudgetCallCount;
return WddmResidencyController::trimResidencyToBudget(bytes);
}
}; };
} // namespace NEO } // namespace NEO

View File

@@ -1153,7 +1153,12 @@ class CommandStreamReceiverHwDirectSubmissionMock : public CommandStreamReceiver
return CommandStreamReceiverHw<Type>::obtainUniqueOwnership(); return CommandStreamReceiverHw<Type>::obtainUniqueOwnership();
} }
void startControllingDirectSubmissions() override {
startControllingDirectSubmissionsCalled = true;
}
uint32_t recursiveLockCounter = 0; uint32_t recursiveLockCounter = 0;
bool startControllingDirectSubmissionsCalled = false;
}; };
HWTEST_F(InitDirectSubmissionTest, whenCallInitDirectSubmissionAgainThenItIsNotReinitialized) { HWTEST_F(InitDirectSubmissionTest, whenCallInitDirectSubmissionAgainThenItIsNotReinitialized) {
@@ -1184,7 +1189,7 @@ HWTEST_F(InitDirectSubmissionTest, whenCallInitDirectSubmissionAgainThenItIsNotR
csr.reset(); csr.reset();
} }
HWTEST_F(InitDirectSubmissionTest, whenCallInitDirectSubmissionThenObtainLock) { HWTEST_F(InitDirectSubmissionTest, whenCallInitDirectSubmissionThenObtainLockAndInitController) {
auto csr = std::make_unique<CommandStreamReceiverHwDirectSubmissionMock<FamilyType>>(*device->executionEnvironment, device->getRootDeviceIndex(), device->getDeviceBitfield()); auto csr = std::make_unique<CommandStreamReceiverHwDirectSubmissionMock<FamilyType>>(*device->executionEnvironment, device->getRootDeviceIndex(), device->getDeviceBitfield());
std::unique_ptr<OsContext> osContext(OsContext::create(device->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.get(), device->getRootDeviceIndex(), 0, std::unique_ptr<OsContext> osContext(OsContext::create(device->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.get(), device->getRootDeviceIndex(), 0,
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::regular}, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::regular},
@@ -1198,6 +1203,7 @@ HWTEST_F(InitDirectSubmissionTest, whenCallInitDirectSubmissionThenObtainLock) {
csr->initializeTagAllocation(); csr->initializeTagAllocation();
csr->initDirectSubmission(); csr->initDirectSubmission();
EXPECT_EQ(1u, csr->recursiveLockCounter); EXPECT_EQ(1u, csr->recursiveLockCounter);
EXPECT_TRUE(csr->startControllingDirectSubmissionsCalled);
csr.reset(); csr.reset();
} }
@@ -6194,7 +6200,7 @@ HWTEST_F(CommandStreamReceiverTest, givenCommandStreamReceiverWhenEnqueueWaitFor
std::mutex mtx; std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx); std::unique_lock<std::mutex> lock(mtx);
csr.directSubmissionAvailable = false; csr.directSubmissionAvailable = false;
controller->handlePagingFenceRequests(lock); controller->handlePagingFenceRequests(lock, false);
EXPECT_EQ(10u, csr.pagingFenceValueToUnblock); EXPECT_EQ(10u, csr.pagingFenceValueToUnblock);
} }

View File

@@ -31,18 +31,6 @@ struct DirectSubmissionControllerMock : public DirectSubmissionController {
using DirectSubmissionController::timeoutDivisor; using DirectSubmissionController::timeoutDivisor;
using DirectSubmissionController::timeSinceLastCheck; using DirectSubmissionController::timeSinceLastCheck;
void wait(std::unique_lock<std::mutex> &lock) override {
waitOnConditionVar.store(!waitPredicate());
DirectSubmissionController::wait(lock);
}
void waitTillSleep() {
do {
std::this_thread::yield();
std::lock_guard<std::mutex> lock(condVarMutex);
} while (!waitOnConditionVar.load());
}
bool sleep(std::unique_lock<std::mutex> &lock) override { bool sleep(std::unique_lock<std::mutex> &lock) override {
this->sleepCalled = true; this->sleepCalled = true;
if (callBaseSleepMethod) { if (callBaseSleepMethod) {
@@ -54,16 +42,6 @@ struct DirectSubmissionControllerMock : public DirectSubmissionController {
} }
} }
void handlePagingFenceRequests(std::unique_lock<std::mutex> &lock) override {
handlePagingFenceRequestsCalled = true;
DirectSubmissionController::handlePagingFenceRequests(lock);
}
void checkNewSubmissions() override {
checkNewSubmissionCalled.store(true);
DirectSubmissionController::checkNewSubmissions();
}
SteadyClock::time_point getCpuTimestamp() override { SteadyClock::time_point getCpuTimestamp() override {
return cpuTimestamp; return cpuTimestamp;
} }
@@ -77,13 +55,10 @@ struct DirectSubmissionControllerMock : public DirectSubmissionController {
} }
SteadyClock::time_point cpuTimestamp{}; SteadyClock::time_point cpuTimestamp{};
std::atomic<bool> waitOnConditionVar{false};
std::atomic<bool> sleepCalled{false}; std::atomic<bool> sleepCalled{false};
std::atomic<bool> sleepReturnValue{false}; std::atomic<bool> sleepReturnValue{false};
std::atomic<TimeoutElapsedMode> timeoutElapsedReturnValue{TimeoutElapsedMode::notElapsed}; std::atomic<TimeoutElapsedMode> timeoutElapsedReturnValue{TimeoutElapsedMode::notElapsed};
std::atomic<bool> timeoutElapsedCallBase{false}; std::atomic<bool> timeoutElapsedCallBase{false};
std::atomic<bool> checkNewSubmissionCalled{false};
std::atomic<bool> handlePagingFenceRequestsCalled{false};
bool callBaseSleepMethod = false; bool callBaseSleepMethod = false;
}; };
} // namespace NEO } // namespace NEO

View File

@@ -46,13 +46,11 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenRegiste
DirectSubmissionControllerMock controller; DirectSubmissionControllerMock controller;
controller.timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed); controller.timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed);
controller.registerDirectSubmission(&csr); controller.registerDirectSubmission(&csr);
controller.notifyNewSubmission(&csr);
controller.checkNewSubmissions(); controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped); EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 5u); EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 5u);
csr.taskCount.store(6u); csr.taskCount.store(6u);
controller.notifyNewSubmission(&csr);
controller.checkNewSubmissions(); controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped); EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 6u); EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 6u);
@@ -66,7 +64,6 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenRegiste
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 6u); EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 6u);
csr.taskCount.store(8u); csr.taskCount.store(8u);
controller.notifyNewSubmission(&csr);
controller.checkNewSubmissions(); controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped); EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 8u); EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 8u);
@@ -133,8 +130,6 @@ TEST(DirectSubmissionControllerTests, givenDebugFlagSetWhenCheckingNewSubmission
controller.timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed); controller.timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed);
controller.registerDirectSubmission(&bcsCsr); controller.registerDirectSubmission(&bcsCsr);
controller.registerDirectSubmission(&ccsCsr); controller.registerDirectSubmission(&ccsCsr);
controller.notifyNewSubmission(&bcsCsr);
controller.notifyNewSubmission(&ccsCsr);
controller.checkNewSubmissions(); controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&bcsCsr].isStopped); EXPECT_FALSE(controller.directSubmissions[&bcsCsr].isStopped);
@@ -148,8 +143,6 @@ TEST(DirectSubmissionControllerTests, givenDebugFlagSetWhenCheckingNewSubmission
bcsCsr.taskCount.store(6u); bcsCsr.taskCount.store(6u);
ccsCsr.taskCount.store(6u); ccsCsr.taskCount.store(6u);
controller.notifyNewSubmission(&bcsCsr);
controller.notifyNewSubmission(&ccsCsr);
controller.checkNewSubmissions(); controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&bcsCsr].isStopped); EXPECT_FALSE(controller.directSubmissions[&bcsCsr].isStopped);
EXPECT_EQ(controller.directSubmissions[&bcsCsr].taskCount, 6u); EXPECT_EQ(controller.directSubmissions[&bcsCsr].taskCount, 6u);
@@ -187,7 +180,6 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenIncreas
controller.registerDirectSubmission(&csr); controller.registerDirectSubmission(&csr);
{ {
csr.taskCount.store(1u); csr.taskCount.store(1u);
controller.notifyNewSubmission(&csr);
controller.checkNewSubmissions(); controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped); EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 1u); EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 1u);
@@ -203,7 +195,6 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenIncreas
} }
{ {
csr.taskCount.store(2u); csr.taskCount.store(2u);
controller.notifyNewSubmission(&csr);
controller.checkNewSubmissions(); controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped); EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 2u); EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 2u);
@@ -218,7 +209,6 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenIncreas
} }
{ {
csr.taskCount.store(3u); csr.taskCount.store(3u);
controller.notifyNewSubmission(&csr);
controller.checkNewSubmissions(); controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped); EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 3u); EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 3u);
@@ -234,7 +224,6 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenIncreas
{ {
controller.timeout = std::chrono::microseconds(5'000); controller.timeout = std::chrono::microseconds(5'000);
csr.taskCount.store(4u); csr.taskCount.store(4u);
controller.notifyNewSubmission(&csr);
controller.checkNewSubmissions(); controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped); EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 4u); EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 4u);
@@ -274,12 +263,12 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenEnqueue
EXPECT_EQ(request.pagingFenceValue, 10u); EXPECT_EQ(request.pagingFenceValue, 10u);
std::mutex mtx; std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx); std::unique_lock<std::mutex> lock(mtx);
controller.handlePagingFenceRequests(lock); controller.handlePagingFenceRequests(lock, false);
EXPECT_EQ(10u, csr.pagingFenceValueToUnblock); EXPECT_EQ(10u, csr.pagingFenceValueToUnblock);
// Do nothing when queue is empty // Do nothing when queue is empty
csr.pagingFenceValueToUnblock = 0u; csr.pagingFenceValueToUnblock = 0u;
controller.handlePagingFenceRequests(lock); controller.handlePagingFenceRequests(lock, false);
EXPECT_EQ(0u, csr.pagingFenceValueToUnblock); EXPECT_EQ(0u, csr.pagingFenceValueToUnblock);
} }
@@ -304,7 +293,7 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenDrainPa
EXPECT_EQ(10u, csr.pagingFenceValueToUnblock); EXPECT_EQ(10u, csr.pagingFenceValueToUnblock);
} }
TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenEnqueueWaitForPagingFenceThenDoNotCheckSubmissions) { TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenEnqueueWaitForPagingFenceWithCheckSubmissionsThenCheckSubmissions) {
MockExecutionEnvironment executionEnvironment; MockExecutionEnvironment executionEnvironment;
executionEnvironment.prepareRootDeviceEnvironments(1); executionEnvironment.prepareRootDeviceEnvironments(1);
executionEnvironment.initializeMemoryManager(); executionEnvironment.initializeMemoryManager();
@@ -327,14 +316,13 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenEnqueue
csr.taskCount.store(5u); csr.taskCount.store(5u);
controller.registerDirectSubmission(&csr); controller.registerDirectSubmission(&csr);
controller.notifyNewSubmission(&csr);
std::mutex mtx; std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx); std::unique_lock<std::mutex> lock(mtx);
controller.timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed); controller.timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed);
controller.handlePagingFenceRequests(lock); controller.handlePagingFenceRequests(lock, true);
EXPECT_EQ(10u, csr.pagingFenceValueToUnblock); EXPECT_EQ(10u, csr.pagingFenceValueToUnblock);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 0u); EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 5u);
} }
TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenCheckTimeoutElapsedThenReturnCorrectValue) { TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWhenCheckTimeoutElapsedThenReturnCorrectValue) {
@@ -384,7 +372,6 @@ struct DirectSubmissionIdleDetectionTests : public ::testing::Test {
controller->timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed); controller->timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed);
controller->registerDirectSubmission(csr.get()); controller->registerDirectSubmission(csr.get());
csr->taskCount.store(10u); csr->taskCount.store(10u);
controller->notifyNewSubmission(csr.get());
controller->checkNewSubmissions(); controller->checkNewSubmissions();
} }
@@ -461,7 +448,6 @@ TEST_F(DirectSubmissionIdleDetectionTests, givenDebugFlagSetWhenTaskCountNotUpda
controller->registerDirectSubmission(csr.get()); controller->registerDirectSubmission(csr.get());
csr->taskCount.store(10u); csr->taskCount.store(10u);
controller->notifyNewSubmission(csr.get());
controller->checkNewSubmissions(); controller->checkNewSubmissions();
csr->setLatestFlushedTaskCount(10u); csr->setLatestFlushedTaskCount(10u);
csr->isBusyReturnValue = true; csr->isBusyReturnValue = true;
@@ -623,8 +609,6 @@ struct DirectSubmissionCheckForCopyEngineIdleTests : public ::testing::Test {
controller->registerDirectSubmission(bcsCsr.get()); controller->registerDirectSubmission(bcsCsr.get());
bcsCsr->taskCount.store(10u); bcsCsr->taskCount.store(10u);
ccsCsr->taskCount.store(10u); ccsCsr->taskCount.store(10u);
controller->notifyNewSubmission(ccsCsr.get());
controller->notifyNewSubmission(bcsCsr.get());
controller->checkNewSubmissions(); controller->checkNewSubmissions();
} }
@@ -651,8 +635,6 @@ TEST_F(DirectSubmissionCheckForCopyEngineIdleTests, givenCheckBcsForDirectSubmis
ccsCsr->isBusyReturnValue = false; ccsCsr->isBusyReturnValue = false;
bcsCsr->isBusyReturnValue = true; bcsCsr->isBusyReturnValue = true;
controller->directSubmissions[bcsCsr.get()].isStopped = false; controller->directSubmissions[bcsCsr.get()].isStopped = false;
controller->notifyNewSubmission(ccsCsr.get());
controller->notifyNewSubmission(bcsCsr.get());
controller->checkNewSubmissions(); controller->checkNewSubmissions();
EXPECT_EQ(controller->directSubmissions[ccsCsr.get()].taskCount, 10u); EXPECT_EQ(controller->directSubmissions[ccsCsr.get()].taskCount, 10u);
@@ -693,7 +675,6 @@ TEST_F(DirectSubmissionCheckForCopyEngineIdleTests, givenCheckBcsForDirectSubmis
secondDeviceCsr.setupContext(*osContext); secondDeviceCsr.setupContext(*osContext);
controller->registerDirectSubmission(&secondDeviceCsr); controller->registerDirectSubmission(&secondDeviceCsr);
secondDeviceCsr.taskCount.store(10u); secondDeviceCsr.taskCount.store(10u);
controller->notifyNewSubmission(&secondDeviceCsr);
controller->checkNewSubmissions(); controller->checkNewSubmissions();
secondDeviceCsr.setLatestFlushedTaskCount(10u); secondDeviceCsr.setLatestFlushedTaskCount(10u);
@@ -702,7 +683,6 @@ TEST_F(DirectSubmissionCheckForCopyEngineIdleTests, givenCheckBcsForDirectSubmis
secondDeviceCsr.isBusyReturnValue = false; secondDeviceCsr.isBusyReturnValue = false;
bcsCsr->isBusyReturnValue = true; bcsCsr->isBusyReturnValue = true;
controller->directSubmissions[bcsCsr.get()].isStopped = false; controller->directSubmissions[bcsCsr.get()].isStopped = false;
controller->notifyNewSubmission(&secondDeviceCsr);
controller->checkNewSubmissions(); controller->checkNewSubmissions();
EXPECT_EQ(controller->directSubmissions[&secondDeviceCsr].taskCount, 10u); EXPECT_EQ(controller->directSubmissions[&secondDeviceCsr].taskCount, 10u);
EXPECT_TRUE(controller->directSubmissions[&secondDeviceCsr].isStopped); EXPECT_TRUE(controller->directSubmissions[&secondDeviceCsr].isStopped);

View File

@@ -16,89 +16,67 @@
namespace NEO { namespace NEO {
TEST(DirectSubmissionControllerTestsMt, givenDirectSubmissionControllerWhenNewSubmissionThenDirectSubmissionsAreChecked) { TEST(DirectSubmissionControllerTestsMt, givenDirectSubmissionControllerWhenTimeoutThenDirectSubmissionsAreChecked) {
MockExecutionEnvironment executionEnvironment; MockExecutionEnvironment executionEnvironment;
executionEnvironment.prepareRootDeviceEnvironments(1); executionEnvironment.prepareRootDeviceEnvironments(1);
executionEnvironment.initializeMemoryManager(); executionEnvironment.initializeMemoryManager();
executionEnvironment.rootDeviceEnvironments[0]->initOsTime(); executionEnvironment.rootDeviceEnvironments[0]->initOsTime();
DeviceBitfield deviceBitfield(1); DeviceBitfield deviceBitfield(1);
MockCommandStreamReceiver csr(executionEnvironment, 0, deviceBitfield);
std::unique_ptr<OsContext> osContext(OsContext::create(nullptr, 0, 0, std::unique_ptr<OsContext> osContext(OsContext::create(nullptr, 0, 0,
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_CCS, EngineUsage::regular}, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_CCS, EngineUsage::regular},
PreemptionMode::ThreadGroup, deviceBitfield))); PreemptionMode::ThreadGroup, deviceBitfield)));
csr.setupContext(*osContext.get());
MockCommandStreamReceiver csr1(executionEnvironment, 0, deviceBitfield); csr.initializeTagAllocation();
MockCommandStreamReceiver csr2(executionEnvironment, 0, deviceBitfield); *csr.tagAddress = 9u;
csr.taskCount.store(9u);
csr1.setupContext(*osContext.get());
csr2.setupContext(*osContext.get());
DirectSubmissionControllerMock controller; DirectSubmissionControllerMock controller;
executionEnvironment.directSubmissionController.reset(&controller);
controller.timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed); controller.timeoutElapsedReturnValue.store(TimeoutElapsedMode::fullyElapsed);
controller.registerDirectSubmission(&csr1);
controller.registerDirectSubmission(&csr2);
controller.startThread(); controller.startThread();
controller.waitTillSleep(); csr.startControllingDirectSubmissions();
// Nothing to do, we are deep sleeping on condition var controller.registerDirectSubmission(&csr);
EXPECT_TRUE(controller.waitOnConditionVar.load());
EXPECT_FALSE(controller.handlePagingFenceRequestsCalled.load());
EXPECT_FALSE(controller.sleepCalled.load());
EXPECT_FALSE(controller.checkNewSubmissionCalled.load());
// Wake up controller with new submission to csr1 only, work should be done and wait again while (controller.directSubmissions[&csr].taskCount != 9u) {
controller.waitOnConditionVar.store(false); std::this_thread::yield();
EXPECT_FALSE(controller.waitOnConditionVar.load()); }
while (!controller.directSubmissions[&csr].isStopped) {
csr1.taskCount = 10; std::this_thread::yield();
csr2.taskCount = 20; }
controller.notifyNewSubmission(&csr1); {
std::lock_guard<std::mutex> lock(controller.directSubmissionsMutex);
controller.waitTillSleep(); EXPECT_NE(controller.directSubmissionControllingThread.get(), nullptr);
EXPECT_TRUE(controller.directSubmissions[&csr].isStopped);
// Work is done, verify results for csr1 EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 9u);
EXPECT_TRUE(controller.waitOnConditionVar.load()); }
EXPECT_TRUE(controller.handlePagingFenceRequestsCalled.load());
EXPECT_TRUE(controller.sleepCalled.load());
EXPECT_TRUE(controller.checkNewSubmissionCalled.load());
EXPECT_NE(controller.directSubmissionControllingThread.get(), nullptr);
EXPECT_TRUE(controller.directSubmissions[&csr1].isStopped.load());
EXPECT_EQ(10u, controller.directSubmissions[&csr1].taskCount.load());
EXPECT_EQ(10u, csr1.peekTaskCount());
// csr2 is unhandled despite task count is not 0, direct submission was not started on csr2
EXPECT_FALSE(controller.directSubmissions[&csr2].isActive.load());
EXPECT_TRUE(controller.directSubmissions[&csr2].isStopped.load());
EXPECT_EQ(0u, controller.directSubmissions[&csr2].taskCount.load());
EXPECT_EQ(20u, csr2.peekTaskCount());
// csr2 should be as well handled when direct submission started
controller.waitOnConditionVar.store(false);
EXPECT_FALSE(controller.waitOnConditionVar.load());
controller.notifyNewSubmission(&csr2);
controller.waitTillSleep();
EXPECT_TRUE(controller.waitOnConditionVar.load());
EXPECT_TRUE(controller.handlePagingFenceRequestsCalled.load());
EXPECT_TRUE(controller.sleepCalled.load());
EXPECT_TRUE(controller.checkNewSubmissionCalled.load());
EXPECT_TRUE(controller.directSubmissions[&csr2].isStopped.load());
EXPECT_EQ(20u, controller.directSubmissions[&csr2].taskCount.load());
EXPECT_EQ(20u, csr2.peekTaskCount());
controller.stopThread(); controller.stopThread();
controller.unregisterDirectSubmission(&csr1); controller.unregisterDirectSubmission(&csr);
controller.unregisterDirectSubmission(&csr2); executionEnvironment.directSubmissionController.release();
} }
TEST(DirectSubmissionControllerTestsMt, givenDirectSubmissionControllerWhenShuttingDownThenNoHang) { TEST(DirectSubmissionControllerTestsMt, givenDirectSubmissionControllerWithStartedControllingWhenShuttingDownThenNoHang) {
DirectSubmissionControllerMock controller; DirectSubmissionControllerMock controller;
controller.startThread(); controller.startThread();
EXPECT_NE(controller.directSubmissionControllingThread.get(), nullptr); EXPECT_NE(controller.directSubmissionControllingThread.get(), nullptr);
std::this_thread::yield(); controller.startControlling();
while (!controller.sleepCalled) {
std::this_thread::yield();
}
controller.stopThread();
}
TEST(DirectSubmissionControllerTestsMt, givenDirectSubmissionControllerWithNotStartedControllingWhenShuttingDownThenNoHang) {
DirectSubmissionControllerMock controller;
controller.startThread();
EXPECT_NE(controller.directSubmissionControllingThread.get(), nullptr);
while (!controller.sleepCalled) {
std::this_thread::yield();
}
controller.stopThread(); controller.stopThread();
EXPECT_EQ(controller.directSubmissionControllingThread.get(), nullptr);
} }
TEST(DirectSubmissionControllerTestsMt, givenDirectSubmissionControllerWhenEnqueuedWaitForPagingFenceThenRequestHandled) { TEST(DirectSubmissionControllerTestsMt, givenDirectSubmissionControllerWhenEnqueuedWaitForPagingFenceThenRequestHandled) {
@@ -113,26 +91,29 @@ TEST(DirectSubmissionControllerTestsMt, givenDirectSubmissionControllerWhenEnque
DirectSubmissionControllerMock controller; DirectSubmissionControllerMock controller;
controller.sleepCalled.store(false); controller.sleepCalled.store(false);
controller.startThread(); controller.startThread();
controller.waitTillSleep(); while (!controller.sleepCalled) {
std::this_thread::yield();
EXPECT_TRUE(controller.waitOnConditionVar.load()); }
EXPECT_FALSE(controller.handlePagingFenceRequestsCalled.load()); EXPECT_EQ(0u, csr.pagingFenceValueToUnblock);
EXPECT_FALSE(controller.sleepCalled.load());
EXPECT_FALSE(controller.checkNewSubmissionCalled.load());
// Wake up controller with paging fence, work should be done and wait again
controller.waitOnConditionVar.store(false);
EXPECT_FALSE(controller.waitOnConditionVar.load());
controller.enqueueWaitForPagingFence(&csr, 10u); controller.enqueueWaitForPagingFence(&csr, 10u);
controller.waitTillSleep(); // Wait until csr is not updated
while (csr.pagingFenceValueToUnblock == 0u) {
EXPECT_TRUE(controller.waitOnConditionVar.load()); std::this_thread::yield();
EXPECT_TRUE(controller.sleepCalled.load()); }
EXPECT_TRUE(controller.handlePagingFenceRequestsCalled.load());
EXPECT_TRUE(controller.checkNewSubmissionCalled.load());
EXPECT_EQ(10u, csr.pagingFenceValueToUnblock); EXPECT_EQ(10u, csr.pagingFenceValueToUnblock);
// Verify that controller is able to handle requests during controlling
controller.startControlling();
controller.enqueueWaitForPagingFence(&csr, 20u);
while (csr.pagingFenceValueToUnblock == 10u) {
std::this_thread::yield();
}
EXPECT_EQ(20u, csr.pagingFenceValueToUnblock);
controller.stopThread(); controller.stopThread();
} }
} // namespace NEO } // namespace NEO

View File

@@ -5,16 +5,12 @@
* *
*/ */
#include "shared/test/common/mocks/mock_memory_manager.h"
#include "shared/test/common/mocks/mock_usm_memory_reuse_cleaner.h" #include "shared/test/common/mocks/mock_usm_memory_reuse_cleaner.h"
#include "shared/test/common/test_macros/test.h" #include "shared/test/common/test_macros/test.h"
namespace NEO { namespace NEO {
TEST(UnifiedMemoryReuseCleanerTestsMt, givenUnifiedMemoryReuseCleanerWhenCachesAreEmptyThenWorkerThreadIsWaitingOnConditionVar) { TEST(UnifiedMemoryReuseCleanerTestsMt, givenUnifiedMemoryReuseCleanerWhenSleepExpiredThenTrimOldInCachesIsCalled) {
MockMemoryManager mockMemoryManager; MockUnifiedMemoryReuseCleaner cleaner(false);
mockMemoryManager.executionEnvironment.unifiedMemoryReuseCleaner.reset(new MockUnifiedMemoryReuseCleaner(false));
MockUnifiedMemoryReuseCleaner &cleaner = *static_cast<MockUnifiedMemoryReuseCleaner *>(mockMemoryManager.executionEnvironment.unifiedMemoryReuseCleaner.get());
cleaner.callBaseStartThread = true; cleaner.callBaseStartThread = true;
cleaner.callBaseTrimOldInCaches = false; cleaner.callBaseTrimOldInCaches = false;
EXPECT_EQ(nullptr, cleaner.unifiedMemoryReuseCleanerThread); EXPECT_EQ(nullptr, cleaner.unifiedMemoryReuseCleanerThread);
@@ -26,52 +22,31 @@ TEST(UnifiedMemoryReuseCleanerTestsMt, givenUnifiedMemoryReuseCleanerWhenCachesA
cleaner.startThread(); cleaner.startThread();
EXPECT_EQ(cleanerThread, cleaner.unifiedMemoryReuseCleanerThread.get()); EXPECT_EQ(cleanerThread, cleaner.unifiedMemoryReuseCleanerThread.get());
} }
EXPECT_FALSE(cleaner.runCleaning.load());
EXPECT_TRUE(cleaner.keepCleaning.load()); EXPECT_TRUE(cleaner.keepCleaning.load());
// Nothing to do, sleeping on condition var
cleaner.waitTillSleep();
EXPECT_TRUE(cleaner.waitOnConditionVar.load());
EXPECT_TRUE(cleaner.isEmpty());
EXPECT_FALSE(cleaner.trimOldInCachesCalled); EXPECT_FALSE(cleaner.trimOldInCachesCalled);
cleaner.registerSvmAllocationCache(nullptr);
EXPECT_TRUE(cleaner.runCleaning.load());
auto svmAllocCache = std::make_unique<SVMAllocsManager::SvmAllocationCache>(); while (false == cleaner.trimOldInCachesCalled) {
std::this_thread::yield();
constexpr size_t svmAllocSize = 1024; }
mockMemoryManager.usmReuseInfo.init(svmAllocSize, svmAllocSize);
svmAllocCache->memoryManager = &mockMemoryManager;
cleaner.registerSvmAllocationCache(svmAllocCache.get());
// Caches are empty, ensure cleaner thread is still waiting on condition var
cleaner.waitTillSleep();
EXPECT_TRUE(cleaner.waitOnConditionVar.load());
EXPECT_TRUE(cleaner.isEmpty());
EXPECT_FALSE(cleaner.trimOldInCachesCalled);
// Wake cleaner thread to proceed some data
cleaner.waitOnConditionVar.store(false);
EXPECT_FALSE(cleaner.waitOnConditionVar.load());
SvmAllocationData allocData{0};
svmAllocCache->insert(svmAllocSize, nullptr, &allocData, false);
cleaner.waitTillSleep();
EXPECT_TRUE(cleaner.waitOnConditionVar.load());
EXPECT_TRUE(cleaner.isEmpty());
EXPECT_TRUE(cleaner.trimOldInCachesCalled);
cleaner.stopThread(); cleaner.stopThread();
EXPECT_EQ(nullptr, cleaner.unifiedMemoryReuseCleanerThread); EXPECT_EQ(nullptr, cleaner.unifiedMemoryReuseCleanerThread);
EXPECT_FALSE(cleaner.runCleaning.load());
EXPECT_FALSE(cleaner.keepCleaning.load()); EXPECT_FALSE(cleaner.keepCleaning.load());
} }
TEST(UnifiedMemoryReuseCleanerTestsMt, givenUnifiedMemoryReuseCleanerWhenShuttingDownThenNoHang) { TEST(UnifiedMemoryReuseCleanerTestsMt, givenUnifiedMemoryReuseCleanerWithNotStartedCleaningWhenShuttingDownThenNoHang) {
MockUnifiedMemoryReuseCleaner cleaner(false); MockUnifiedMemoryReuseCleaner cleaner(false);
cleaner.callBaseStartThread = true; cleaner.callBaseStartThread = true;
cleaner.callBaseTrimOldInCaches = false; cleaner.callBaseTrimOldInCaches = false;
cleaner.startThread(); cleaner.startThread();
EXPECT_NE(nullptr, cleaner.unifiedMemoryReuseCleanerThread); EXPECT_NE(nullptr, cleaner.unifiedMemoryReuseCleanerThread);
std::this_thread::yield(); std::this_thread::yield();
cleaner.stopThread(); cleaner.stopThread();
EXPECT_EQ(nullptr, cleaner.unifiedMemoryReuseCleanerThread);
} }
} // namespace NEO } // namespace NEO

View File

@@ -127,12 +127,16 @@ struct MockWddmCsr : public WddmCommandStreamReceiver<GfxFamily> {
} }
return ret; return ret;
} }
void startControllingDirectSubmissions() override {
directSubmissionControllerStarted = true;
}
uint32_t flushCalledCount = 0; uint32_t flushCalledCount = 0;
std::unique_ptr<CommandBuffer> recordedCommandBuffer; std::unique_ptr<CommandBuffer> recordedCommandBuffer;
bool callParentInitDirectSubmission = true; bool callParentInitDirectSubmission = true;
bool initBlitterDirectSubmission = false; bool initBlitterDirectSubmission = false;
uint32_t fillReusableAllocationsListCalled = 0; uint32_t fillReusableAllocationsListCalled = 0;
bool directSubmissionControllerStarted = false;
}; };
class WddmCommandStreamMockGdiTest : public ::testing::Test { class WddmCommandStreamMockGdiTest : public ::testing::Test {
@@ -1189,6 +1193,7 @@ HWTEST_TEMPLATED_F(WddmCommandStreamMockGdiTest, givenDirectSubmissionEnabledOnR
EXPECT_TRUE(ret); EXPECT_TRUE(ret);
EXPECT_TRUE(csr->isDirectSubmissionEnabled()); EXPECT_TRUE(csr->isDirectSubmissionEnabled());
EXPECT_FALSE(csr->isBlitterDirectSubmissionEnabled()); EXPECT_FALSE(csr->isBlitterDirectSubmissionEnabled());
EXPECT_FALSE(mockCsr->directSubmissionControllerStarted);
GraphicsAllocation *commandBuffer = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize}); GraphicsAllocation *commandBuffer = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize});
ASSERT_NE(nullptr, commandBuffer); ASSERT_NE(nullptr, commandBuffer);
@@ -1235,6 +1240,7 @@ HWTEST_TEMPLATED_F(WddmCommandStreamMockGdiTest, givenDirectSubmissionEnabledOnB
EXPECT_TRUE(ret); EXPECT_TRUE(ret);
EXPECT_FALSE(csr->isDirectSubmissionEnabled()); EXPECT_FALSE(csr->isDirectSubmissionEnabled());
EXPECT_TRUE(csr->isBlitterDirectSubmissionEnabled()); EXPECT_TRUE(csr->isBlitterDirectSubmissionEnabled());
EXPECT_FALSE(mockCsr->directSubmissionControllerStarted);
GraphicsAllocation *commandBuffer = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize}); GraphicsAllocation *commandBuffer = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize});
ASSERT_NE(nullptr, commandBuffer); ASSERT_NE(nullptr, commandBuffer);

View File

@@ -994,30 +994,6 @@ TEST_F(WddmResidencyControllerWithMockWddmTest, givenMakeResidentFailsAndTrimToB
EXPECT_EQ(2u, residencyPack.size()); EXPECT_EQ(2u, residencyPack.size());
} }
HWTEST_F(WddmResidencyControllerTest, givenMakeResidentFailsAndTrimToBudgetFailsWhenCallingMakeResidentResidencyAllocationsThenStopDirectSubmissionAndRetry) {
auto gmmHelper = rootDeviceEnvironment->getGmmHelper();
MockWddmAllocation allocation1(gmmHelper);
void *cpuPtr = reinterpret_cast<void *>(wddm->getWddmMinAddress() + 0x1000);
size_t allocationSize = 0x1000;
auto canonizedAddress = gmmHelper->canonize(castToUint64(const_cast<void *>(cpuPtr)));
WddmAllocation allocationToTrim(0, 1u /*num gmms*/, AllocationType::unknown, cpuPtr, canonizedAddress, allocationSize, nullptr, MemoryPool::memoryNull, 0u, 1u);
allocationToTrim.getResidencyData().updateCompletionData(mockOsContextWin->getMonitoredFence().lastSubmittedFence + 1, osContextId);
allocationToTrim.getResidencyData().resident[osContextId] = true;
residencyController->getEvictionAllocations().push_back(&allocationToTrim);
wddm->makeResidentNumberOfBytesToTrim = allocationSize;
wddm->makeResidentResults = {false, true};
ResidencyContainer residencyPack{&allocation1};
bool requiresBlockingResidencyHandling = true;
residencyController->makeResidentResidencyAllocations(residencyPack, requiresBlockingResidencyHandling, *mockOsContextWin);
auto ultCsr = static_cast<UltCommandStreamReceiver<FamilyType> *>(csr.get());
EXPECT_TRUE(ultCsr->stopDirectSubmissionCalled);
EXPECT_EQ(2u, residencyController->trimResidencyToBudgetCallCount);
}
TEST_F(WddmResidencyControllerWithMockWddmTest, givenMakeResidentFailsWhenCallingMakeResidentResidencyAllocationsThenMemoryBudgetExhaustedIsSetToTrue) { TEST_F(WddmResidencyControllerWithMockWddmTest, givenMakeResidentFailsWhenCallingMakeResidentResidencyAllocationsThenMemoryBudgetExhaustedIsSetToTrue) {
MockWddmAllocation allocation1(gmmHelper); MockWddmAllocation allocation1(gmmHelper);
ResidencyContainer residencyPack{&allocation1}; ResidencyContainer residencyPack{&allocation1};