feature: update Xe KMD header

xe_drm.h header is generated from the series "uAPI Alignment - take 1 v4"
from https://patchwork.freedesktop.org/series/124387/

Related-To: NEO-8324
Signed-off-by: Francois Dugast <francois.dugast@intel.com>
Signed-off-by: Kamil, Kopryk <kamil.kopryk@intel.com>
Signed-off-by: Naklicki, Mateusz <mateusz.naklicki@intel.com>
This commit is contained in:
Francois Dugast
2023-09-18 10:49:16 +00:00
committed by Compute-Runtime-Automation
parent 5c162e2bd7
commit 1fd9d29f54
14 changed files with 904 additions and 513 deletions

View File

@@ -19,95 +19,10 @@ namespace NEO {
DeviceTimeDrm::DeviceTimeDrm(OSInterface &osInterface) {
pDrm = osInterface.getDriverModel()->as<Drm>();
timestampTypeDetect();
}
void DeviceTimeDrm::timestampTypeDetect() {
RegisterRead reg = {};
int err;
reg.offset = (REG_GLOBAL_TIMESTAMP_LDW | 1);
auto ioctlHelper = pDrm->getIoctlHelper();
err = ioctlHelper->ioctl(DrmIoctl::RegRead, &reg);
if (err) {
reg.offset = REG_GLOBAL_TIMESTAMP_UN;
err = ioctlHelper->ioctl(DrmIoctl::RegRead, &reg);
if (err) {
getGpuTime = &DeviceTimeDrm::getGpuTime32;
} else {
getGpuTime = &DeviceTimeDrm::getGpuTimeSplitted;
}
} else {
getGpuTime = &DeviceTimeDrm::getGpuTime36;
}
}
bool DeviceTimeDrm::getGpuTime32(uint64_t *timestamp) {
RegisterRead reg = {};
reg.offset = REG_GLOBAL_TIMESTAMP_LDW;
auto ioctlHelper = pDrm->getIoctlHelper();
if (ioctlHelper->ioctl(DrmIoctl::RegRead, &reg)) {
return false;
}
*timestamp = reg.value >> 32;
return true;
}
bool DeviceTimeDrm::getGpuTime36(uint64_t *timestamp) {
RegisterRead reg = {};
reg.offset = REG_GLOBAL_TIMESTAMP_LDW | 1;
auto ioctlHelper = pDrm->getIoctlHelper();
if (ioctlHelper->ioctl(DrmIoctl::RegRead, &reg)) {
return false;
}
*timestamp = reg.value;
return true;
}
bool DeviceTimeDrm::getGpuTimeSplitted(uint64_t *timestamp) {
RegisterRead regHi = {};
RegisterRead regLo = {};
uint64_t tmpHi;
int err = 0, loop = 3;
regHi.offset = REG_GLOBAL_TIMESTAMP_UN;
regLo.offset = REG_GLOBAL_TIMESTAMP_LDW;
auto ioctlHelper = pDrm->getIoctlHelper();
err += ioctlHelper->ioctl(DrmIoctl::RegRead, &regHi);
do {
tmpHi = regHi.value;
err += ioctlHelper->ioctl(DrmIoctl::RegRead, &regLo);
err += ioctlHelper->ioctl(DrmIoctl::RegRead, &regHi);
} while (err == 0 && regHi.value != tmpHi && --loop);
if (err) {
return false;
}
*timestamp = regLo.value | (regHi.value << 32);
return true;
}
std::optional<uint64_t> initialGpuTimeStamp{};
bool waitingForGpuTimeStampOverflow = false;
uint64_t gpuTimeStampOverflowCounter = 0;
bool DeviceTimeDrm::getGpuCpuTimeImpl(TimeStampData *pGpuCpuTime, OSTime *osTime) {
if (nullptr == this->getGpuTime) {
return false;
}
if (!(this->*getGpuTime)(&pGpuCpuTime->gpuTimeStamp)) {
return false;
}
if (!osTime->getCpuTime(&pGpuCpuTime->cpuTimeinNS)) {
return false;
}
return true;
return pDrm->getIoctlHelper()->setGpuCpuTimes(pGpuCpuTime, osTime);
}
double DeviceTimeDrm::getDynamicDeviceTimerResolution(HardwareInfo const &hwInfo) const {
@@ -116,13 +31,14 @@ double DeviceTimeDrm::getDynamicDeviceTimerResolution(HardwareInfo const &hwInfo
auto error = pDrm->getTimestampFrequency(frequency);
if (!error) {
return 1000000000.0 / frequency;
return nanosecondsPerSecond / frequency;
}
}
return OSTime::getDeviceTimerResolution(hwInfo);
}
uint64_t DeviceTimeDrm::getDynamicDeviceTimerClock(HardwareInfo const &hwInfo) const {
if (pDrm) {
int frequency = 0;
@@ -131,7 +47,7 @@ uint64_t DeviceTimeDrm::getDynamicDeviceTimerClock(HardwareInfo const &hwInfo) c
return static_cast<uint64_t>(frequency);
}
}
return static_cast<uint64_t>(1000000000.0 / OSTime::getDeviceTimerResolution(hwInfo));
return static_cast<uint64_t>(nanosecondsPerSecond / OSTime::getDeviceTimerResolution(hwInfo));
}
} // namespace NEO
} // namespace NEO

View File

@@ -15,17 +15,13 @@ class DeviceTimeDrm : public DeviceTime {
public:
DeviceTimeDrm(OSInterface &osInterface);
bool getGpuCpuTimeImpl(TimeStampData *pGpuCpuTime, OSTime *osTime) override;
typedef bool (DeviceTimeDrm::*TimestampFunction)(uint64_t *);
void timestampTypeDetect();
TimestampFunction getGpuTime = nullptr;
bool getGpuTime32(uint64_t *timestamp);
bool getGpuTime36(uint64_t *timestamp);
bool getGpuTimeSplitted(uint64_t *timestamp);
double getDynamicDeviceTimerResolution(HardwareInfo const &hwInfo) const override;
uint64_t getDynamicDeviceTimerClock(HardwareInfo const &hwInfo) const override;
protected:
Drm *pDrm = nullptr;
static constexpr double nanosecondsPerSecond = 1000000000.0;
};
} // namespace NEO

View File

@@ -14,12 +14,14 @@
#include "shared/source/helpers/constants.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/helpers/ptr_math.h"
#include "shared/source/helpers/register_offsets.h"
#include "shared/source/os_interface/linux/drm_neo.h"
#include "shared/source/os_interface/linux/drm_wrappers.h"
#include "shared/source/os_interface/linux/engine_info.h"
#include "shared/source/os_interface/linux/i915.h"
#include "shared/source/os_interface/linux/memory_info.h"
#include "shared/source/os_interface/linux/os_context_linux.h"
#include "shared/source/os_interface/os_time.h"
#include <fcntl.h>
#include <sstream>
@@ -574,4 +576,89 @@ bool IoctlHelper::setGemTiling(void *setTiling) {
bool IoctlHelper::getGemTiling(void *setTiling) {
return this->ioctl(DrmIoctl::GemGetTiling, setTiling) == 0;
}
bool getGpuTime32(::NEO::Drm &drm, uint64_t *timestamp) {
RegisterRead reg = {};
reg.offset = REG_GLOBAL_TIMESTAMP_LDW;
if (drm.ioctl(DrmIoctl::RegRead, &reg)) {
return false;
}
*timestamp = reg.value >> 32;
return true;
}
bool getGpuTime36(::NEO::Drm &drm, uint64_t *timestamp) {
RegisterRead reg = {};
reg.offset = REG_GLOBAL_TIMESTAMP_LDW | 1;
if (drm.ioctl(DrmIoctl::RegRead, &reg)) {
return false;
}
*timestamp = reg.value;
return true;
}
bool getGpuTimeSplitted(::NEO::Drm &drm, uint64_t *timestamp) {
RegisterRead regHi = {};
RegisterRead regLo = {};
uint64_t tmpHi;
int err = 0, loop = 3;
regHi.offset = REG_GLOBAL_TIMESTAMP_UN;
regLo.offset = REG_GLOBAL_TIMESTAMP_LDW;
err += drm.ioctl(DrmIoctl::RegRead, &regHi);
do {
tmpHi = regHi.value;
err += drm.ioctl(DrmIoctl::RegRead, &regLo);
err += drm.ioctl(DrmIoctl::RegRead, &regHi);
} while (err == 0 && regHi.value != tmpHi && --loop);
if (err) {
return false;
}
*timestamp = regLo.value | (regHi.value << 32);
return true;
}
void IoctlHelper::initializeGetGpuTimeFunction() {
RegisterRead reg = {};
int err;
reg.offset = (REG_GLOBAL_TIMESTAMP_LDW | 1);
err = this->ioctl(DrmIoctl::RegRead, &reg);
if (err) {
reg.offset = REG_GLOBAL_TIMESTAMP_UN;
err = this->ioctl(DrmIoctl::RegRead, &reg);
if (err) {
this->getGpuTime = getGpuTime32;
} else {
this->getGpuTime = getGpuTimeSplitted;
}
} else {
this->getGpuTime = getGpuTime36;
}
}
bool IoctlHelper::setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) {
if (pGpuCpuTime == nullptr || osTime == nullptr) {
return false;
}
if (!this->getGpuTime) {
return false;
}
if (!this->getGpuTime(drm, &pGpuCpuTime->gpuTimeStamp)) {
return false;
}
if (!osTime->getCpuTime(&pGpuCpuTime->cpuTimeinNS)) {
return false;
}
return true;
}
} // namespace NEO

View File

@@ -15,6 +15,7 @@
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>
@@ -24,6 +25,7 @@ namespace NEO {
class Drm;
class OsContextLinux;
class IoctlHelper;
class OSTime;
enum class CacheRegion : uint16_t;
enum class PreferredLocation : int16_t;
enum class AtomicAccessMode : uint32_t;
@@ -31,6 +33,7 @@ struct HardwareInfo;
struct HardwareIpVersion;
struct EngineInfo;
struct DrmQueryTopologyData;
struct TimeStampData;
class MemoryInfo;
@@ -163,6 +166,10 @@ class IoctlHelper {
bool translateTopologyInfo(const QueryTopologyInfo *queryTopologyInfo, DrmQueryTopologyData &topologyData, TopologyMapping &mapping);
virtual void fillBindInfoForIpcHandle(uint32_t handle, size_t size);
virtual void initializeGetGpuTimeFunction();
virtual bool setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime);
std::function<bool(::NEO::Drm &, uint64_t *)> getGpuTime;
protected:
Drm &drm;
};

