2019-07-04 18:17:42 +08:00
|
|
|
/*
|
2021-03-08 19:39:07 +08:00
|
|
|
* Copyright (C) 2019-2021 Intel Corporation
|
2019-07-04 18:17:42 +08:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/page_fault_manager/cpu_page_fault_manager.h"
|
2019-07-04 18:17:42 +08:00
|
|
|
|
2021-03-08 19:39:07 +08:00
|
|
|
#include "shared/source/debug_settings/debug_settings_manager.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/debug_helpers.h"
|
2021-03-08 19:39:07 +08:00
|
|
|
#include "shared/source/helpers/options.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/ptr_math.h"
|
|
|
|
#include "shared/source/memory_manager/unified_memory_manager.h"
|
2019-07-04 18:17:42 +08:00
|
|
|
|
|
|
|
#include <mutex>
|
|
|
|
|
|
|
|
namespace NEO {
|
2020-09-14 22:39:12 +08:00
|
|
|
void PageFaultManager::insertAllocation(void *ptr, size_t size, SVMAllocsManager *unifiedMemoryManager, void *cmdQ, const MemoryProperties &memoryProperties) {
|
2021-07-09 23:46:57 +08:00
|
|
|
bool initialPlacementCpu = true;
|
|
|
|
if (memoryProperties.allocFlags.usmInitialPlacementGpu) {
|
|
|
|
initialPlacementCpu = false;
|
|
|
|
}
|
|
|
|
if (memoryProperties.allocFlags.usmInitialPlacementCpu) {
|
|
|
|
initialPlacementCpu = true;
|
|
|
|
}
|
|
|
|
if (const int32_t debugFlag = DebugManager.flags.UsmInitialPlacement.get(); debugFlag != -1) {
|
|
|
|
initialPlacementCpu = debugFlag != 1;
|
|
|
|
}
|
2020-09-14 22:39:12 +08:00
|
|
|
const auto domain = initialPlacementCpu ? AllocationDomain::Cpu : AllocationDomain::None;
|
|
|
|
|
2019-07-04 18:17:42 +08:00
|
|
|
std::unique_lock<SpinLock> lock{mtx};
|
2020-09-14 22:39:12 +08:00
|
|
|
this->memoryData.insert(std::make_pair(ptr, PageFaultData{size, unifiedMemoryManager, cmdQ, domain}));
|
|
|
|
if (!initialPlacementCpu) {
|
|
|
|
this->setAubWritable(false, ptr, unifiedMemoryManager);
|
|
|
|
this->protectCPUMemoryAccess(ptr, size);
|
|
|
|
}
|
2019-07-04 18:17:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void PageFaultManager::removeAllocation(void *ptr) {
|
|
|
|
std::unique_lock<SpinLock> lock{mtx};
|
|
|
|
auto alloc = memoryData.find(ptr);
|
|
|
|
if (alloc != memoryData.end()) {
|
|
|
|
auto &pageFaultData = alloc->second;
|
2020-09-14 22:39:12 +08:00
|
|
|
if (pageFaultData.domain == AllocationDomain::Gpu) {
|
2019-07-04 18:17:42 +08:00
|
|
|
allowCPUMemoryAccess(ptr, pageFaultData.size);
|
|
|
|
}
|
|
|
|
this->memoryData.erase(ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageFaultManager::moveAllocationToGpuDomain(void *ptr) {
|
|
|
|
std::unique_lock<SpinLock> lock{mtx};
|
|
|
|
auto alloc = memoryData.find(ptr);
|
|
|
|
if (alloc != memoryData.end()) {
|
|
|
|
auto &pageFaultData = alloc->second;
|
2020-09-14 22:39:12 +08:00
|
|
|
if (pageFaultData.domain != AllocationDomain::Gpu) {
|
2019-11-13 21:19:55 +08:00
|
|
|
this->setAubWritable(false, ptr, pageFaultData.unifiedMemoryManager);
|
2020-09-14 22:39:12 +08:00
|
|
|
if (pageFaultData.domain == AllocationDomain::Cpu) {
|
|
|
|
this->transferToGpu(ptr, pageFaultData.cmdQ);
|
|
|
|
this->protectCPUMemoryAccess(ptr, pageFaultData.size);
|
|
|
|
}
|
|
|
|
pageFaultData.domain = AllocationDomain::Gpu;
|
2019-07-04 18:17:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageFaultManager::moveAllocationsWithinUMAllocsManagerToGpuDomain(SVMAllocsManager *unifiedMemoryManager) {
|
|
|
|
std::unique_lock<SpinLock> lock{mtx};
|
|
|
|
for (auto &alloc : this->memoryData) {
|
|
|
|
auto allocPtr = alloc.first;
|
|
|
|
auto &pageFaultData = alloc.second;
|
2020-09-14 22:39:12 +08:00
|
|
|
if (pageFaultData.unifiedMemoryManager == unifiedMemoryManager && pageFaultData.domain != AllocationDomain::Gpu) {
|
2019-11-13 21:19:55 +08:00
|
|
|
this->setAubWritable(false, allocPtr, pageFaultData.unifiedMemoryManager);
|
2020-09-14 22:39:12 +08:00
|
|
|
if (pageFaultData.domain == AllocationDomain::Cpu) {
|
|
|
|
this->transferToGpu(allocPtr, pageFaultData.cmdQ);
|
|
|
|
this->protectCPUMemoryAccess(allocPtr, pageFaultData.size);
|
|
|
|
}
|
|
|
|
pageFaultData.domain = AllocationDomain::Gpu;
|
2019-07-04 18:17:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PageFaultManager::verifyPageFault(void *ptr) {
|
|
|
|
std::unique_lock<SpinLock> lock{mtx};
|
|
|
|
for (auto &alloc : this->memoryData) {
|
|
|
|
auto allocPtr = alloc.first;
|
|
|
|
auto &pageFaultData = alloc.second;
|
|
|
|
if (ptr >= allocPtr && ptr < ptrOffset(allocPtr, pageFaultData.size)) {
|
2019-11-13 21:19:55 +08:00
|
|
|
this->setAubWritable(true, allocPtr, pageFaultData.unifiedMemoryManager);
|
2021-03-08 19:39:07 +08:00
|
|
|
|
|
|
|
gpuDomainHandler(this, allocPtr, pageFaultData);
|
2019-07-04 18:17:42 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2019-11-13 21:19:55 +08:00
|
|
|
|
2021-03-08 19:39:07 +08:00
|
|
|
void PageFaultManager::handleGpuDomainTransferForHw(PageFaultManager *pageFaultHandler, void *allocPtr, PageFaultData &pageFaultData) {
|
|
|
|
if (pageFaultData.domain == AllocationDomain::Gpu) {
|
|
|
|
pageFaultHandler->transferToCpu(allocPtr, pageFaultData.size, pageFaultData.cmdQ);
|
|
|
|
}
|
|
|
|
pageFaultData.domain = AllocationDomain::Cpu;
|
|
|
|
pageFaultHandler->allowCPUMemoryAccess(allocPtr, pageFaultData.size);
|
|
|
|
}
|
|
|
|
|
2021-04-02 22:22:34 +08:00
|
|
|
void PageFaultManager::handleGpuDomainTransferForAubAndTbx(PageFaultManager *pageFaultHandler, void *allocPtr, PageFaultData &pageFaultData) {
|
2021-03-08 19:39:07 +08:00
|
|
|
pageFaultHandler->allowCPUMemoryAccess(allocPtr, pageFaultData.size);
|
|
|
|
|
|
|
|
if (pageFaultData.domain == AllocationDomain::Gpu) {
|
|
|
|
pageFaultHandler->transferToCpu(allocPtr, pageFaultData.size, pageFaultData.cmdQ);
|
|
|
|
}
|
|
|
|
pageFaultData.domain = AllocationDomain::Cpu;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageFaultManager::selectGpuDomainHandler() {
|
2021-04-02 22:22:34 +08:00
|
|
|
if (DebugManager.flags.SetCommandStreamReceiver.get() == CommandStreamReceiverType::CSR_AUB ||
|
|
|
|
DebugManager.flags.SetCommandStreamReceiver.get() == CommandStreamReceiverType::CSR_TBX ||
|
2021-03-08 19:39:07 +08:00
|
|
|
DebugManager.flags.SetCommandStreamReceiver.get() == CommandStreamReceiverType::CSR_TBX_WITH_AUB) {
|
2021-04-02 22:22:34 +08:00
|
|
|
this->gpuDomainHandler = &PageFaultManager::handleGpuDomainTransferForAubAndTbx;
|
2021-03-08 19:39:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-13 21:19:55 +08:00
|
|
|
void PageFaultManager::setAubWritable(bool writable, void *ptr, SVMAllocsManager *unifiedMemoryManager) {
|
2019-11-30 00:34:18 +08:00
|
|
|
UNRECOVERABLE_IF(ptr == nullptr);
|
2020-06-29 18:47:13 +08:00
|
|
|
auto gpuAlloc = unifiedMemoryManager->getSVMAlloc(ptr)->gpuAllocations.getDefaultGraphicsAllocation();
|
2019-11-13 21:19:55 +08:00
|
|
|
gpuAlloc->setAubWritable(writable, GraphicsAllocation::allBanks);
|
|
|
|
}
|
2020-07-06 19:09:12 +08:00
|
|
|
|
2019-07-04 18:17:42 +08:00
|
|
|
} // namespace NEO
|