View File

@@ -920,6 +920,7 @@ bool IoctlHelperPrelim20::queryHwIpVersion(EngineClassInstance &engineInfo, Hard
}
bool IoctlHelperPrelim20::initialize() {
initializeGetGpuTimeFunction();
return true;
}

View File

@@ -17,6 +17,7 @@ namespace NEO {
bool IoctlHelperUpstream::initialize() {
detectExtSetPatSupport();
initializeGetGpuTimeFunction();
return true;
}

View File

@@ -15,6 +15,7 @@
#include "shared/source/helpers/bit_helpers.h"
#include "shared/source/helpers/common_types.h"
#include "shared/source/helpers/constants.h"
#include "shared/source/helpers/engine_control.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/helpers/ptr_math.h"
#include "shared/source/helpers/register_offsets.h"
@@ -23,6 +24,7 @@
#include "shared/source/os_interface/linux/engine_info.h"
#include "shared/source/os_interface/linux/memory_info.h"
#include "shared/source/os_interface/linux/os_context_linux.h"
#include "shared/source/os_interface/os_time.h"
#include "drm/i915_drm_prelim.h"
#include "drm/xe_drm.h"
@@ -83,22 +85,34 @@ const char *IoctlHelperXe::xeGetClassName(int className) {
return "???";
}
const char *IoctlHelperXe::xeGetBindOpName(int bindOp) {
switch (bindOp) {
const char *IoctlHelperXe::xeGetBindOperationName(int bindOperation) {
switch (bindOperation) {
case XE_VM_BIND_OP_MAP:
return "MAP";
case XE_VM_BIND_OP_UNMAP:
return "UNMAP";
case XE_VM_BIND_OP_MAP_USERPTR:
return "MAP_USERPTR";
case XE_VM_BIND_OP_MAP | XE_VM_BIND_FLAG_ASYNC:
return "AS_MAP";
case XE_VM_BIND_OP_UNMAP | XE_VM_BIND_FLAG_ASYNC:
return "AS_UNMAP";
case XE_VM_BIND_OP_MAP_USERPTR | XE_VM_BIND_FLAG_ASYNC:
return "AS_MAP_USERPTR";
case XE_VM_BIND_OP_UNMAP_ALL:
return "UNMAP ALL";
case XE_VM_BIND_OP_PREFETCH:
return "PREFETCH";
}
return "unknown_OP";
return "Unknown operation";
}
const char *IoctlHelperXe::xeGetBindFlagsName(int bindFlags) {
switch (bindFlags) {
case XE_VM_BIND_FLAG_READONLY:
return "READ_ONLY";
case XE_VM_BIND_FLAG_ASYNC:
return "ASYNC";
case XE_VM_BIND_FLAG_IMMEDIATE:
return "IMMEDIATE";
case XE_VM_BIND_FLAG_NULL:
return "NULL";
}
return "Unknown flag";
}
const char *IoctlHelperXe::xeGetengineClassName(uint32_t engineClass) {
@@ -125,7 +139,7 @@ IoctlHelperXe::IoctlHelperXe(Drm &drmArg) : IoctlHelper(drmArg) {
bool IoctlHelperXe::initialize() {
xeLog("IoctlHelperXe::initialize\n", "");
struct drm_xe_device_query queryConfig = {};
drm_xe_device_query queryConfig = {};
queryConfig.query = DRM_XE_DEVICE_QUERY_CONFIG;
auto retVal = IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig);
@@ -139,7 +153,7 @@ bool IoctlHelperXe::initialize() {
xeLog("XE_QUERY_CONFIG_REV_AND_DEVICE_ID\t%#llx\n",
config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID]);
xeLog(" REV_ID\t\t\t\t%#llx\n",
config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] >> 16);
(config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] >> 16) & 0xff);
xeLog(" DEVICE_ID\t\t\t\t%#llx\n",
config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] & 0xffff);
xeLog("XE_QUERY_CONFIG_FLAGS\t\t\t%#llx\n",
@@ -159,7 +173,7 @@ bool IoctlHelperXe::initialize() {
config->info[XE_QUERY_CONFIG_MEM_REGION_COUNT]);
chipsetId = config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] & 0xffff;
revId = static_cast<int>(config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] >> 16);
revId = static_cast<int>((config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] >> 16) & 0xff);
hasVram = config->info[XE_QUERY_CONFIG_FLAGS] & XE_QUERY_CONFIG_FLAGS_HAS_VRAM ? 1 : 0;
memset(&queryConfig, 0, sizeof(queryConfig));
@@ -173,6 +187,7 @@ bool IoctlHelperXe::initialize() {
auto hwInfo = this->drm.getRootDeviceEnvironment().getMutableHardwareInfo();
hwInfo->platform.usDeviceID = chipsetId;
hwInfo->platform.usRevId = revId;
return true;
}
@@ -253,6 +268,9 @@ std::unique_ptr<EngineInfo> IoctlHelperXe::createEngineInfo(bool isSysmanEnabled
multiTileArchInfo.TileCount = multiTileMask.count();
multiTileArchInfo.TileMask = static_cast<uint8_t>(multiTileMask.to_ulong());
}
setDefaultEngine();
return std::make_unique<EngineInfo>(&drm, enginesPerTile);
}
@@ -267,15 +285,15 @@ inline MemoryRegion createMemoryRegionFromXeMemRegion(const drm_xe_query_mem_reg
std::unique_ptr<MemoryInfo> IoctlHelperXe::createMemoryInfo() {
auto memUsageData = queryData<uint64_t>(DRM_XE_DEVICE_QUERY_MEM_USAGE);
auto gtsData = queryData<uint64_t>(DRM_XE_DEVICE_QUERY_GTS);
auto gtListData = queryData<uint64_t>(DRM_XE_DEVICE_QUERY_GT_LIST);
if (memUsageData.empty() || gtsData.empty()) {
if (memUsageData.empty() || gtListData.empty()) {
return {};
}
MemoryInfo::RegionContainer regionsContainer{};
auto xeMemUsageData = reinterpret_cast<drm_xe_query_mem_usage *>(memUsageData.data());
auto xeGtsData = reinterpret_cast<drm_xe_query_gts *>(gtsData.data());
auto xeGtListData = reinterpret_cast<drm_xe_query_gt_list *>(gtListData.data());
std::array<drm_xe_query_mem_region *, 64> memoryRegionInstances{};
@@ -291,19 +309,84 @@ std::unique_ptr<MemoryInfo> IoctlHelperXe::createMemoryInfo() {
return {};
}
for (auto i = 0u; i < xeGtsData->num_gt; i++) {
if (xeGtsData->gts[i].type != XE_QUERY_GT_TYPE_MEDIA) {
uint64_t nativeMemRegions = xeGtsData->gts[i].native_mem_regions;
for (auto i = 0u; i < xeGtListData->num_gt; i++) {
if (xeGtListData->gt_list[i].type != XE_QUERY_GT_TYPE_MEDIA) {
uint64_t nativeMemRegions = xeGtListData->gt_list[i].native_mem_regions;
auto regionIndex = Math::log2(nativeMemRegions);
UNRECOVERABLE_IF(!memoryRegionInstances[regionIndex]);
regionsContainer.push_back(createMemoryRegionFromXeMemRegion(*memoryRegionInstances[regionIndex]));
xeTimestampFrequency = xeGtsData->gts[i].clock_freq;
xeTimestampFrequency = xeGtListData->gt_list[i].clock_freq;
}
}
return std::make_unique<MemoryInfo>(regionsContainer, drm);
}
bool IoctlHelperXe::setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) {
if (pGpuCpuTime == nullptr || osTime == nullptr) {
return false;
}
drm_xe_device_query deviceQuery = {};
deviceQuery.query = DRM_XE_DEVICE_QUERY_ENGINE_CYCLES;
auto ret = IoctlHelper::ioctl(DrmIoctl::Query, &deviceQuery);
if (ret != 0) {
xeLog(" -> IoctlHelperXe::%s s=0x%lx r=%d\n", __FUNCTION__, deviceQuery.size, ret);
return false;
}
std::vector<uint8_t> retVal(deviceQuery.size);
deviceQuery.data = castToUint64(retVal.data());
drm_xe_query_engine_cycles *queryEngineCycles = reinterpret_cast<drm_xe_query_engine_cycles *>(retVal.data());
queryEngineCycles->clockid = CLOCK_MONOTONIC_RAW;
queryEngineCycles->eci = *this->defaultEngine;
ret = IoctlHelper::ioctl(DrmIoctl::Query, &deviceQuery);
auto nValidBits = queryEngineCycles->width;
auto gpuTimestampValidBits = maxNBitValue(nValidBits);
auto gpuCycles = queryEngineCycles->engine_cycles & gpuTimestampValidBits;
xeLog(" -> IoctlHelperXe::%s [%d,%d] clockId=0x%x s=0x%lx nValidBits=0x%x gpuCycles=0x%x cpuTimeInNS=0x%x r=%d\n", __FUNCTION__,
queryEngineCycles->eci.engine_class, queryEngineCycles->eci.engine_instance,
queryEngineCycles->clockid, deviceQuery.size, nValidBits, gpuCycles, queryEngineCycles->cpu_timestamp, ret);
pGpuCpuTime->gpuTimeStamp = gpuCycles;
pGpuCpuTime->cpuTimeinNS = queryEngineCycles->cpu_timestamp;
return ret == 0;
}
bool IoctlHelperXe::getTimestampFrequency(uint64_t &frequency) {
drm_xe_device_query deviceQuery = {};
deviceQuery.query = DRM_XE_DEVICE_QUERY_ENGINE_CYCLES;
auto ret = IoctlHelper::ioctl(DrmIoctl::Query, &deviceQuery);
if (ret != 0) {
xeLog(" -> IoctlHelperXe::%s s=0x%lx r=%d\n", __FUNCTION__, deviceQuery.size, ret);
return false;
}
std::vector<uint8_t> retVal(deviceQuery.size);
deviceQuery.data = castToUint64(retVal.data());
drm_xe_query_engine_cycles *queryEngineCycles = reinterpret_cast<drm_xe_query_engine_cycles *>(retVal.data());
queryEngineCycles->clockid = CLOCK_MONOTONIC_RAW;
queryEngineCycles->eci = *defaultEngine;
ret = IoctlHelper::ioctl(DrmIoctl::Query, &deviceQuery);
frequency = queryEngineCycles->engine_frequency;
xeLog(" -> IoctlHelperXe::%s [%d,%d] clockId=0x%x s=0x%lx frequency=0x%x r=%d\n", __FUNCTION__,
queryEngineCycles->eci.engine_class, queryEngineCycles->eci.engine_instance,
queryEngineCycles->clockid, deviceQuery.size, frequency, ret);
return ret == 0;
}
void IoctlHelperXe::getTopologyData(size_t nTiles, std::vector<std::bitset<8>> *geomDss, std::vector<std::bitset<8>> *computeDss,
std::vector<std::bitset<8>> *euDss, DrmQueryTopologyData &topologyData, bool &isComputeDssEmpty) {
int subSliceCount = 0;
@@ -383,13 +466,13 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo
auto topologySize = queryGtTopology.size();
auto dataPtr = queryGtTopology.data();
auto gtsData = queryData<uint64_t>(DRM_XE_DEVICE_QUERY_GTS);
auto xeGtsData = reinterpret_cast<drm_xe_query_gts *>(gtsData.data());
gtIdToTile.resize(xeGtsData->num_gt, -1);
auto gtsData = queryData<uint64_t>(DRM_XE_DEVICE_QUERY_GT_LIST);
auto xeGtListData = reinterpret_cast<drm_xe_query_gt_list *>(gtsData.data());
gtIdToTile.resize(xeGtListData->num_gt, -1);
auto tileIndex = 0u;
for (auto gt = 0u; gt < gtIdToTile.size(); gt++) {
if (xeGtsData->gts[gt].type != XE_QUERY_GT_TYPE_MEDIA) {
if (xeGtListData->gt_list[gt].type != XE_QUERY_GT_TYPE_MEDIA) {
gtIdToTile[gt] = tileIndex++;
}
}
@@ -403,7 +486,7 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo
uint32_t gtId = topo->gt_id;
if (xeGtsData->gts[gtId].type != XE_QUERY_GT_TYPE_MEDIA) {
if (xeGtListData->gt_list[gtId].type != XE_QUERY_GT_TYPE_MEDIA) {
switch (topo->type) {
case XE_TOPO_DSS_GEOMETRY:
fillMask(geomDss[gtIdToTile[gtId]], topo);
@@ -440,6 +523,21 @@ void IoctlHelperXe::updateBindInfo(uint32_t handle, uint64_t userPtr, uint64_t s
bindInfo.push_back(b);
}
void IoctlHelperXe::setDefaultEngine() {
auto defaultEngineClass = DRM_XE_ENGINE_CLASS_COMPUTE;
for (auto i = 0u; i < allEngines.size(); i++) {
if (allEngines[i].engine_class == defaultEngineClass) {
defaultEngine = xeFindMatchingEngine(defaultEngineClass, allEngines[i].engine_instance);
break;
}
}
if (defaultEngine == nullptr) {
UNRECOVERABLE_IF(true);
}
}
int IoctlHelperXe::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) {
struct drm_xe_gem_create create = {};
uint32_t regionsSize = static_cast<uint32_t>(memClassInstances.size());
@@ -814,8 +912,6 @@ unsigned int IoctlHelperXe::getIoctlRequestValue(DrmIoctl ioctlRequest) const {
RETURN_ME(DRM_IOCTL_PRIME_FD_TO_HANDLE);
case DrmIoctl::PrimeHandleToFd:
RETURN_ME(DRM_IOCTL_PRIME_HANDLE_TO_FD);
case DrmIoctl::RegRead:
RETURN_ME(DRM_IOCTL_XE_MMIO);
default:
UNRECOVERABLE_IF(true);
return 0;
@@ -885,8 +981,6 @@ std::string IoctlHelperXe::getIoctlString(DrmIoctl ioctlRequest) const {
STRINGIFY_ME(DRM_IOCTL_PRIME_FD_TO_HANDLE);
case DrmIoctl::PrimeHandleToFd:
STRINGIFY_ME(DRM_IOCTL_PRIME_HANDLE_TO_FD);
case DrmIoctl::RegRead:
STRINGIFY_ME(DRM_IOCTL_XE_MMIO);
default:
return "???";
}
@@ -915,9 +1009,12 @@ int IoctlHelperXe::ioctl(DrmIoctl request, void *arg) {
case static_cast<int>(DrmParam::ParamHasScheduler):
*d->value = static_cast<int>(0x80000037);
break;
case static_cast<int>(DrmParam::ParamCsTimestampFrequency):
*d->value = static_cast<int>(xeTimestampFrequency);
break;
case static_cast<int>(DrmParam::ParamCsTimestampFrequency): {
uint64_t frequency = 0;
if (getTimestampFrequency(frequency)) {
*d->value = static_cast<int>(frequency);
}
} break;
default:
ret = -1;
}
@@ -1045,23 +1142,10 @@ int IoctlHelperXe::ioctl(DrmIoctl request, void *arg) {
}
xeLog(" -> IoctlHelperXe::ioctl GemClose found=%d h=0x%x r=%d\n", found, d->handle, ret);
} break;
case DrmIoctl::RegRead: {
struct drm_xe_mmio mmio = {};
RegisterRead *reg = static_cast<RegisterRead *>(arg);
mmio.addr = static_cast<uint32_t>(reg->offset);
if (reg->offset == (REG_GLOBAL_TIMESTAMP_LDW | 1)) {
mmio.addr = REG_GLOBAL_TIMESTAMP_LDW;
}
mmio.flags = DRM_XE_MMIO_READ | DRM_XE_MMIO_64BIT;
ret = IoctlHelper::ioctl(request, &mmio);
reg->value = mmio.value;
xeLog(" -> IoctlHelperXe::ioctl RegRead 0x%lx/0x%lx r=%d\n",
reg->offset, reg->value, ret);
} break;
case DrmIoctl::GemVmCreate: {
GemVmControl *d = static_cast<GemVmControl *>(arg);
struct drm_xe_vm_create args = {};
args.flags = DRM_XE_VM_CREATE_ASYNC_BIND_OPS |
args.flags = DRM_XE_VM_CREATE_ASYNC_DEFAULT |
DRM_XE_VM_CREATE_COMPUTE_MODE;
if (drm.hasPageFaultSupport()) {
args.flags |= DRM_XE_VM_CREATE_FAULT_MODE;
@@ -1139,10 +1223,10 @@ void IoctlHelperXe::xeShowBindTable() {
}
int IoctlHelperXe::createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex) {
struct drm_xe_exec_queue_create create = {};
drm_xe_exec_queue_create create = {};
uint32_t drmContextId = 0;
struct drm_xe_engine_class_instance *currentEngine = nullptr;
std::vector<struct drm_xe_engine_class_instance> engine;
drm_xe_engine_class_instance *currentEngine = nullptr;
std::vector<drm_xe_engine_class_instance> engine;
int requestClass = 0;
xeLog("createDrmContext VM=0x%x\n", drmVmId);
@@ -1193,12 +1277,7 @@ int IoctlHelperXe::createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_
}
create.instances = castToUint64(engine.data());
create.num_placements = engine.size();
struct drm_xe_ext_exec_queue_set_property ext = {};
ext.base.name = XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY;
ext.property = XE_EXEC_QUEUE_SET_PROPERTY_COMPUTE_MODE;
ext.value = 1;
create.extensions = castToUint64(&ext);
int ret = IoctlHelper::ioctl(DrmIoctl::GemContextCreateExt, &create);
drmContextId = create.exec_queue_id;
xeLog("%s:%d (%d) vmid=0x%x ctx=0x%x r=0x%x\n", xeGetClassName(engine[0].engine_class),
@@ -1209,80 +1288,86 @@ int IoctlHelperXe::createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_
return drmContextId;
}
int IoctlHelperXe::xeVmBind(const VmBindParams &vmBindParams, bool bindOp) {
int IoctlHelperXe::xeVmBind(const VmBindParams &vmBindParams, bool isBind) {
constexpr int invalidIndex = -1;
auto gmmHelper = drm.getRootDeviceEnvironment().getGmmHelper();
int ret = -1;
const char *operation = "unbind";
if (bindOp) {
operation = "bind";
}
int found = -1;
if (bindOp) {
for (unsigned int i = 0; i < bindInfo.size(); i++) {
const char *operation = isBind ? "bind" : "unbind";
int index = invalidIndex;
if (isBind) {
for (auto i = 0u; i < bindInfo.size(); i++) {
if (vmBindParams.handle == bindInfo[i].handle) {
found = i;
index = i;
break;
}
}
} else {
auto gmmHelper = drm.getRootDeviceEnvironment().getGmmHelper();
uint64_t ad = gmmHelper->decanonize(vmBindParams.start);
for (unsigned int i = 0; i < bindInfo.size(); i++) {
if (ad == bindInfo[i].addr) {
found = i;
} else // unbind
{
auto address = gmmHelper->decanonize(vmBindParams.start);
for (auto i = 0u; i < bindInfo.size(); i++) {
if (address == bindInfo[i].addr) {
index = i;
break;
}
}
}
if (found != -1) {
uint32_t extraBindFlag = 0;
struct drm_xe_sync sync[1] = {};
if (index != invalidIndex) {
drm_xe_sync sync[1] = {};
sync[0].flags = DRM_XE_SYNC_USER_FENCE | DRM_XE_SYNC_SIGNAL;
extraBindFlag = XE_VM_BIND_FLAG_ASYNC;
auto xeBindExtUserFence = reinterpret_cast<UserFenceExtension *>(vmBindParams.extensions);
UNRECOVERABLE_IF(!xeBindExtUserFence);
UNRECOVERABLE_IF(xeBindExtUserFence->tag != UserFenceExtension::tagValue);
sync[0].addr = xeBindExtUserFence->addr;
sync[0].timeline_value = xeBindExtUserFence->value;
struct drm_xe_vm_bind bind = {};
drm_xe_vm_bind bind = {};
bind.vm_id = vmBindParams.vmId;
bind.num_binds = 1;
bind.bind.obj = vmBindParams.handle;
bind.bind.obj_offset = vmBindParams.offset;
bind.bind.range = vmBindParams.length;
auto gmmHelper = drm.getRootDeviceEnvironment().getGmmHelper();
bind.bind.addr = gmmHelper->decanonize(vmBindParams.start);
bind.bind.op = XE_VM_BIND_OP_MAP;
bind.num_syncs = 1;
bind.syncs = reinterpret_cast<uintptr_t>(&sync);
if (vmBindParams.handle & XE_USERPTR_FAKE_FLAG) {
bind.bind.obj = 0;
bind.bind.obj_offset = bindInfo[found].userptr;
bind.bind.op = XE_VM_BIND_OP_MAP_USERPTR;
}
if (!bindOp) {
bind.bind.range = vmBindParams.length;
bind.bind.addr = gmmHelper->decanonize(vmBindParams.start);
bind.bind.flags = XE_VM_BIND_FLAG_ASYNC;
bind.bind.obj_offset = vmBindParams.offset;
if (isBind) {
bind.bind.op = XE_VM_BIND_OP_MAP;
bind.bind.obj = vmBindParams.handle;
if (bindInfo[index].handle & XE_USERPTR_FAKE_FLAG) {
bind.bind.op = XE_VM_BIND_OP_MAP_USERPTR;
bind.bind.obj = 0;
bind.bind.obj_offset = bindInfo[index].userptr;
}
} else {
bind.bind.op = XE_VM_BIND_OP_UNMAP;
bind.bind.obj = 0;
if (bindInfo[found].handle & XE_USERPTR_FAKE_FLAG) {
bind.bind.obj_offset = bindInfo[found].userptr;
if (bindInfo[index].handle & XE_USERPTR_FAKE_FLAG) {
bind.bind.obj_offset = bindInfo[index].userptr;
}
}
bind.bind.op |= extraBindFlag;
bindInfo[found].addr = bind.bind.addr;
xeLog(" vm=%d obj=0x%x off=0x%llx range=0x%llx addr=0x%llx op=%d(%s) nsy=%d\n",
bindInfo[index].addr = bind.bind.addr;
ret = IoctlHelper::ioctl(DrmIoctl::GemVmBind, &bind);
xeLog(" vm=%d obj=0x%x off=0x%llx range=0x%llx addr=0x%llx operation=%d(%s) flags=%d(%s) nsy=%d ret=%d\n",
bind.vm_id,
bind.bind.obj,
bind.bind.obj_offset,
bind.bind.range,
bind.bind.addr,
bind.bind.op,
xeGetBindOpName(bind.bind.op),
bind.num_syncs);
ret = IoctlHelper::ioctl(DrmIoctl::GemVmBind, &bind);
xeGetBindOperationName(bind.bind.op),
bind.bind.flags,
xeGetBindFlagsName(bind.bind.flags),
bind.num_syncs,
ret);
if (ret != 0) {
xeLog("error: %s\n", operation);
return ret;
}
@@ -1291,8 +1376,8 @@ int IoctlHelperXe::xeVmBind(const VmBindParams &vmBindParams, bool bindOp) {
sync[0].timeline_value, XE_ONE_SEC);
}
xeLog(" -> IoctlHelperXe::%s %s found=%d vmid=0x%x h=0x%x s=0x%llx o=0x%llx l=0x%llx f=0x%llx r=%d\n",
__FUNCTION__, operation, found, vmBindParams.vmId,
xeLog("error: -> IoctlHelperXe::%s %s index=%d vmid=0x%x h=0x%x s=0x%llx o=0x%llx l=0x%llx f=0x%llx r=%d\n",
__FUNCTION__, operation, index, vmBindParams.vmId,
vmBindParams.handle, vmBindParams.start, vmBindParams.offset,
vmBindParams.length, vmBindParams.flags, ret);
@@ -1406,8 +1491,7 @@ std::string IoctlHelperXe::getFileForMaxMemoryFrequencyOfSubDevice(int subDevice
return "/device/gt" + std::to_string(subDeviceId) + "/freq_rp0";
}
struct drm_xe_engine_class_instance *
IoctlHelperXe::xeFindMatchingEngine(uint16_t engineClass, uint16_t engineInstance) {
drm_xe_engine_class_instance *IoctlHelperXe::xeFindMatchingEngine(uint16_t engineClass, uint16_t engineInstance) {
for (auto &engine : allEngines) {
if (engine.engine_class == engineClass &&
(engineInstance == XE_FIND_INVALID_INSTANCE || engine.engine_instance == engineInstance)) {
@@ -1443,4 +1527,4 @@ void IoctlHelperXe::fillBindInfoForIpcHandle(uint32_t handle, size_t size) {
bool IoctlHelperXe::isImmediateVmBindRequired() const {
return true;
}
} // namespace NEO
} // namespace NEO

View File

@@ -28,6 +28,8 @@ struct drm_xe_engine_class_instance;
namespace NEO {
enum class EngineClass : uint16_t;
struct BindInfo {
uint32_t handle;
uint64_t userptr;
@@ -107,6 +109,11 @@ class IoctlHelperXe : public IoctlHelper {
std::unique_ptr<MemoryInfo> createMemoryInfo() override;
void getTopologyData(size_t nTiles, std::vector<std::bitset<8>> *geomDss, std::vector<std::bitset<8>> *computeDss, std::vector<std::bitset<8>> *euDss, DrmQueryTopologyData &topologyData, bool &isComputeDssEmpty);
void getTopologyMap(size_t nTiles, std::vector<std::bitset<8>> *dssInfo, TopologyMap &topologyMap);
bool setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) override;
void initializeGetGpuTimeFunction() override{};
bool getTimestampFrequency(uint64_t &frequency);
void fillBindInfoForIpcHandle(uint32_t handle, size_t size) override;
bool isImmediateVmBindRequired() const override;
@@ -114,11 +121,13 @@ class IoctlHelperXe : public IoctlHelper {
template <typename... XeLogArgs>
void xeLog(XeLogArgs &&...args) const;
int xeGetQuery(Query *data);
struct drm_xe_engine_class_instance *xeFindMatchingEngine(uint16_t engineClass, uint16_t engineInstance);
drm_xe_engine_class_instance *xeFindMatchingEngine(uint16_t engineClass, uint16_t engineInstance);
protected:
const char *xeGetClassName(int className);
const char *xeGetBindOpName(int bindOp);
const char *xeGetBindOperationName(int bindOperation);
const char *xeGetBindFlagsName(int bindFlags);
const char *xeGetengineClassName(uint32_t engineClass);
template <typename DataType>
std::vector<DataType> queryData(uint32_t queryId);
@@ -134,6 +143,8 @@ class IoctlHelperXe : public IoctlHelper {
uint64_t value;
};
void setDefaultEngine();
protected:
int chipsetId = 0;
int revId = 0;
@@ -149,6 +160,8 @@ class IoctlHelperXe : public IoctlHelper {
std::vector<uint32_t> hwconfigFakei915;
std::vector<drm_xe_engine_class_instance> contextParamEngine;
std::vector<drm_xe_engine_class_instance> allEngines;
drm_xe_engine_class_instance *defaultEngine = nullptr;
};
} // namespace NEO
} // namespace NEO

View File

@@ -44,7 +44,6 @@ class MockOSTimeLinux : public OSTimeLinux {
void updateDrm(Drm *drm) {
osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
static_cast<MockDeviceTimeDrm *>(this->deviceTime.get())->pDrm = drm;
static_cast<MockDeviceTimeDrm *>(this->deviceTime.get())->timestampTypeDetect();
}
static std::unique_ptr<MockOSTimeLinux> create(OSInterface &osInterface) {
return std::unique_ptr<MockOSTimeLinux>(new MockOSTimeLinux(osInterface));

View File

@@ -14,6 +14,7 @@
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/variable_backup.h"
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/test/common/mocks/linux/mock_os_time_linux.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h"
#include "shared/test/common/test_macros/hw_test.h"
@@ -26,6 +27,12 @@ using namespace NEO;
extern std::vector<uint64_t> getRegionInfo(const std::vector<MemoryRegion> &inputRegions);
extern std::vector<uint64_t> getEngineInfo(const std::vector<EngineCapabilities> &inputEngines);
namespace NEO {
bool getGpuTimeSplitted(Drm &drm, uint64_t *timestamp);
bool getGpuTime32(Drm &drm, uint64_t *timestamp);
bool getGpuTime36(Drm &drm, uint64_t *timestamp);
} // namespace NEO
struct IoctlPrelimHelperTests : ::testing::Test {
MockExecutionEnvironment executionEnvironment{};
std::unique_ptr<Drm> drm{Drm::create(std::make_unique<HwDeviceIdDrm>(0, ""), *executionEnvironment.rootDeviceEnvironments[0])};
@@ -595,3 +602,90 @@ TEST_F(IoctlPrelimHelperTests, WhenSetupIpVersionIsCalledThenIpVersionIsCorrect)
ioctlHelper.setupIpVersion();
EXPECT_EQ(config, hwInfo.ipVersion.value);
}
TEST_F(IoctlPrelimHelperTests, whenGettingGpuTimeThenSucceeds) {
MockExecutionEnvironment executionEnvironment{};
auto drm = std::make_unique<DrmMockTime>(mockFd, *executionEnvironment.rootDeviceEnvironments[0]);
ASSERT_NE(nullptr, drm);
IoctlHelperPrelim20 ioctlHelper{*drm};
ASSERT_EQ(true, ioctlHelper.initialize());
uint64_t time = 0;
auto success = getGpuTime32(*drm.get(), &time);
EXPECT_TRUE(success);
EXPECT_NE(0ULL, time);
success = getGpuTime36(*drm.get(), &time);
EXPECT_TRUE(success);
EXPECT_NE(0ULL, time);
success = getGpuTimeSplitted(*drm.get(), &time);
EXPECT_TRUE(success);
EXPECT_NE(0ULL, time);
}
TEST_F(IoctlPrelimHelperTests, givenInvalidDrmWhenGettingGpuTimeThenFails) {
MockExecutionEnvironment executionEnvironment{};
auto drm = std::make_unique<DrmMockFail>(*executionEnvironment.rootDeviceEnvironments[0]);
ASSERT_NE(nullptr, drm);
IoctlHelperPrelim20 ioctlHelper{*drm};
ASSERT_EQ(true, ioctlHelper.initialize());
uint64_t time = 0;
auto success = getGpuTime32(*drm.get(), &time);
EXPECT_FALSE(success);
success = getGpuTime36(*drm.get(), &time);
EXPECT_FALSE(success);
success = getGpuTimeSplitted(*drm.get(), &time);
EXPECT_FALSE(success);
}
TEST_F(IoctlPrelimHelperTests, whenGettingTimeThenTimeIsCorrect) {
MockExecutionEnvironment executionEnvironment{};
auto drm = std::make_unique<DrmMockCustom>(*executionEnvironment.rootDeviceEnvironments[0]);
ASSERT_NE(nullptr, drm);
IoctlHelperPrelim20 ioctlHelper{*drm};
ASSERT_EQ(true, ioctlHelper.initialize());
{
auto p = ioctlHelper.getGpuTime;
bool (*const *ptr)(Drm &, uint64_t *) = p.target<bool (*)(Drm &, uint64_t *)>();
EXPECT_EQ(*ptr, &::NEO::getGpuTime36);
}
{
drm->ioctlRes = -1;
ioctlHelper.initializeGetGpuTimeFunction();
auto p = ioctlHelper.getGpuTime;
bool (*const *ptr)(Drm &, uint64_t *) = p.target<bool (*)(Drm &, uint64_t *)>();
EXPECT_EQ(*ptr, &::NEO::getGpuTime32);
}
DrmMockCustom::IoctlResExt ioctlToPass = {1, 0};
{
drm->reset();
drm->ioctlRes = -1;
drm->ioctlResExt = &ioctlToPass; // 2nd ioctl is successful
ioctlHelper.initializeGetGpuTimeFunction();
auto p = ioctlHelper.getGpuTime;
bool (*const *ptr)(Drm &, uint64_t *) = p.target<bool (*)(Drm &, uint64_t *)>();
EXPECT_EQ(*ptr, &::NEO::getGpuTimeSplitted);
drm->ioctlResExt = &drm->none;
}
}
TEST_F(IoctlPrelimHelperTests, givenInitializeGetGpuTimeFunctionNotCalledWhenSetGpuCpuTimesIsCalledThenFalseIsReturned) {
MockExecutionEnvironment executionEnvironment{};
auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0];
rootDeviceEnvironment.osInterface = std::make_unique<OSInterface>();
rootDeviceEnvironment.osInterface->setDriverModel(std::make_unique<DrmMockTime>(mockFd, rootDeviceEnvironment));
auto drm = std::make_unique<DrmMockCustom>(rootDeviceEnvironment);
IoctlHelperPrelim20 ioctlHelper{*drm};
drm->ioctlRes = -1;
TimeStampData pGpuCpuTime{};
std::unique_ptr<MockOSTimeLinux> osTime = MockOSTimeLinux::create(*rootDeviceEnvironment.osInterface);
auto ret = ioctlHelper.setGpuCpuTimes(&pGpuCpuTime, osTime.get());
EXPECT_EQ(false, ret);
}

View File

@@ -12,19 +12,36 @@
#include "shared/source/os_interface/product_helper.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/default_hw_info.h"
#include "shared/test/common/mocks/linux/mock_os_time_linux.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/test_macros/test.h"
#include "shared/test/unit_test/os_interface/linux/drm_mock_impl.h"
using namespace NEO;
namespace NEO {
bool getGpuTimeSplitted(Drm &drm, uint64_t *timestamp);
bool getGpuTime32(Drm &drm, uint64_t *timestamp);
bool getGpuTime36(Drm &drm, uint64_t *timestamp);
} // namespace NEO
struct MockIoctlHelperUpstream : IoctlHelperUpstream {
using IoctlHelperUpstream::initializeGetGpuTimeFunction;
using IoctlHelperUpstream::IoctlHelperUpstream;
using IoctlHelperUpstream::isSetPatSupported;
void detectExtSetPatSupport() override {
detectExtSetPatSupportCallCount++;
size_t currentIoctlCallCount = ioctlCallCount;
IoctlHelperUpstream::detectExtSetPatSupport();
detectExtSetPatSupportIoctlCallCount += ioctlCallCount - currentIoctlCallCount;
}
void initializeGetGpuTimeFunction() override {
initializeGetGpuTimeFunctionCallCount++;
size_t currentIoctlCallCount = ioctlCallCount;
IoctlHelperUpstream::initializeGetGpuTimeFunction();
initializeGetGpuTimeFunctionIoctlCallCount += ioctlCallCount - currentIoctlCallCount;
}
int ioctl(DrmIoctl request, void *arg) override {
@@ -51,6 +68,9 @@ struct MockIoctlHelperUpstream : IoctlHelperUpstream {
}
size_t detectExtSetPatSupportCallCount = 0;
size_t detectExtSetPatSupportIoctlCallCount = 0;
size_t initializeGetGpuTimeFunctionCallCount = 0;
size_t initializeGetGpuTimeFunctionIoctlCallCount = 0;
size_t ioctlCallCount = 0;
std::optional<int> overrideGemCreateExtReturnValue{};
bool lastGemCreateContainedSetPat = false;
@@ -63,31 +83,48 @@ TEST(IoctlHelperUpstreamTest, whenInitializeIsCalledThenDetectExtSetPatSupportFu
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto drm = std::make_unique<DrmTipMock>(*executionEnvironment->rootDeviceEnvironments[0]);
MockIoctlHelperUpstream mockIoctlHelper{*drm};
EXPECT_EQ(0u, mockIoctlHelper.detectExtSetPatSupportCallCount);
EXPECT_FALSE(mockIoctlHelper.lastGemCreateContainedSetPat);
EXPECT_EQ(0u, mockIoctlHelper.ioctlCallCount);
EXPECT_EQ(0u, mockIoctlHelper.detectExtSetPatSupportIoctlCallCount);
mockIoctlHelper.overrideGemCreateExtReturnValue = 0;
mockIoctlHelper.initialize();
EXPECT_EQ(1u, mockIoctlHelper.detectExtSetPatSupportCallCount);
EXPECT_TRUE(mockIoctlHelper.lastGemCreateContainedSetPat);
EXPECT_EQ(2u, mockIoctlHelper.ioctlCallCount); // create and close
EXPECT_EQ(2u, mockIoctlHelper.detectExtSetPatSupportIoctlCallCount); // create and close
EXPECT_TRUE(mockIoctlHelper.isSetPatSupported);
mockIoctlHelper.overrideGemCreateExtReturnValue = -1;
mockIoctlHelper.initialize();
EXPECT_EQ(2u, mockIoctlHelper.detectExtSetPatSupportCallCount);
EXPECT_TRUE(mockIoctlHelper.lastGemCreateContainedSetPat);
EXPECT_EQ(3u, mockIoctlHelper.ioctlCallCount); // only create
EXPECT_EQ(3u, mockIoctlHelper.detectExtSetPatSupportIoctlCallCount); // only create
EXPECT_FALSE(mockIoctlHelper.isSetPatSupported);
DebugManager.flags.DisableGemCreateExtSetPat.set(true);
mockIoctlHelper.initialize();
EXPECT_EQ(3u, mockIoctlHelper.detectExtSetPatSupportCallCount);
EXPECT_EQ(3u, mockIoctlHelper.ioctlCallCount); // no ioctl calls
EXPECT_EQ(3u, mockIoctlHelper.detectExtSetPatSupportIoctlCallCount); // no ioctl calls
EXPECT_FALSE(mockIoctlHelper.isSetPatSupported);
}
TEST(IoctlHelperUpstreamTest, whenInitializeIsCalledThenInitializeGetGpuTimeFunctiontFunctionIsCalled) {
DebugManagerStateRestore stateRestore;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto drm = std::make_unique<DrmTipMock>(*executionEnvironment->rootDeviceEnvironments[0]);
MockIoctlHelperUpstream mockIoctlHelper{*drm};
EXPECT_EQ(0u, mockIoctlHelper.initializeGetGpuTimeFunctionCallCount);
EXPECT_EQ(0u, mockIoctlHelper.initializeGetGpuTimeFunctionIoctlCallCount);
mockIoctlHelper.initialize();
EXPECT_EQ(1u, mockIoctlHelper.initializeGetGpuTimeFunctionCallCount);
EXPECT_EQ(2u, mockIoctlHelper.initializeGetGpuTimeFunctionIoctlCallCount);
EXPECT_NE(nullptr, mockIoctlHelper.getGpuTime);
}
TEST(IoctlHelperUpstreamTest, whenGettingVmBindAvailabilityThenFalseIsReturned) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto drm = std::make_unique<DrmTipMock>(*executionEnvironment->rootDeviceEnvironments[0]);
@@ -675,3 +712,90 @@ TEST(IoctlHelperTestsUpstream, WhenSetupIpVersionIsCalledThenIpVersionIsCorrect)
ioctlHelper.setupIpVersion();
EXPECT_EQ(config, hwInfo.ipVersion.value);
}
TEST(IoctlHelperTestsUpstream, whenGettingGpuTimeThenSucceeds) {
MockExecutionEnvironment executionEnvironment{};
auto drm = std::make_unique<DrmMockTime>(mockFd, *executionEnvironment.rootDeviceEnvironments[0]);
ASSERT_NE(nullptr, drm);
IoctlHelperUpstream ioctlHelper{*drm};
ASSERT_EQ(true, ioctlHelper.initialize());
uint64_t time = 0;
auto success = getGpuTime32(*drm.get(), &time);
EXPECT_TRUE(success);
EXPECT_NE(0ULL, time);
success = getGpuTime36(*drm.get(), &time);
EXPECT_TRUE(success);
EXPECT_NE(0ULL, time);
success = getGpuTimeSplitted(*drm.get(), &time);
EXPECT_TRUE(success);
EXPECT_NE(0ULL, time);
}
TEST(IoctlHelperTestsUpstream, givenInvalidDrmWhenGettingGpuTimeThenFails) {
MockExecutionEnvironment executionEnvironment{};
auto drm = std::make_unique<DrmMockFail>(*executionEnvironment.rootDeviceEnvironments[0]);
ASSERT_NE(nullptr, drm);
IoctlHelperUpstream ioctlHelper{*drm};
ASSERT_EQ(true, ioctlHelper.initialize());
uint64_t time = 0;
auto success = getGpuTime32(*drm.get(), &time);
EXPECT_FALSE(success);
success = getGpuTime36(*drm.get(), &time);
EXPECT_FALSE(success);
success = getGpuTimeSplitted(*drm.get(), &time);
EXPECT_FALSE(success);
}
TEST(IoctlHelperTestsUpstream, whenGettingTimeThenTimeIsCorrect) {
MockExecutionEnvironment executionEnvironment{};
auto drm = std::make_unique<DrmMockCustom>(*executionEnvironment.rootDeviceEnvironments[0]);
ASSERT_NE(nullptr, drm);
IoctlHelperUpstream ioctlHelper{*drm};
ASSERT_EQ(true, ioctlHelper.initialize());
{
auto p = ioctlHelper.getGpuTime;
bool (*const *ptr)(Drm &, uint64_t *) = p.target<bool (*)(Drm &, uint64_t *)>();
EXPECT_EQ(*ptr, &::NEO::getGpuTime36);
}
{
drm->ioctlRes = -1;
ioctlHelper.initializeGetGpuTimeFunction();
auto p = ioctlHelper.getGpuTime;
bool (*const *ptr)(Drm &, uint64_t *) = p.target<bool (*)(Drm &, uint64_t *)>();
EXPECT_EQ(*ptr, &::NEO::getGpuTime32);
}
DrmMockCustom::IoctlResExt ioctlToPass = {1, 0};
{
drm->reset();
drm->ioctlRes = -1;
drm->ioctlResExt = &ioctlToPass; // 2nd ioctl is successful
ioctlHelper.initializeGetGpuTimeFunction();
auto p = ioctlHelper.getGpuTime;
bool (*const *ptr)(Drm &, uint64_t *) = p.target<bool (*)(Drm &, uint64_t *)>();
EXPECT_EQ(*ptr, &::NEO::getGpuTimeSplitted);
drm->ioctlResExt = &drm->none;
}
}
TEST(IoctlHelperTestsUpstream, givenInitializeGetGpuTimeFunctionNotCalledWhenSetGpuCpuTimesIsCalledThenFalseIsReturned) {
MockExecutionEnvironment executionEnvironment{};
auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0];
rootDeviceEnvironment.osInterface = std::make_unique<OSInterface>();
rootDeviceEnvironment.osInterface->setDriverModel(std::make_unique<DrmMockTime>(mockFd, rootDeviceEnvironment));
auto drm = std::make_unique<DrmMockCustom>(rootDeviceEnvironment);
IoctlHelperUpstream ioctlHelper{*drm};
drm->ioctlRes = -1;
TimeStampData pGpuCpuTime{};
std::unique_ptr<MockOSTimeLinux> osTime = MockOSTimeLinux::create(*rootDeviceEnvironment.osInterface);
auto ret = ioctlHelper.setGpuCpuTimes(&pGpuCpuTime, osTime.get());
EXPECT_EQ(false, ret);
}

View File

@@ -6,6 +6,7 @@
*/
#include "shared/source/os_interface/linux/drm_neo.h"
#include "shared/source/os_interface/linux/ioctl_helper.h"
#include "shared/source/os_interface/linux/os_time_linux.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/test/common/mocks/linux/mock_os_time_linux.h"
@@ -71,33 +72,6 @@ TEST_F(DrmTimeTest, GivenFalseTimeFuncWhenGettingCpuTimeThenFails) {
EXPECT_FALSE(error);
}
TEST_F(DrmTimeTest, WhenGettingGpuTimeThenSuceeds) {
uint64_t time = 0;
auto pDrm = new DrmMockTime(mockFd, *executionEnvironment.rootDeviceEnvironments[0]);
osTime->updateDrm(pDrm);
auto error = osTime->getDeviceTime()->getGpuTime32(&time);
EXPECT_TRUE(error);
EXPECT_NE(0ULL, time);
error = osTime->getDeviceTime()->getGpuTime36(&time);
EXPECT_TRUE(error);
EXPECT_NE(0ULL, time);
error = osTime->getDeviceTime()->getGpuTimeSplitted(&time);
EXPECT_TRUE(error);
EXPECT_NE(0ULL, time);
}
TEST_F(DrmTimeTest, GivenInvalidDrmWhenGettingGpuTimeThenFails) {
uint64_t time = 0;
auto pDrm = new DrmMockFail(*executionEnvironment.rootDeviceEnvironments[0]);
osTime->updateDrm(pDrm);
auto error = osTime->getDeviceTime()->getGpuTime32(&time);
EXPECT_FALSE(error);
error = osTime->getDeviceTime()->getGpuTime36(&time);
EXPECT_FALSE(error);
error = osTime->getDeviceTime()->getGpuTimeSplitted(&time);
EXPECT_FALSE(error);
}
TEST_F(DrmTimeTest, WhenGettingGpuCpuTimeThenSucceeds) {
TimeStampData gpuCpuTime01 = {0, 0};
TimeStampData gpuCpuTime02 = {0, 0};
@@ -220,34 +194,6 @@ TEST_F(DrmTimeTest, GivenInvalidFuncTimeWhenGettingGpuCpuTimeCpuThenFails) {
EXPECT_FALSE(error);
}
TEST_F(DrmTimeTest, WhenGettingTimeThenTimeIsCorrect) {
auto drm = new DrmMockCustom(*executionEnvironment.rootDeviceEnvironments[0]);
osTime->updateDrm(drm);
{
auto p = osTime->getDeviceTime()->getGpuTime;
EXPECT_EQ(p, &DeviceTimeDrm::getGpuTime36);
}
{
drm->ioctlRes = -1;
osTime->getDeviceTime()->timestampTypeDetect();
auto p = osTime->getDeviceTime()->getGpuTime;
EXPECT_EQ(p, &DeviceTimeDrm::getGpuTime32);
}
DrmMockCustom::IoctlResExt ioctlToPass = {1, 0};
{
drm->reset();
drm->ioctlRes = -1;
drm->ioctlResExt = &ioctlToPass; // 2nd ioctl is successful
osTime->getDeviceTime()->timestampTypeDetect();
auto p = osTime->getDeviceTime()->getGpuTime;
EXPECT_EQ(p, &DeviceTimeDrm::getGpuTimeSplitted);
drm->ioctlResExt = &drm->none;
}
}
TEST_F(DrmTimeTest, givenGpuTimestampResolutionQueryWhenIoctlFailsThenDefaultResolutionIsReturned) {
auto defaultResolution = defaultHwInfo->capabilityTable.defaultProfilingTimerResolution;

View File

@@ -17,6 +17,7 @@
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/default_hw_info.h"
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/test/common/mocks/linux/mock_os_time_linux.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/test_macros/test.h"
@@ -26,12 +27,14 @@ using namespace NEO;
struct MockIoctlHelperXe : IoctlHelperXe {
using IoctlHelperXe::bindInfo;
using IoctlHelperXe::defaultEngine;
using IoctlHelperXe::IoctlHelperXe;
using IoctlHelperXe::xeGetBindOpName;
using IoctlHelperXe::setDefaultEngine;
using IoctlHelperXe::xeGetBindFlagsName;
using IoctlHelperXe::xeGetBindOperationName;
using IoctlHelperXe::xeGetClassName;
using IoctlHelperXe::xeGetengineClassName;
using IoctlHelperXe::xeShowBindTable;
using IoctlHelperXe::xeTimestampFrequency;
};
TEST(IoctlHelperXeTest, givenXeDrmVersionsWhenGettingIoctlHelperThenValidIoctlHelperIsReturned) {
@@ -145,31 +148,28 @@ class DrmMockXe : public DrmMockCustom {
MemoryConstants::gigaByte // used size
};
auto xeQueryGts = reinterpret_cast<drm_xe_query_gts *>(queryGts.begin());
xeQueryGts->num_gt = 3;
xeQueryGts->gts[0] = {
auto xeQueryGtList = reinterpret_cast<drm_xe_query_gt_list *>(queryGtList.begin());
xeQueryGtList->num_gt = 3;
xeQueryGtList->gt_list[0] = {
XE_QUERY_GT_TYPE_MAIN, // type
0, // instance
12500000, // clock freq
0, // features
0, // gt_id
12500000, // clock_freq
0b100, // native mem regions
0x011, // slow mem regions
0 // inaccessible mem regions
};
xeQueryGts->gts[1] = {
xeQueryGtList->gt_list[1] = {
XE_QUERY_GT_TYPE_MEDIA, // type
1, // instance
1, // gt_id
12500000, // clock freq
0, // features
0b001, // native mem regions
0x110, // slow mem regions
0 // inaccessible mem regions
};
xeQueryGts->gts[2] = {
xeQueryGtList->gt_list[2] = {
XE_QUERY_GT_TYPE_MAIN, // type
0, // instance
0, // gt_id
12500000, // clock freq
0, // features
0b010, // native mem regions
0x101, // slow mem regions
0 // inaccessible mem regions
@@ -187,11 +187,6 @@ class DrmMockXe : public DrmMockCustom {
return setIoctlAnswer;
}
switch (request) {
case DrmIoctl::RegRead: {
struct drm_xe_mmio *reg = static_cast<struct drm_xe_mmio *>(arg);
reg->value = reg->addr;
ret = 0;
} break;
case DrmIoctl::GemVmCreate: {
struct drm_xe_vm_create *v = static_cast<struct drm_xe_vm_create *>(arg);
v->vm_id = testValueVmId;
@@ -257,11 +252,11 @@ class DrmMockXe : public DrmMockCustom {
}
deviceQuery->size = sizeof(queryMemUsage);
break;
case DRM_XE_DEVICE_QUERY_GTS:
case DRM_XE_DEVICE_QUERY_GT_LIST:
if (deviceQuery->data) {
memcpy_s(reinterpret_cast<void *>(deviceQuery->data), deviceQuery->size, queryGts.begin(), sizeof(queryGts));
memcpy_s(reinterpret_cast<void *>(deviceQuery->data), deviceQuery->size, queryGtList.begin(), sizeof(queryGtList));
}
deviceQuery->size = sizeof(queryGts);
deviceQuery->size = sizeof(queryGtList);
break;
case DRM_XE_DEVICE_QUERY_GT_TOPOLOGY:
if (deviceQuery->data) {
@@ -269,6 +264,12 @@ class DrmMockXe : public DrmMockCustom {
}
deviceQuery->size = static_cast<unsigned int>(queryTopology.size());
break;
case DRM_XE_DEVICE_QUERY_ENGINE_CYCLES:
if (deviceQuery->data) {
memcpy_s(reinterpret_cast<void *>(deviceQuery->data), deviceQuery->size, queryEngineCycles, sizeof(queryEngineCycles));
}
deviceQuery->size = sizeof(queryEngineCycles);
break;
};
ret = 0;
} break;
@@ -335,9 +336,11 @@ class DrmMockXe : public DrmMockCustom {
static_assert(sizeof(drm_xe_query_mem_region) == 12 * sizeof(uint64_t), "");
uint64_t queryMemUsage[37]{}; // 1 qword for num regions and 12 qwords per region
static_assert(sizeof(drm_xe_query_gts::drm_xe_query_gt) == 13 * sizeof(uint64_t), "");
StackVec<uint64_t, 40> queryGts{}; // 1 qword for num gts and 13 qwords per gt
std::vector<uint8_t> queryTopology;
static_assert(sizeof(drm_xe_query_gt) == 12 * sizeof(uint64_t), "");
StackVec<uint64_t, 37> queryGtList{}; // 1 qword for num gts and 12 qwords per gt
alignas(64) std::vector<uint8_t> queryTopology;
static_assert(sizeof(drm_xe_query_engine_cycles) == 6 * sizeof(uint64_t), "");
uint64_t queryEngineCycles[6]{}; // 1 qword for eci and 5 qwords
StackVec<drm_xe_wait_user_fence, 1> waitUserFenceInputs;
StackVec<drm_xe_vm_bind, 1> vmBindInputs;
StackVec<drm_xe_sync, 1> syncInputs;
@@ -644,7 +647,6 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsRe
verifyIoctlString(DrmIoctl::GemWaitUserFence, "DRM_IOCTL_XE_WAIT_USER_FENCE");
verifyIoctlString(DrmIoctl::PrimeFdToHandle, "DRM_IOCTL_PRIME_FD_TO_HANDLE");
verifyIoctlString(DrmIoctl::PrimeHandleToFd, "DRM_IOCTL_PRIME_HANDLE_TO_FD");
verifyIoctlString(DrmIoctl::RegRead, "DRM_IOCTL_XE_MMIO");
EXPECT_TRUE(xeIoctlHelper->completionFenceExtensionSupported(true));
@@ -685,7 +687,6 @@ TEST(IoctlHelperXeTest, whenGettingIoctlRequestValueThenPropertValueIsReturned)
verifyIoctlRequestValue(DRM_IOCTL_XE_EXEC_QUEUE_DESTROY, DrmIoctl::GemContextDestroy);
verifyIoctlRequestValue(DRM_IOCTL_PRIME_FD_TO_HANDLE, DrmIoctl::PrimeFdToHandle);
verifyIoctlRequestValue(DRM_IOCTL_PRIME_HANDLE_TO_FD, DrmIoctl::PrimeHandleToFd);
verifyIoctlRequestValue(DRM_IOCTL_XE_MMIO, DrmIoctl::RegRead);
EXPECT_THROW(xeIoctlHelper->getIoctlRequestValue(DrmIoctl::DebuggerOpen), std::runtime_error);
}
@@ -701,8 +702,12 @@ TEST(IoctlHelperXeTest, verifyPublicFunctions) {
EXPECT_STREQ(name, mockXeIoctlHelper->xeGetClassName(xeClass));
};
auto verifyXeOpBindName = [&mockXeIoctlHelper](const char *name, auto bind) {
EXPECT_STREQ(name, mockXeIoctlHelper->xeGetBindOpName(bind));
auto verifyXeOperationBindName = [&mockXeIoctlHelper](const char *name, auto bind) {
EXPECT_STREQ(name, mockXeIoctlHelper->xeGetBindOperationName(bind));
};
auto verifyXeFlagsBindName = [&mockXeIoctlHelper](const char *name, auto flags) {
EXPECT_STREQ(name, mockXeIoctlHelper->xeGetBindFlagsName(flags));
};
auto verifyXeEngineClassName = [&mockXeIoctlHelper](const char *name, auto engineClass) {
@@ -715,12 +720,18 @@ TEST(IoctlHelperXeTest, verifyPublicFunctions) {
verifyXeClassName("vecs", DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE);
verifyXeClassName("ccs", DRM_XE_ENGINE_CLASS_COMPUTE);
verifyXeOpBindName("MAP", XE_VM_BIND_OP_MAP);
verifyXeOpBindName("UNMAP", XE_VM_BIND_OP_UNMAP);
verifyXeOpBindName("MAP_USERPTR", XE_VM_BIND_OP_MAP_USERPTR);
verifyXeOpBindName("AS_MAP", XE_VM_BIND_OP_MAP | XE_VM_BIND_FLAG_ASYNC);
verifyXeOpBindName("AS_MAP_USERPTR", XE_VM_BIND_OP_MAP_USERPTR | XE_VM_BIND_FLAG_ASYNC);
verifyXeOpBindName("unknown_OP", -1);
verifyXeOperationBindName("MAP", XE_VM_BIND_OP_MAP);
verifyXeOperationBindName("UNMAP", XE_VM_BIND_OP_UNMAP);
verifyXeOperationBindName("MAP_USERPTR", XE_VM_BIND_OP_MAP_USERPTR);
verifyXeOperationBindName("UNMAP ALL", XE_VM_BIND_OP_UNMAP_ALL);
verifyXeOperationBindName("PREFETCH", XE_VM_BIND_OP_PREFETCH);
verifyXeOperationBindName("Unknown operation", -1);
verifyXeFlagsBindName("READ_ONLY", XE_VM_BIND_FLAG_READONLY);
verifyXeFlagsBindName("ASYNC", XE_VM_BIND_FLAG_ASYNC);
verifyXeFlagsBindName("IMMEDIATE", XE_VM_BIND_FLAG_IMMEDIATE);
verifyXeFlagsBindName("NULL", XE_VM_BIND_FLAG_NULL);
verifyXeFlagsBindName("Unknown flag", -1);
verifyXeEngineClassName("DRM_XE_ENGINE_CLASS_RENDER", DRM_XE_ENGINE_CLASS_RENDER);
verifyXeEngineClassName("DRM_XE_ENGINE_CLASS_COPY", DRM_XE_ENGINE_CLASS_COPY);
@@ -767,8 +778,7 @@ TEST(IoctlHelperXeTest, whenCallingIoctlThenProperValueIsReturned) {
DebugManagerStateRestore restorer;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXe>(drm);
auto mockXeIoctlHelper = static_cast<MockIoctlHelperXe *>(xeIoctlHelper.get());
auto mockXeIoctlHelper = std::make_unique<MockIoctlHelperXe>(drm);
drm.reset();
{
@@ -787,17 +797,10 @@ TEST(IoctlHelperXeTest, whenCallingIoctlThenProperValueIsReturned) {
ret = mockXeIoctlHelper->ioctl(DrmIoctl::GemClose, &cl);
EXPECT_EQ(0, ret);
}
{
RegisterRead test = {};
test.offset = REG_GLOBAL_TIMESTAMP_LDW;
ret = mockXeIoctlHelper->ioctl(DrmIoctl::RegRead, &test);
EXPECT_EQ(0, ret);
EXPECT_EQ(test.offset, test.value);
}
{
GemVmControl test = {};
drm.pageFaultSupported = false;
uint32_t expectedVmCreateFlags = DRM_XE_VM_CREATE_ASYNC_BIND_OPS |
uint32_t expectedVmCreateFlags = DRM_XE_VM_CREATE_ASYNC_DEFAULT |
DRM_XE_VM_CREATE_COMPUTE_MODE;
ret = mockXeIoctlHelper->ioctl(DrmIoctl::GemVmCreate, &test);
EXPECT_EQ(0, ret);
@@ -805,7 +808,7 @@ TEST(IoctlHelperXeTest, whenCallingIoctlThenProperValueIsReturned) {
EXPECT_EQ(test.flags, expectedVmCreateFlags);
drm.pageFaultSupported = true;
expectedVmCreateFlags = DRM_XE_VM_CREATE_ASYNC_BIND_OPS |
expectedVmCreateFlags = DRM_XE_VM_CREATE_ASYNC_DEFAULT |
DRM_XE_VM_CREATE_COMPUTE_MODE |
DRM_XE_VM_CREATE_FAULT_MODE;
ret = mockXeIoctlHelper->ioctl(DrmIoctl::GemVmCreate, &test);
@@ -898,6 +901,8 @@ TEST(IoctlHelperXeTest, whenCallingIoctlThenProperValueIsReturned) {
ret = mockXeIoctlHelper->ioctl(DrmIoctl::GemClose, &test);
EXPECT_EQ(0, ret);
}
auto engineInfo = mockXeIoctlHelper->createEngineInfo(false);
EXPECT_NE(nullptr, engineInfo);
{
GetParam test = {};
int dstvalue;
@@ -1037,13 +1042,12 @@ TEST(IoctlHelperXeTest, givenOnlyMediaTypeWhenGetTopologyDataAndMapThenSubsliceI
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeQueryGts = reinterpret_cast<drm_xe_query_gts *>(drm.queryGts.begin());
xeQueryGts->num_gt = 1;
xeQueryGts->gts[0] = {
auto xeQueryGtList = reinterpret_cast<drm_xe_query_gt_list *>(drm.queryGtList.begin());
xeQueryGtList->num_gt = 1;
xeQueryGtList->gt_list[0] = {
XE_QUERY_GT_TYPE_MEDIA, // type
0, // instance
0, // gt_id
12500000, // clock freq
0, // features
0b100, // native mem regions
0x011, // slow mem regions
0 // inaccessible mem regions
@@ -1083,41 +1087,37 @@ TEST(IoctlHelperXeTest, givenMainAndMediaTypesWhenGetTopologyDataAndMapThenResul
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]};
drm.queryGts.resize(53);
auto xeQueryGts = reinterpret_cast<drm_xe_query_gts *>(drm.queryGts.begin());
xeQueryGts->num_gt = 4;
xeQueryGts->gts[0] = {
drm.queryGtList.resize(49);
auto xeQueryGtList = reinterpret_cast<drm_xe_query_gt_list *>(drm.queryGtList.begin());
xeQueryGtList->num_gt = 4;
xeQueryGtList->gt_list[0] = {
XE_QUERY_GT_TYPE_MAIN, // type
0, // instance
0, // gt_id
12500000, // clock freq
0, // features
0b100, // native mem regions
0x011, // slow mem regions
0 // inaccessible mem regions
};
xeQueryGts->gts[1] = {
xeQueryGtList->gt_list[1] = {
XE_QUERY_GT_TYPE_MEDIA, // type
0, // instance
0, // gt_id
12500000, // clock freq
0, // features
0b100, // native mem regions
0x011, // slow mem regions
0 // inaccessible mem regions
};
xeQueryGts->gts[2] = {
xeQueryGtList->gt_list[2] = {
XE_QUERY_GT_TYPE_MAIN, // type
0, // instance
0, // gt_id
12500000, // clock freq
0, // features
0b010, // native mem regions
0x101, // slow mem regions
0 // inaccessible mem regions
};
xeQueryGts->gts[3] = {
xeQueryGtList->gt_list[3] = {
XE_QUERY_GT_TYPE_MEDIA, // type
0, // instance
0, // gt_id
12500000, // clock freq
0, // features
0b001, // native mem regions
0x100, // slow mem regions
0 // inaccessible mem regions
@@ -1182,23 +1182,21 @@ struct DrmMockXe2T : public DrmMockXe {
4 * MemoryConstants::gigaByte, // total size
MemoryConstants::gigaByte // used size
};
queryGts.resize(27);
auto xeQueryGts = reinterpret_cast<drm_xe_query_gts *>(queryGts.begin());
xeQueryGts->num_gt = 2;
xeQueryGts->gts[0] = {
queryGtList.resize(25);
auto xeQueryGtList = reinterpret_cast<drm_xe_query_gt_list *>(queryGtList.begin());
xeQueryGtList->num_gt = 2;
xeQueryGtList->gt_list[0] = {
XE_QUERY_GT_TYPE_MAIN, // type
0, // instance
0, // gt_id
12500000, // clock freq
0, // features
0b100, // native mem regions
0x011, // slow mem regions
0 // inaccessible mem regions
};
xeQueryGts->gts[1] = {
xeQueryGtList->gt_list[1] = {
XE_QUERY_GT_TYPE_MAIN, // type
0, // instance
0, // gt_id
12500000, // clock freq
0, // features
0b010, // native mem regions
0x101, // slow mem regions
0 // inaccessible mem regions
@@ -1559,8 +1557,6 @@ TEST(IoctlHelperXeTest, whenCreatingMemoryInfoThenProperMemoryBanksAreDiscovered
EXPECT_EQ(1u, memoryRegions[2].region.memoryInstance);
EXPECT_EQ(2 * MemoryConstants::gigaByte, memoryRegions[2].probedSize);
EXPECT_EQ(2 * MemoryConstants::gigaByte - MemoryConstants::megaByte, memoryRegions[2].unallocatedSize);
EXPECT_EQ(12500000u, xeIoctlHelper->xeTimestampFrequency);
}
TEST(IoctlHelperXeTest, givenIoctlFailureWhenCreatingMemoryInfoThenNoMemoryBanksAreDiscovered) {
@@ -1819,3 +1815,109 @@ TEST(IoctlHelperXeTest, whenFillBindInfoForIpcHandleIsCalledThenBindInfoIsCorrec
EXPECT_EQ(bindInfo.handle, handle);
EXPECT_EQ(bindInfo.size, size);
}
TEST(IoctlHelperXeTest, givenIoctlFailureWhenGetTimestampFrequencyIsCalledThenFalseIsReturned) {
DebugManagerStateRestore restorer;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXe>(drm);
auto engineInfo = xeIoctlHelper->createEngineInfo(false);
ASSERT_NE(nullptr, engineInfo);
drm.testMode(1, -1);
uint64_t frequency;
auto ret = xeIoctlHelper->getTimestampFrequency(frequency);
EXPECT_EQ(false, ret);
}
TEST(IoctlHelperXeTest, whenGetTimestampFrequencyIsCalledThenProperFrequencyIsSet) {
DebugManagerStateRestore restorer;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXe>(drm);
auto engineInfo = xeIoctlHelper->createEngineInfo(false);
ASSERT_NE(nullptr, engineInfo);
uint64_t expectedFrequency = 100;
auto xeQueryEngineCycles = reinterpret_cast<drm_xe_query_engine_cycles *>(drm.queryEngineCycles);
xeQueryEngineCycles->engine_frequency = expectedFrequency;
uint64_t frequency = 0;
auto ret = xeIoctlHelper->getTimestampFrequency(frequency);
EXPECT_EQ(true, ret);
EXPECT_EQ(expectedFrequency, frequency);
}
TEST(IoctlHelperXeTest, givenIoctlFailureWhenSetGpuCpuTimesIsCalledThenFalseIsReturned) {
DebugManagerStateRestore restorer;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto &rootDeviceEnvironment = *executionEnvironment->rootDeviceEnvironments[0];
rootDeviceEnvironment.osInterface = std::make_unique<OSInterface>();
rootDeviceEnvironment.osInterface->setDriverModel(std::make_unique<DrmMockTime>(mockFd, rootDeviceEnvironment));
DrmMockXe drm{rootDeviceEnvironment};
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXe>(drm);
auto engineInfo = xeIoctlHelper->createEngineInfo(false);
ASSERT_NE(nullptr, engineInfo);
drm.testMode(1, -1);
TimeStampData pGpuCpuTime{};
std::unique_ptr<MockOSTimeLinux> osTime = MockOSTimeLinux::create(*rootDeviceEnvironment.osInterface);
auto ret = xeIoctlHelper->setGpuCpuTimes(&pGpuCpuTime, osTime.get());
EXPECT_EQ(false, ret);
}
TEST(IoctlHelperXeTest, givenIoctlFailureWhenSetGpuCpuTimesIsCalledThenProperValuesAreSet) {
DebugManagerStateRestore restorer;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto &rootDeviceEnvironment = *executionEnvironment->rootDeviceEnvironments[0];
rootDeviceEnvironment.osInterface = std::make_unique<OSInterface>();
rootDeviceEnvironment.osInterface->setDriverModel(std::make_unique<DrmMockTime>(mockFd, rootDeviceEnvironment));
DrmMockXe drm{rootDeviceEnvironment};
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXe>(drm);
auto engineInfo = xeIoctlHelper->createEngineInfo(false);
ASSERT_NE(nullptr, engineInfo);
uint64_t expectedCycles = 100000;
uint64_t expectedTimestamp = 100;
auto xeQueryEngineCycles = reinterpret_cast<drm_xe_query_engine_cycles *>(drm.queryEngineCycles);
xeQueryEngineCycles->width = 32;
xeQueryEngineCycles->engine_cycles = expectedCycles;
xeQueryEngineCycles->cpu_timestamp = expectedTimestamp;
TimeStampData pGpuCpuTime{};
std::unique_ptr<MockOSTimeLinux> osTime = MockOSTimeLinux::create(*rootDeviceEnvironment.osInterface);
auto ret = xeIoctlHelper->setGpuCpuTimes(&pGpuCpuTime, osTime.get());
EXPECT_EQ(true, ret);
EXPECT_EQ(pGpuCpuTime.gpuTimeStamp, expectedCycles);
EXPECT_EQ(pGpuCpuTime.cpuTimeinNS, expectedTimestamp);
}
TEST(IoctlHelperXeTest, whenSetDefaultEngineIsCalledThenProperEngineIsSet) {
NEO::HardwareInfo hwInfo = *NEO::defaultHwInfo.get();
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>(&hwInfo);
DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXe>(drm);
auto engineInfo = xeIoctlHelper->createEngineInfo(true);
ASSERT_NE(nullptr, engineInfo);
xeIoctlHelper->setDefaultEngine();
EXPECT_EQ(DRM_XE_ENGINE_CLASS_COMPUTE, xeIoctlHelper->defaultEngine->engine_class);
}
TEST(IoctlHelperXeTest, givenNoEnginesWhenSetDefaultEngineIsCalledThenAbortIsThrown) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXe>(drm);
EXPECT_THROW(xeIoctlHelper->setDefaultEngine(), std::exception);
}
TEST(IoctlHelperXeTest, givenXeIoctlHelperWhenInitializeGetGpuTimeFunctionIsCalledGetGpuFunctionIsNotSet) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeIoctlHelper = std::make_unique<MockIoctlHelperXe>(drm);
xeIoctlHelper->initializeGetGpuTimeFunction();
EXPECT_EQ(xeIoctlHelper->getGpuTime, nullptr);
}