2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2022-01-04 22:48:05 +08:00
|
|
|
* Copyright (C) 2018-2022 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-18 15:11:08 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "drm_neo.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/debug_settings/debug_settings_manager.h"
|
2020-03-17 14:26:46 +08:00
|
|
|
#include "shared/source/execution_environment/execution_environment.h"
|
2020-07-07 15:34:31 +08:00
|
|
|
#include "shared/source/execution_environment/root_device_environment.h"
|
2020-04-02 17:28:38 +08:00
|
|
|
#include "shared/source/helpers/constants.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/debug_helpers.h"
|
2020-07-07 15:34:31 +08:00
|
|
|
#include "shared/source/helpers/hw_helper.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/hw_info.h"
|
2020-06-09 21:51:26 +08:00
|
|
|
#include "shared/source/helpers/ptr_math.h"
|
2020-11-05 20:40:03 +08:00
|
|
|
#include "shared/source/os_interface/driver_info.h"
|
2022-02-03 19:13:44 +08:00
|
|
|
#include "shared/source/os_interface/linux/cache_info_impl.h"
|
2022-02-11 21:46:23 +08:00
|
|
|
#include "shared/source/os_interface/linux/drm_engine_mapper.h"
|
2021-05-21 07:17:57 +08:00
|
|
|
#include "shared/source/os_interface/linux/drm_gem_close_worker.h"
|
|
|
|
#include "shared/source/os_interface/linux/drm_memory_manager.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/linux/hw_device_id.h"
|
2021-12-14 17:46:01 +08:00
|
|
|
#include "shared/source/os_interface/linux/ioctl_helper.h"
|
2021-09-02 00:28:18 +08:00
|
|
|
#include "shared/source/os_interface/linux/os_context_linux.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/linux/os_inc.h"
|
2021-05-20 06:36:24 +08:00
|
|
|
#include "shared/source/os_interface/linux/pci_path.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/linux/sys_calls.h"
|
2020-11-24 23:00:33 +08:00
|
|
|
#include "shared/source/os_interface/linux/system_info.h"
|
2020-03-17 14:26:46 +08:00
|
|
|
#include "shared/source/os_interface/os_environment.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/os_interface.h"
|
|
|
|
#include "shared/source/utilities/directory.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2020-11-19 19:04:17 +08:00
|
|
|
#include "drm_query_flags.h"
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstring>
|
2020-02-07 21:32:02 +08:00
|
|
|
#include <linux/limits.h>
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
namespace NEO {
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2021-10-21 20:37:31 +08:00
|
|
|
Drm::Drm(std::unique_ptr<HwDeviceIdDrm> &&hwDeviceIdIn, RootDeviceEnvironment &rootDeviceEnvironment)
|
2021-05-21 07:17:57 +08:00
|
|
|
: DriverModel(DriverModelType::DRM),
|
|
|
|
hwDeviceId(std::move(hwDeviceIdIn)), rootDeviceEnvironment(rootDeviceEnvironment) {
|
2021-02-05 23:27:21 +08:00
|
|
|
pagingFence.fill(0u);
|
|
|
|
fenceVal.fill(0u);
|
2020-07-15 14:07:53 +08:00
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
int Drm::ioctl(unsigned long request, void *arg) {
|
|
|
|
int ret;
|
2021-05-12 23:09:01 +08:00
|
|
|
int returnedErrno;
|
2017-12-21 07:45:38 +08:00
|
|
|
SYSTEM_ENTER();
|
|
|
|
do {
|
2021-04-21 21:52:11 +08:00
|
|
|
auto measureTime = DebugManager.flags.PrintIoctlTimes.get();
|
|
|
|
std::chrono::steady_clock::time_point start;
|
|
|
|
std::chrono::steady_clock::time_point end;
|
|
|
|
|
2021-04-22 21:37:02 +08:00
|
|
|
auto printIoctl = DebugManager.flags.PrintIoctlEntries.get();
|
|
|
|
|
|
|
|
if (printIoctl) {
|
2022-02-12 01:45:20 +08:00
|
|
|
printf("IOCTL %s called\n", ioctlHelper->getIoctlString(request).c_str());
|
2021-04-22 21:37:02 +08:00
|
|
|
}
|
|
|
|
|
2021-08-19 23:26:34 +08:00
|
|
|
if (measureTime) {
|
|
|
|
start = std::chrono::steady_clock::now();
|
|
|
|
}
|
2020-02-13 20:26:40 +08:00
|
|
|
ret = SysCalls::ioctl(getFileDescriptor(), request, arg);
|
2021-04-21 21:52:11 +08:00
|
|
|
|
2021-05-12 23:09:01 +08:00
|
|
|
returnedErrno = errno;
|
|
|
|
|
2021-04-21 21:52:11 +08:00
|
|
|
if (measureTime) {
|
|
|
|
end = std::chrono::steady_clock::now();
|
2021-08-19 23:26:34 +08:00
|
|
|
long long elapsedTime = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
|
2021-04-21 21:52:11 +08:00
|
|
|
|
2021-08-19 23:26:34 +08:00
|
|
|
IoctlStatisticsEntry ioctlData{};
|
2021-04-21 21:52:11 +08:00
|
|
|
auto ioctlDataIt = this->ioctlStatistics.find(request);
|
|
|
|
if (ioctlDataIt != this->ioctlStatistics.end()) {
|
|
|
|
ioctlData = ioctlDataIt->second;
|
|
|
|
}
|
|
|
|
|
2021-08-19 23:26:34 +08:00
|
|
|
ioctlData.totalTime += elapsedTime;
|
|
|
|
ioctlData.count++;
|
|
|
|
ioctlData.minTime = std::min(ioctlData.minTime, elapsedTime);
|
|
|
|
ioctlData.maxTime = std::max(ioctlData.maxTime, elapsedTime);
|
2021-04-21 21:52:11 +08:00
|
|
|
|
|
|
|
this->ioctlStatistics[request] = ioctlData;
|
|
|
|
}
|
2021-08-19 23:26:34 +08:00
|
|
|
|
|
|
|
if (printIoctl) {
|
2021-12-31 09:38:08 +08:00
|
|
|
if (ret == 0) {
|
|
|
|
printf("IOCTL %s returns %d\n",
|
2022-02-12 01:45:20 +08:00
|
|
|
ioctlHelper->getIoctlString(request).c_str(), ret);
|
2021-12-31 09:38:08 +08:00
|
|
|
} else {
|
|
|
|
printf("IOCTL %s returns %d, errno %d(%s)\n",
|
2022-02-12 01:45:20 +08:00
|
|
|
ioctlHelper->getIoctlString(request).c_str(), ret, returnedErrno, strerror(returnedErrno));
|
2021-12-31 09:38:08 +08:00
|
|
|
}
|
2021-08-19 23:26:34 +08:00
|
|
|
}
|
|
|
|
|
2021-05-12 23:09:01 +08:00
|
|
|
} while (ret == -1 && (returnedErrno == EINTR || returnedErrno == EAGAIN || returnedErrno == EBUSY));
|
2017-12-21 07:45:38 +08:00
|
|
|
SYSTEM_LEAVE(request);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-03-12 19:03:20 +08:00
|
|
|
int Drm::getParamIoctl(int param, int *dstValue) {
|
|
|
|
drm_i915_getparam_t getParam = {};
|
|
|
|
getParam.param = param;
|
|
|
|
getParam.value = dstValue;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-01-31 23:10:03 +08:00
|
|
|
int retVal = ioctl(DRM_IOCTL_I915_GETPARAM, &getParam);
|
2021-06-25 20:28:28 +08:00
|
|
|
if (DebugManager.flags.PrintIoctlEntries.get()) {
|
|
|
|
printf("DRM_IOCTL_I915_GETPARAM: param: %s, output value: %d, retCode:% d\n",
|
2022-02-12 01:45:20 +08:00
|
|
|
ioctlHelper->getIoctlParamString(param).c_str(),
|
2021-06-25 20:28:28 +08:00
|
|
|
*getParam.value,
|
|
|
|
retVal);
|
|
|
|
}
|
2020-01-31 23:10:03 +08:00
|
|
|
return retVal;
|
2018-03-12 19:03:20 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-03-12 19:03:20 +08:00
|
|
|
int Drm::getDeviceID(int &devId) {
|
|
|
|
return getParamIoctl(I915_PARAM_CHIPSET_ID, &devId);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getDeviceRevID(int &revId) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_REVISION, &revId);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getExecSoftPin(int &execSoftPin) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_HAS_EXEC_SOFTPIN, &execSoftPin);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::enableTurboBoost() {
|
2018-03-20 17:49:09 +08:00
|
|
|
drm_i915_gem_context_param contextParam = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
contextParam.param = I915_CONTEXT_PRIVATE_PARAM_BOOST;
|
|
|
|
contextParam.value = 1;
|
2018-03-20 17:49:09 +08:00
|
|
|
return ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getEnabledPooledEu(int &enabled) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_HAS_POOLED_EU, &enabled);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-04-09 00:14:19 +08:00
|
|
|
std::string Drm::getSysFsPciPath() {
|
|
|
|
std::string path = std::string(Os::sysFsPciPathPrefix) + hwDeviceId->getPciPath() + "/drm";
|
|
|
|
std::string expectedFilePrefix = path + "/card";
|
|
|
|
auto files = Directory::getFiles(path.c_str());
|
|
|
|
for (auto &file : files) {
|
|
|
|
if (file.find(expectedFilePrefix.c_str()) != std::string::npos) {
|
|
|
|
return file;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
2020-04-09 00:14:19 +08:00
|
|
|
return {};
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-12-17 22:17:52 +08:00
|
|
|
int Drm::queryGttSize(uint64_t >tSizeOutput) {
|
2019-04-23 21:42:33 +08:00
|
|
|
drm_i915_gem_context_param contextParam = {0};
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_GTT_SIZE;
|
|
|
|
|
2019-12-17 22:17:52 +08:00
|
|
|
int ret = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &contextParam);
|
2019-04-23 21:42:33 +08:00
|
|
|
if (ret == 0) {
|
2019-12-17 22:17:52 +08:00
|
|
|
gttSizeOutput = contextParam.value;
|
2019-04-23 21:42:33 +08:00
|
|
|
}
|
2019-12-17 22:17:52 +08:00
|
|
|
|
|
|
|
return ret;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2022-02-05 00:03:36 +08:00
|
|
|
bool Drm::isGpuHangDetected(OsContext &osContext) {
|
|
|
|
const auto osContextLinux = static_cast<OsContextLinux *>(&osContext);
|
2022-01-21 00:56:19 +08:00
|
|
|
const auto &drmContextIds = osContextLinux->getDrmContextIds();
|
|
|
|
|
|
|
|
for (const auto drmContextId : drmContextIds) {
|
|
|
|
drm_i915_reset_stats reset_stats{};
|
|
|
|
reset_stats.ctx_id = drmContextId;
|
|
|
|
|
|
|
|
const auto retVal{ioctl(DRM_IOCTL_I915_GET_RESET_STATS, &reset_stats)};
|
|
|
|
UNRECOVERABLE_IF(retVal != 0);
|
|
|
|
|
|
|
|
if (reset_stats.batch_active > 0 || reset_stats.batch_pending > 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-12-07 22:03:23 +08:00
|
|
|
void Drm::checkPreemptionSupport() {
|
2017-12-21 07:45:38 +08:00
|
|
|
int value = 0;
|
2019-03-22 13:21:52 +08:00
|
|
|
auto ret = getParamIoctl(I915_PARAM_HAS_SCHEDULER, &value);
|
|
|
|
preemptionSupported = ((0 == ret) && (value & I915_SCHEDULER_CAP_PREEMPTION));
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-08-21 18:50:47 +08:00
|
|
|
void Drm::checkQueueSliceSupport() {
|
|
|
|
sliceCountChangeSupported = getQueueSliceCount(&sseu) == 0 ? true : false;
|
|
|
|
}
|
|
|
|
|
2018-12-11 15:21:56 +08:00
|
|
|
void Drm::setLowPriorityContextParam(uint32_t drmContextId) {
|
2018-12-07 22:03:23 +08:00
|
|
|
drm_i915_gem_context_param gcp = {};
|
2018-12-11 15:21:56 +08:00
|
|
|
gcp.ctx_id = drmContextId;
|
2017-12-21 07:45:38 +08:00
|
|
|
gcp.param = I915_CONTEXT_PARAM_PRIORITY;
|
|
|
|
gcp.value = -1023;
|
|
|
|
|
2018-12-11 15:21:56 +08:00
|
|
|
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &gcp);
|
|
|
|
UNRECOVERABLE_IF(retVal != 0);
|
|
|
|
}
|
|
|
|
|
2019-08-21 18:50:47 +08:00
|
|
|
int Drm::getQueueSliceCount(drm_i915_gem_context_param_sseu *sseu) {
|
|
|
|
drm_i915_gem_context_param contextParam = {};
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_SSEU;
|
|
|
|
sseu->engine.engine_class = I915_ENGINE_CLASS_RENDER;
|
|
|
|
sseu->engine.engine_instance = I915_EXEC_DEFAULT;
|
|
|
|
contextParam.value = reinterpret_cast<uint64_t>(sseu);
|
|
|
|
contextParam.size = sizeof(struct drm_i915_gem_context_param_sseu);
|
|
|
|
|
|
|
|
return ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &contextParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t Drm::getSliceMask(uint64_t sliceCount) {
|
2019-11-28 01:00:52 +08:00
|
|
|
return maxNBitValue(sliceCount);
|
2019-08-21 18:50:47 +08:00
|
|
|
}
|
|
|
|
bool Drm::setQueueSliceCount(uint64_t sliceCount) {
|
|
|
|
if (sliceCountChangeSupported) {
|
|
|
|
drm_i915_gem_context_param contextParam = {};
|
|
|
|
sseu.slice_mask = getSliceMask(sliceCount);
|
|
|
|
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_SSEU;
|
|
|
|
contextParam.ctx_id = 0;
|
|
|
|
contextParam.value = reinterpret_cast<uint64_t>(&sseu);
|
|
|
|
contextParam.size = sizeof(struct drm_i915_gem_context_param_sseu);
|
|
|
|
int retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
|
|
|
|
if (retVal == 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-02-11 00:05:32 +08:00
|
|
|
void Drm::checkNonPersistentContextsSupport() {
|
2019-12-19 02:38:22 +08:00
|
|
|
drm_i915_gem_context_param contextParam = {};
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_PERSISTENCE;
|
2020-02-11 00:05:32 +08:00
|
|
|
|
|
|
|
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &contextParam);
|
|
|
|
if (retVal == 0 && contextParam.value == 1) {
|
|
|
|
nonPersistentContextsSupported = true;
|
|
|
|
} else {
|
|
|
|
nonPersistentContextsSupported = false;
|
|
|
|
}
|
2019-12-19 02:38:22 +08:00
|
|
|
}
|
|
|
|
|
2019-12-24 19:20:23 +08:00
|
|
|
void Drm::setNonPersistentContext(uint32_t drmContextId) {
|
2019-12-19 02:38:22 +08:00
|
|
|
drm_i915_gem_context_param contextParam = {};
|
|
|
|
contextParam.ctx_id = drmContextId;
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_PERSISTENCE;
|
|
|
|
|
2020-02-11 00:05:32 +08:00
|
|
|
ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
|
2019-12-19 02:38:22 +08:00
|
|
|
}
|
|
|
|
|
2021-09-10 05:16:11 +08:00
|
|
|
void Drm::setUnrecoverableContext(uint32_t drmContextId) {
|
|
|
|
drm_i915_gem_context_param contextParam = {};
|
|
|
|
contextParam.ctx_id = drmContextId;
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_RECOVERABLE;
|
|
|
|
contextParam.value = 0;
|
|
|
|
contextParam.size = 0;
|
|
|
|
|
|
|
|
ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
|
|
|
|
}
|
|
|
|
|
2021-12-14 20:41:38 +08:00
|
|
|
uint32_t Drm::createDrmContext(uint32_t drmVmId, bool isDirectSubmissionRequested, bool isCooperativeContextRequested) {
|
2021-09-03 23:32:33 +08:00
|
|
|
drm_i915_gem_context_create_ext gcc = {};
|
|
|
|
|
2021-12-14 20:41:38 +08:00
|
|
|
this->appendDrmContextFlags(gcc, isDirectSubmissionRequested);
|
2021-09-03 23:32:33 +08:00
|
|
|
|
2021-12-14 20:41:38 +08:00
|
|
|
auto retVal = this->createDrmContextExt(gcc, drmVmId, isCooperativeContextRequested);
|
2021-09-03 23:32:33 +08:00
|
|
|
UNRECOVERABLE_IF(retVal != 0);
|
|
|
|
|
|
|
|
return gcc.ctx_id;
|
|
|
|
}
|
|
|
|
|
2018-12-11 15:21:56 +08:00
|
|
|
void Drm::destroyDrmContext(uint32_t drmContextId) {
|
2018-03-20 17:49:09 +08:00
|
|
|
drm_i915_gem_context_destroy destroy = {};
|
2018-12-11 15:21:56 +08:00
|
|
|
destroy.ctx_id = drmContextId;
|
2018-12-07 22:03:23 +08:00
|
|
|
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, &destroy);
|
|
|
|
UNRECOVERABLE_IF(retVal != 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-07-07 15:34:31 +08:00
|
|
|
void Drm::destroyDrmVirtualMemory(uint32_t drmVmId) {
|
|
|
|
drm_i915_gem_vm_control ctl = {};
|
|
|
|
ctl.vm_id = drmVmId;
|
|
|
|
auto ret = SysCalls::ioctl(getFileDescriptor(), DRM_IOCTL_I915_GEM_VM_DESTROY, &ctl);
|
|
|
|
UNRECOVERABLE_IF(ret != 0);
|
|
|
|
}
|
|
|
|
|
2020-08-31 13:04:58 +08:00
|
|
|
int Drm::queryVmId(uint32_t drmContextId, uint32_t &vmId) {
|
2020-08-17 18:07:39 +08:00
|
|
|
drm_i915_gem_context_param param{};
|
|
|
|
param.ctx_id = drmContextId;
|
|
|
|
param.value = 0;
|
|
|
|
param.param = I915_CONTEXT_PARAM_VM;
|
|
|
|
auto retVal = this->ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, ¶m);
|
|
|
|
|
2020-08-31 13:04:58 +08:00
|
|
|
vmId = static_cast<uint32_t>(param.value);
|
2020-08-17 18:07:39 +08:00
|
|
|
|
2020-08-31 13:04:58 +08:00
|
|
|
return retVal;
|
2020-08-17 18:07:39 +08:00
|
|
|
}
|
|
|
|
|
2021-08-09 22:33:44 +08:00
|
|
|
std::unique_lock<std::mutex> Drm::lockBindFenceMutex() {
|
|
|
|
return std::unique_lock<std::mutex>(this->bindFenceMutex);
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
int Drm::getEuTotal(int &euTotal) {
|
2019-07-23 17:45:10 +08:00
|
|
|
return getParamIoctl(I915_PARAM_EU_TOTAL, &euTotal);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getSubsliceTotal(int &subsliceTotal) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_SUBSLICE_TOTAL, &subsliceTotal);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getMinEuInPool(int &minEUinPool) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_MIN_EU_IN_POOL, &minEUinPool);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-02-28 19:09:48 +08:00
|
|
|
int Drm::getErrno() {
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
2019-10-18 16:15:09 +08:00
|
|
|
int Drm::setupHardwareInfo(DeviceDescriptor *device, bool setupFeatureTableAndWorkaroundTable) {
|
|
|
|
HardwareInfo *hwInfo = const_cast<HardwareInfo *>(device->pHwInfo);
|
|
|
|
int ret;
|
|
|
|
|
2022-01-29 05:00:05 +08:00
|
|
|
const auto productFamily = hwInfo->platform.eProductFamily;
|
|
|
|
setupIoctlHelper(productFamily);
|
|
|
|
|
2021-04-27 22:45:13 +08:00
|
|
|
Drm::QueryTopologyData topologyData = {};
|
|
|
|
|
|
|
|
bool status = queryTopology(*hwInfo, topologyData);
|
2020-06-09 21:51:26 +08:00
|
|
|
|
|
|
|
if (!status) {
|
2020-09-25 17:24:15 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "WARNING: Topology query failed!\n");
|
2020-06-09 21:51:26 +08:00
|
|
|
|
2021-04-27 22:45:13 +08:00
|
|
|
ret = getEuTotal(topologyData.euCount);
|
2020-06-09 21:51:26 +08:00
|
|
|
if (ret != 0) {
|
2020-09-25 17:24:15 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query EU total parameter!\n");
|
2020-06-09 21:51:26 +08:00
|
|
|
return ret;
|
|
|
|
}
|
2019-10-18 16:15:09 +08:00
|
|
|
|
2021-04-27 22:45:13 +08:00
|
|
|
ret = getSubsliceTotal(topologyData.subSliceCount);
|
2020-06-09 21:51:26 +08:00
|
|
|
if (ret != 0) {
|
2020-09-25 17:24:15 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query subslice total parameter!\n");
|
2020-06-09 21:51:26 +08:00
|
|
|
return ret;
|
|
|
|
}
|
2019-10-18 16:15:09 +08:00
|
|
|
}
|
|
|
|
|
2021-04-27 22:45:13 +08:00
|
|
|
hwInfo->gtSystemInfo.SliceCount = static_cast<uint32_t>(topologyData.sliceCount);
|
|
|
|
hwInfo->gtSystemInfo.SubSliceCount = static_cast<uint32_t>(topologyData.subSliceCount);
|
2021-06-01 21:07:41 +08:00
|
|
|
hwInfo->gtSystemInfo.DualSubSliceCount = static_cast<uint32_t>(topologyData.subSliceCount);
|
2021-04-27 22:45:13 +08:00
|
|
|
hwInfo->gtSystemInfo.EUCount = static_cast<uint32_t>(topologyData.euCount);
|
2022-01-21 20:39:11 +08:00
|
|
|
rootDeviceEnvironment.setHwInfo(hwInfo);
|
2021-04-27 22:45:13 +08:00
|
|
|
|
2020-11-24 23:00:33 +08:00
|
|
|
status = querySystemInfo();
|
2021-06-15 18:43:12 +08:00
|
|
|
if (status) {
|
|
|
|
setupSystemInfo(hwInfo, systemInfo.get());
|
2020-11-24 23:00:33 +08:00
|
|
|
}
|
2021-06-15 18:43:12 +08:00
|
|
|
device->setupHardwareInfo(hwInfo, setupFeatureTableAndWorkaroundTable);
|
|
|
|
|
2020-11-24 23:00:33 +08:00
|
|
|
if (systemInfo) {
|
2021-06-15 18:43:12 +08:00
|
|
|
systemInfo->checkSysInfoMismatch(hwInfo);
|
2020-11-24 23:00:33 +08:00
|
|
|
}
|
|
|
|
|
2021-01-30 06:23:06 +08:00
|
|
|
setupCacheInfo(*hwInfo);
|
|
|
|
|
2019-10-18 16:15:09 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-04-09 00:14:19 +08:00
|
|
|
void appendHwDeviceId(std::vector<std::unique_ptr<HwDeviceId>> &hwDeviceIds, int fileDescriptor, const char *pciPath) {
|
2020-04-08 17:27:04 +08:00
|
|
|
if (fileDescriptor >= 0) {
|
|
|
|
if (Drm::isi915Version(fileDescriptor)) {
|
2021-05-25 01:34:55 +08:00
|
|
|
hwDeviceIds.push_back(std::make_unique<HwDeviceIdDrm>(fileDescriptor, pciPath));
|
2020-04-08 17:27:04 +08:00
|
|
|
} else {
|
|
|
|
SysCalls::close(fileDescriptor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-28 01:44:47 +08:00
|
|
|
std::vector<std::unique_ptr<HwDeviceId>> Drm::discoverDevices(ExecutionEnvironment &executionEnvironment) {
|
2021-10-11 23:34:03 +08:00
|
|
|
std::string str = "";
|
|
|
|
return Drm::discoverDevices(executionEnvironment, str);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::unique_ptr<HwDeviceId>> Drm::discoverDevice(ExecutionEnvironment &executionEnvironment, std::string &osPciPath) {
|
|
|
|
return Drm::discoverDevices(executionEnvironment, osPciPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::unique_ptr<HwDeviceId>> Drm::discoverDevices(ExecutionEnvironment &executionEnvironment, std::string &osPciPath) {
|
2020-02-17 23:14:22 +08:00
|
|
|
std::vector<std::unique_ptr<HwDeviceId>> hwDeviceIds;
|
2020-03-17 14:26:46 +08:00
|
|
|
executionEnvironment.osEnvironment = std::make_unique<OsEnvironment>();
|
2020-04-08 17:27:04 +08:00
|
|
|
size_t numRootDevices = 0u;
|
2020-02-17 23:14:22 +08:00
|
|
|
if (DebugManager.flags.CreateMultipleRootDevices.get()) {
|
|
|
|
numRootDevices = DebugManager.flags.CreateMultipleRootDevices.get();
|
|
|
|
}
|
2020-04-08 17:27:04 +08:00
|
|
|
|
|
|
|
std::vector<std::string> files = Directory::getFiles(Os::pciDevicesDirectory);
|
|
|
|
|
|
|
|
if (files.size() == 0) {
|
|
|
|
const char *pathPrefix = "/dev/dri/renderD";
|
|
|
|
const unsigned int maxDrmDevices = 64;
|
|
|
|
unsigned int startNum = 128;
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < maxDrmDevices; i++) {
|
|
|
|
std::string path = std::string(pathPrefix) + std::to_string(i + startNum);
|
|
|
|
int fileDescriptor = SysCalls::open(path.c_str(), O_RDWR);
|
2021-03-29 19:43:50 +08:00
|
|
|
|
2021-05-20 06:36:24 +08:00
|
|
|
auto pciPath = NEO::getPciPath(fileDescriptor);
|
2021-03-29 19:43:50 +08:00
|
|
|
|
2021-10-06 09:57:55 +08:00
|
|
|
appendHwDeviceId(hwDeviceIds, fileDescriptor, pciPath.value_or("0000:00:02.0").c_str());
|
2020-05-21 19:01:07 +08:00
|
|
|
if (!hwDeviceIds.empty() && hwDeviceIds.size() == numRootDevices) {
|
|
|
|
break;
|
|
|
|
}
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
2020-02-17 23:14:22 +08:00
|
|
|
return hwDeviceIds;
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
|
|
|
|
2020-04-08 17:27:04 +08:00
|
|
|
do {
|
2021-10-27 01:29:17 +08:00
|
|
|
const char *renderDeviceSuffix = "-render";
|
2020-04-08 17:27:04 +08:00
|
|
|
for (std::vector<std::string>::iterator file = files.begin(); file != files.end(); ++file) {
|
2021-10-27 01:29:17 +08:00
|
|
|
std::string_view devicePathView(file->c_str(), file->size());
|
|
|
|
devicePathView = devicePathView.substr(strlen(Os::pciDevicesDirectory));
|
|
|
|
|
|
|
|
auto rdsPos = devicePathView.rfind(renderDeviceSuffix);
|
|
|
|
if (rdsPos == std::string::npos) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (rdsPos < devicePathView.size() - strlen(renderDeviceSuffix)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// at least 'pci-0000:00:00.0' -> 16
|
|
|
|
if (rdsPos < 16 || devicePathView[rdsPos - 13] != '-') {
|
2020-04-08 17:27:04 +08:00
|
|
|
continue;
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
2021-10-27 01:29:17 +08:00
|
|
|
std::string pciPath(devicePathView.substr(rdsPos - 12, 12));
|
2020-04-08 17:27:04 +08:00
|
|
|
|
2021-10-11 23:34:03 +08:00
|
|
|
if (!osPciPath.empty()) {
|
|
|
|
if (osPciPath.compare(pciPath) != 0) {
|
|
|
|
// if osPciPath is non-empty, then interest is only in discovering device having same bdf as ocPciPath. Skip all other devices.
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-01 01:43:42 +08:00
|
|
|
if (DebugManager.flags.FilterBdfPath.get() != "unk") {
|
|
|
|
if (devicePathView.find(DebugManager.flags.FilterBdfPath.get().c_str()) == std::string::npos) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2020-04-08 17:27:04 +08:00
|
|
|
if (DebugManager.flags.ForceDeviceId.get() != "unk") {
|
2021-10-27 01:29:17 +08:00
|
|
|
if (devicePathView.find(DebugManager.flags.ForceDeviceId.get().c_str()) == std::string::npos) {
|
2020-04-08 17:27:04 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int fileDescriptor = SysCalls::open(file->c_str(), O_RDWR);
|
2020-04-09 00:14:19 +08:00
|
|
|
appendHwDeviceId(hwDeviceIds, fileDescriptor, pciPath.c_str());
|
2020-05-21 19:01:07 +08:00
|
|
|
if (!hwDeviceIds.empty() && hwDeviceIds.size() == numRootDevices) {
|
|
|
|
break;
|
|
|
|
}
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
2020-04-08 17:27:04 +08:00
|
|
|
if (hwDeviceIds.empty()) {
|
|
|
|
return hwDeviceIds;
|
|
|
|
}
|
|
|
|
} while (hwDeviceIds.size() < numRootDevices);
|
2020-02-17 23:14:22 +08:00
|
|
|
return hwDeviceIds;
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Drm::isi915Version(int fileDescriptor) {
|
|
|
|
drm_version_t version = {};
|
|
|
|
char name[5] = {};
|
|
|
|
version.name = name;
|
|
|
|
version.name_len = 5;
|
|
|
|
|
2020-02-13 20:26:40 +08:00
|
|
|
int ret = SysCalls::ioctl(fileDescriptor, DRM_IOCTL_VERSION, &version);
|
2020-02-07 21:32:02 +08:00
|
|
|
if (ret) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
name[4] = '\0';
|
|
|
|
return strcmp(name, "i915") == 0;
|
|
|
|
}
|
|
|
|
|
2021-12-22 22:25:53 +08:00
|
|
|
std::vector<uint8_t> Drm::query(uint32_t queryId, uint32_t queryItemFlags) {
|
2020-06-09 21:51:26 +08:00
|
|
|
drm_i915_query query{};
|
|
|
|
drm_i915_query_item queryItem{};
|
|
|
|
queryItem.query_id = queryId;
|
|
|
|
queryItem.length = 0; // query length first
|
2020-11-19 19:04:17 +08:00
|
|
|
queryItem.flags = queryItemFlags;
|
2020-06-09 21:51:26 +08:00
|
|
|
query.items_ptr = reinterpret_cast<__u64>(&queryItem);
|
|
|
|
query.num_items = 1;
|
|
|
|
|
|
|
|
auto ret = this->ioctl(DRM_IOCTL_I915_QUERY, &query);
|
|
|
|
if (ret != 0 || queryItem.length <= 0) {
|
2021-12-22 22:25:53 +08:00
|
|
|
return {};
|
2020-06-09 21:51:26 +08:00
|
|
|
}
|
|
|
|
|
2021-12-22 22:25:53 +08:00
|
|
|
auto data = std::vector<uint8_t>(queryItem.length, 0);
|
|
|
|
queryItem.data_ptr = castToUint64(data.data());
|
2020-06-09 21:51:26 +08:00
|
|
|
|
|
|
|
ret = this->ioctl(DRM_IOCTL_I915_QUERY, &query);
|
|
|
|
if (ret != 0 || queryItem.length <= 0) {
|
2021-12-22 22:25:53 +08:00
|
|
|
return {};
|
2020-06-09 21:51:26 +08:00
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2021-04-21 21:52:11 +08:00
|
|
|
void Drm::printIoctlStatistics() {
|
|
|
|
if (!DebugManager.flags.PrintIoctlTimes.get()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-11 20:56:07 +08:00
|
|
|
printf("\n--- Ioctls statistics ---\n");
|
2021-08-19 23:26:34 +08:00
|
|
|
printf("%41s %15s %10s %20s %20s %20s", "Request", "Total time(ns)", "Count", "Avg time per ioctl", "Min", "Max\n");
|
2021-04-21 21:52:11 +08:00
|
|
|
for (const auto &ioctlData : this->ioctlStatistics) {
|
2021-08-19 23:26:34 +08:00
|
|
|
printf("%41s %15llu %10lu %20f %20lld %20lld\n",
|
2022-02-12 01:45:20 +08:00
|
|
|
ioctlHelper->getIoctlString(ioctlData.first).c_str(),
|
2021-08-19 23:26:34 +08:00
|
|
|
ioctlData.second.totalTime,
|
|
|
|
static_cast<unsigned long>(ioctlData.second.count),
|
|
|
|
ioctlData.second.totalTime / static_cast<double>(ioctlData.second.count),
|
|
|
|
ioctlData.second.minTime,
|
|
|
|
ioctlData.second.maxTime);
|
2021-04-21 21:52:11 +08:00
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
2020-07-07 15:34:31 +08:00
|
|
|
bool Drm::createVirtualMemoryAddressSpace(uint32_t vmCount) {
|
|
|
|
for (auto i = 0u; i < vmCount; i++) {
|
2021-03-17 01:47:26 +08:00
|
|
|
uint32_t id = i;
|
2020-07-14 10:36:16 +08:00
|
|
|
if (0 != createDrmVirtualMemory(id)) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-07-07 15:34:31 +08:00
|
|
|
virtualMemoryIds.push_back(id);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Drm::destroyVirtualMemoryAddressSpace() {
|
|
|
|
for (auto id : virtualMemoryIds) {
|
|
|
|
destroyDrmVirtualMemory(id);
|
|
|
|
}
|
2020-08-04 16:23:54 +08:00
|
|
|
virtualMemoryIds.clear();
|
2020-07-07 15:34:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Drm::getVirtualMemoryAddressSpace(uint32_t vmId) {
|
2020-07-14 10:36:16 +08:00
|
|
|
if (vmId < virtualMemoryIds.size()) {
|
|
|
|
return virtualMemoryIds[vmId];
|
|
|
|
}
|
|
|
|
return 0;
|
2020-07-07 15:34:31 +08:00
|
|
|
}
|
|
|
|
|
2021-09-02 00:28:18 +08:00
|
|
|
void Drm::setNewResourceBoundToVM(uint32_t vmHandleId) {
|
|
|
|
const auto &engines = this->rootDeviceEnvironment.executionEnvironment.memoryManager->getRegisteredEngines();
|
|
|
|
for (const auto &engine : engines) {
|
|
|
|
if (engine.osContext->getDeviceBitfield().test(vmHandleId)) {
|
|
|
|
auto osContextLinux = static_cast<OsContextLinux *>(engine.osContext);
|
|
|
|
|
|
|
|
if (&osContextLinux->getDrm() == this) {
|
|
|
|
osContextLinux->setNewResourceBound(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-07 23:29:28 +08:00
|
|
|
bool Drm::translateTopologyInfo(const drm_i915_query_topology_info *queryTopologyInfo, QueryTopologyData &data, TopologyMapping &mapping) {
|
|
|
|
int sliceCount = 0;
|
|
|
|
int subSliceCount = 0;
|
|
|
|
int euCount = 0;
|
2021-05-17 23:04:01 +08:00
|
|
|
int maxSliceCount = 0;
|
|
|
|
int maxSubSliceCountPerSlice = 0;
|
2021-04-27 22:45:13 +08:00
|
|
|
std::vector<int> sliceIndices;
|
|
|
|
sliceIndices.reserve(maxSliceCount);
|
2021-01-26 19:02:17 +08:00
|
|
|
|
|
|
|
for (int x = 0; x < queryTopologyInfo->max_slices; x++) {
|
|
|
|
bool isSliceEnable = (queryTopologyInfo->data[x / 8] >> (x % 8)) & 1;
|
|
|
|
if (!isSliceEnable) {
|
|
|
|
continue;
|
|
|
|
}
|
2021-04-27 22:45:13 +08:00
|
|
|
sliceIndices.push_back(x);
|
2021-01-26 19:02:17 +08:00
|
|
|
sliceCount++;
|
2021-05-17 23:04:01 +08:00
|
|
|
|
|
|
|
std::vector<int> subSliceIndices;
|
|
|
|
subSliceIndices.reserve(queryTopologyInfo->max_subslices);
|
|
|
|
|
2021-01-26 19:02:17 +08:00
|
|
|
for (int y = 0; y < queryTopologyInfo->max_subslices; y++) {
|
|
|
|
size_t yOffset = (queryTopologyInfo->subslice_offset + x * queryTopologyInfo->subslice_stride + y / 8);
|
|
|
|
bool isSubSliceEnabled = (queryTopologyInfo->data[yOffset] >> (y % 8)) & 1;
|
|
|
|
if (!isSubSliceEnabled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
subSliceCount++;
|
2021-05-17 23:04:01 +08:00
|
|
|
subSliceIndices.push_back(y);
|
|
|
|
|
2021-01-26 19:02:17 +08:00
|
|
|
for (int z = 0; z < queryTopologyInfo->max_eus_per_subslice; z++) {
|
|
|
|
size_t zOffset = (queryTopologyInfo->eu_offset + (x * queryTopologyInfo->max_subslices + y) * queryTopologyInfo->eu_stride + z / 8);
|
|
|
|
bool isEUEnabled = (queryTopologyInfo->data[zOffset] >> (z % 8)) & 1;
|
|
|
|
if (!isEUEnabled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
euCount++;
|
|
|
|
}
|
|
|
|
}
|
2021-05-17 23:04:01 +08:00
|
|
|
|
|
|
|
if (subSliceIndices.size()) {
|
|
|
|
maxSubSliceCountPerSlice = std::max(maxSubSliceCountPerSlice, subSliceIndices[subSliceIndices.size() - 1] + 1);
|
|
|
|
}
|
2022-01-29 03:08:02 +08:00
|
|
|
|
|
|
|
// single slice available
|
|
|
|
if (sliceCount == 1) {
|
|
|
|
mapping.subsliceIndices = std::move(subSliceIndices);
|
|
|
|
}
|
2021-01-26 19:02:17 +08:00
|
|
|
}
|
|
|
|
|
2021-04-27 22:45:13 +08:00
|
|
|
if (sliceIndices.size()) {
|
|
|
|
maxSliceCount = sliceIndices[sliceIndices.size() - 1] + 1;
|
2021-05-07 23:29:28 +08:00
|
|
|
mapping.sliceIndices = std::move(sliceIndices);
|
2021-04-27 22:45:13 +08:00
|
|
|
}
|
2021-05-07 23:29:28 +08:00
|
|
|
|
2022-01-29 03:08:02 +08:00
|
|
|
if (sliceCount != 1) {
|
|
|
|
mapping.subsliceIndices.clear();
|
|
|
|
}
|
|
|
|
|
2021-05-07 23:29:28 +08:00
|
|
|
data.sliceCount = sliceCount;
|
|
|
|
data.subSliceCount = subSliceCount;
|
|
|
|
data.euCount = euCount;
|
|
|
|
data.maxSliceCount = maxSliceCount;
|
2021-05-17 23:04:01 +08:00
|
|
|
data.maxSubSliceCount = maxSubSliceCountPerSlice;
|
2021-05-07 23:29:28 +08:00
|
|
|
|
|
|
|
return (data.sliceCount && data.subSliceCount && data.euCount);
|
2021-01-26 19:02:17 +08:00
|
|
|
}
|
|
|
|
|
2020-11-05 20:40:03 +08:00
|
|
|
PhysicalDevicePciBusInfo Drm::getPciBusInfo() const {
|
|
|
|
PhysicalDevicePciBusInfo pciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue);
|
|
|
|
|
2021-06-01 00:58:10 +08:00
|
|
|
if (adapterBDF.Data != std::numeric_limits<uint32_t>::max()) {
|
2021-10-22 00:09:45 +08:00
|
|
|
pciBusInfo.pciDomain = this->pciDomain;
|
2021-06-01 00:58:10 +08:00
|
|
|
pciBusInfo.pciBus = adapterBDF.Bus;
|
|
|
|
pciBusInfo.pciDevice = adapterBDF.Device;
|
|
|
|
pciBusInfo.pciFunction = adapterBDF.Function;
|
2020-11-05 20:40:03 +08:00
|
|
|
}
|
|
|
|
return pciBusInfo;
|
|
|
|
}
|
|
|
|
|
2020-07-07 15:34:31 +08:00
|
|
|
Drm::~Drm() {
|
|
|
|
destroyVirtualMemoryAddressSpace();
|
2021-04-21 21:52:11 +08:00
|
|
|
this->printIoctlStatistics();
|
2020-07-07 15:34:31 +08:00
|
|
|
}
|
2020-02-13 22:04:21 +08:00
|
|
|
|
2021-06-01 00:58:10 +08:00
|
|
|
int Drm::queryAdapterBDF() {
|
2021-10-06 09:57:55 +08:00
|
|
|
constexpr int pciBusInfoTokensNum = 4;
|
2022-01-17 19:59:54 +08:00
|
|
|
uint16_t domain = -1;
|
|
|
|
uint8_t bus = -1, device = -1, function = -1;
|
2021-04-23 22:30:04 +08:00
|
|
|
|
2022-01-17 19:59:54 +08:00
|
|
|
if (NEO::parseBdfString(hwDeviceId->getPciPath(), domain, bus, device, function) != pciBusInfoTokensNum) {
|
2021-06-01 00:58:10 +08:00
|
|
|
adapterBDF.Data = std::numeric_limits<uint32_t>::max();
|
|
|
|
return 1;
|
2021-04-23 22:30:04 +08:00
|
|
|
}
|
2021-10-06 09:57:55 +08:00
|
|
|
setPciDomain(domain);
|
2021-04-23 22:30:04 +08:00
|
|
|
adapterBDF.Bus = bus;
|
|
|
|
adapterBDF.Function = function;
|
|
|
|
adapterBDF.Device = device;
|
2021-06-01 00:58:10 +08:00
|
|
|
return 0;
|
2021-04-23 22:30:04 +08:00
|
|
|
}
|
|
|
|
|
2021-05-21 07:17:57 +08:00
|
|
|
void Drm::setGmmInputArgs(void *args) {
|
|
|
|
auto gmmInArgs = reinterpret_cast<GMM_INIT_IN_ARGS *>(args);
|
|
|
|
auto adapterBDF = this->getAdapterBDF();
|
2021-05-26 19:23:04 +08:00
|
|
|
#if defined(__linux__)
|
2021-05-21 07:17:57 +08:00
|
|
|
gmmInArgs->FileDescriptor = adapterBDF.Data;
|
2021-05-26 19:23:04 +08:00
|
|
|
#endif
|
2021-05-21 07:17:57 +08:00
|
|
|
gmmInArgs->ClientType = GMM_CLIENT::GMM_OCL_VISTA;
|
|
|
|
}
|
|
|
|
|
2021-05-07 23:29:28 +08:00
|
|
|
const std::vector<int> &Drm::getSliceMappings(uint32_t deviceIndex) {
|
|
|
|
return topologyMap[deviceIndex].sliceIndices;
|
|
|
|
}
|
|
|
|
|
2021-07-06 22:26:44 +08:00
|
|
|
const TopologyMap &Drm::getTopologyMap() {
|
|
|
|
return topologyMap;
|
|
|
|
}
|
|
|
|
|
2021-06-15 19:31:12 +08:00
|
|
|
int Drm::waitHandle(uint32_t waitHandle, int64_t timeout) {
|
2021-08-16 22:12:33 +08:00
|
|
|
UNRECOVERABLE_IF(isVmBindAvailable());
|
|
|
|
|
2021-06-04 20:23:20 +08:00
|
|
|
drm_i915_gem_wait wait = {};
|
|
|
|
wait.bo_handle = waitHandle;
|
2021-06-15 19:31:12 +08:00
|
|
|
wait.timeout_ns = timeout;
|
2021-06-04 20:23:20 +08:00
|
|
|
|
2021-06-15 19:31:12 +08:00
|
|
|
int ret = ioctl(DRM_IOCTL_I915_GEM_WAIT, &wait);
|
|
|
|
if (ret != 0) {
|
|
|
|
int err = errno;
|
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(I915_GEM_WAIT) failed with %d. errno=%d(%s)\n", ret, err, strerror(err));
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2021-06-04 20:23:20 +08:00
|
|
|
}
|
|
|
|
|
2021-06-25 20:28:28 +08:00
|
|
|
int Drm::getTimestampFrequency(int &frequency) {
|
|
|
|
frequency = 0;
|
|
|
|
return getParamIoctl(I915_PARAM_CS_TIMESTAMP_FREQUENCY, &frequency);
|
|
|
|
}
|
|
|
|
|
2021-09-03 23:20:44 +08:00
|
|
|
bool Drm::queryEngineInfo() {
|
|
|
|
return Drm::queryEngineInfo(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Drm::sysmanQueryEngineInfo() {
|
|
|
|
return Drm::queryEngineInfo(true);
|
|
|
|
}
|
|
|
|
|
2021-09-07 19:27:41 +08:00
|
|
|
int getMaxGpuFrequencyOfDevice(Drm &drm, std::string &sysFsPciPath, int &maxGpuFrequency) {
|
|
|
|
maxGpuFrequency = 0;
|
|
|
|
std::string clockSysFsPath = sysFsPciPath + "/gt_max_freq_mhz";
|
|
|
|
|
|
|
|
std::ifstream ifs(clockSysFsPath.c_str(), std::ifstream::in);
|
|
|
|
if (ifs.fail()) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ifs >> maxGpuFrequency;
|
|
|
|
ifs.close();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int getMaxGpuFrequencyOfSubDevice(Drm &drm, std::string &sysFsPciPath, int subDeviceId, int &maxGpuFrequency) {
|
|
|
|
maxGpuFrequency = 0;
|
|
|
|
std::string clockSysFsPath = sysFsPciPath + "/gt/gt" + std::to_string(subDeviceId) + "/rps_max_freq_mhz";
|
|
|
|
|
|
|
|
std::ifstream ifs(clockSysFsPath.c_str(), std::ifstream::in);
|
|
|
|
if (ifs.fail()) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ifs >> maxGpuFrequency;
|
|
|
|
ifs.close();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getMaxGpuFrequency(HardwareInfo &hwInfo, int &maxGpuFrequency) {
|
|
|
|
int ret = 0;
|
|
|
|
std::string sysFsPciPath = getSysFsPciPath();
|
|
|
|
auto tileCount = hwInfo.gtSystemInfo.MultiTileArchInfo.TileCount;
|
|
|
|
|
|
|
|
if (hwInfo.gtSystemInfo.MultiTileArchInfo.IsValid && tileCount > 0) {
|
|
|
|
for (auto tileId = 0; tileId < tileCount; tileId++) {
|
|
|
|
int maxGpuFreqOfSubDevice = 0;
|
|
|
|
ret |= getMaxGpuFrequencyOfSubDevice(*this, sysFsPciPath, tileId, maxGpuFreqOfSubDevice);
|
|
|
|
maxGpuFrequency = std::max(maxGpuFrequency, maxGpuFreqOfSubDevice);
|
|
|
|
}
|
|
|
|
if (ret == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return getMaxGpuFrequencyOfDevice(*this, sysFsPciPath, maxGpuFrequency);
|
|
|
|
}
|
|
|
|
|
2021-11-19 05:36:55 +08:00
|
|
|
bool Drm::useVMBindImmediate() const {
|
|
|
|
bool useBindImmediate = isDirectSubmissionActive() || hasPageFaultSupport();
|
|
|
|
|
|
|
|
if (DebugManager.flags.EnableImmediateVmBindExt.get() != -1) {
|
|
|
|
useBindImmediate = DebugManager.flags.EnableImmediateVmBindExt.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
return useBindImmediate;
|
|
|
|
}
|
|
|
|
|
2021-11-13 01:34:33 +08:00
|
|
|
void Drm::setupSystemInfo(HardwareInfo *hwInfo, SystemInfo *sysInfo) {
|
|
|
|
GT_SYSTEM_INFO *gtSysInfo = &hwInfo->gtSystemInfo;
|
|
|
|
gtSysInfo->ThreadCount = gtSysInfo->EUCount * sysInfo->getNumThreadsPerEu();
|
|
|
|
gtSysInfo->L3CacheSizeInKb = sysInfo->getL3CacheSizeInKb();
|
|
|
|
gtSysInfo->L3BankCount = sysInfo->getL3BankCount();
|
|
|
|
gtSysInfo->MemoryType = sysInfo->getMemoryType();
|
|
|
|
gtSysInfo->MaxFillRate = sysInfo->getMaxFillRate();
|
|
|
|
gtSysInfo->TotalVsThreads = sysInfo->getTotalVsThreads();
|
|
|
|
gtSysInfo->TotalHsThreads = sysInfo->getTotalHsThreads();
|
|
|
|
gtSysInfo->TotalDsThreads = sysInfo->getTotalDsThreads();
|
|
|
|
gtSysInfo->TotalGsThreads = sysInfo->getTotalGsThreads();
|
|
|
|
gtSysInfo->TotalPsThreadsWindowerRange = sysInfo->getTotalPsThreads();
|
|
|
|
gtSysInfo->MaxEuPerSubSlice = sysInfo->getMaxEuPerDualSubSlice();
|
|
|
|
gtSysInfo->MaxSlicesSupported = sysInfo->getMaxSlicesSupported();
|
|
|
|
gtSysInfo->MaxSubSlicesSupported = sysInfo->getMaxDualSubSlicesSupported();
|
|
|
|
gtSysInfo->MaxDualSubSlicesSupported = sysInfo->getMaxDualSubSlicesSupported();
|
|
|
|
}
|
|
|
|
|
2022-02-03 19:13:44 +08:00
|
|
|
void Drm::setupCacheInfo(const HardwareInfo &hwInfo) {
|
|
|
|
auto &hwHelper = HwHelper::get(hwInfo.platform.eRenderCoreFamily);
|
|
|
|
|
|
|
|
if (DebugManager.flags.ClosEnabled.get() == 0 || hwHelper.getNumCacheRegions() == 0) {
|
|
|
|
this->cacheInfo.reset(new CacheInfoImpl(*this, 0, 0, 0));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const GT_SYSTEM_INFO *gtSysInfo = &hwInfo.gtSystemInfo;
|
|
|
|
|
|
|
|
constexpr uint16_t maxNumWays = 32;
|
|
|
|
constexpr uint16_t globalReservationLimit = 16;
|
|
|
|
constexpr uint16_t clientReservationLimit = 8;
|
|
|
|
constexpr uint16_t maxReservationNumWays = std::min(globalReservationLimit, clientReservationLimit);
|
|
|
|
const size_t totalCacheSize = gtSysInfo->L3CacheSizeInKb * MemoryConstants::kiloByte;
|
|
|
|
const size_t maxReservationCacheSize = (totalCacheSize * maxReservationNumWays) / maxNumWays;
|
|
|
|
const uint32_t maxReservationNumCacheRegions = hwHelper.getNumCacheRegions() - 1;
|
|
|
|
|
|
|
|
this->cacheInfo.reset(new CacheInfoImpl(*this, maxReservationCacheSize, maxReservationNumCacheRegions, maxReservationNumWays));
|
|
|
|
}
|
|
|
|
|
2021-12-08 18:10:27 +08:00
|
|
|
void Drm::getPrelimVersion(std::string &prelimVersion) {
|
|
|
|
std::string sysFsPciPath = getSysFsPciPath();
|
|
|
|
std::string prelimVersionPath = sysFsPciPath + "/prelim_uapi_version";
|
|
|
|
|
|
|
|
std::ifstream ifs(prelimVersionPath.c_str(), std::ifstream::in);
|
|
|
|
|
|
|
|
if (ifs.fail()) {
|
|
|
|
prelimVersion = "";
|
|
|
|
} else {
|
|
|
|
ifs >> prelimVersion;
|
|
|
|
}
|
|
|
|
ifs.close();
|
|
|
|
}
|
|
|
|
|
2021-12-14 17:46:01 +08:00
|
|
|
int Drm::waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout, uint16_t flags) {
|
2022-01-21 20:39:11 +08:00
|
|
|
return ioctlHelper->waitUserFence(this, ctxId, address, value, static_cast<uint32_t>(dataWidth), timeout, flags);
|
2021-12-14 17:46:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Drm::querySystemInfo() {
|
2022-01-21 20:39:11 +08:00
|
|
|
auto request = ioctlHelper->getHwConfigIoctlVal();
|
2021-12-22 22:25:53 +08:00
|
|
|
auto deviceBlobQuery = this->query(request, DrmQueryItemFlags::empty);
|
|
|
|
if (deviceBlobQuery.empty()) {
|
2021-12-14 17:46:01 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stdout, "%s", "INFO: System Info query failed!\n");
|
|
|
|
return false;
|
|
|
|
}
|
2021-12-22 22:25:53 +08:00
|
|
|
this->systemInfo.reset(new SystemInfo(deviceBlobQuery));
|
2021-12-14 17:46:01 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-12-14 20:41:38 +08:00
|
|
|
void Drm::appendDrmContextFlags(drm_i915_gem_context_create_ext &gcc, bool isDirectSubmissionRequested) {
|
|
|
|
if (DebugManager.flags.DirectSubmissionDrmContext.get() != -1) {
|
|
|
|
isDirectSubmissionRequested = DebugManager.flags.DirectSubmissionDrmContext.get();
|
|
|
|
}
|
|
|
|
if (isDirectSubmissionRequested) {
|
2022-01-21 20:39:11 +08:00
|
|
|
gcc.flags |= ioctlHelper->getDirectSubmissionFlag();
|
2021-12-14 20:41:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-28 23:56:13 +08:00
|
|
|
std::vector<uint8_t> Drm::getMemoryRegions() {
|
2022-01-21 20:39:11 +08:00
|
|
|
return this->query(ioctlHelper->getMemRegionsIoctlVal(), DrmQueryItemFlags::empty);
|
2021-12-28 23:56:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Drm::queryMemoryInfo() {
|
|
|
|
auto dataQuery = getMemoryRegions();
|
|
|
|
if (!dataQuery.empty()) {
|
2022-01-21 20:39:11 +08:00
|
|
|
auto memRegions = ioctlHelper->translateToMemoryRegions(dataQuery);
|
2021-12-28 23:56:13 +08:00
|
|
|
this->memoryInfo.reset(new MemoryInfo(memRegions));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-01-04 22:48:05 +08:00
|
|
|
bool Drm::queryEngineInfo(bool isSysmanEnabled) {
|
|
|
|
auto enginesQuery = this->query(ioctlHelper->getEngineInfoIoctlVal(), DrmQueryItemFlags::empty);
|
|
|
|
if (enginesQuery.empty()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto engines = ioctlHelper->translateToEngineCaps(enginesQuery);
|
2022-01-12 23:32:14 +08:00
|
|
|
auto hwInfo = rootDeviceEnvironment.getMutableHardwareInfo();
|
2022-01-04 22:48:05 +08:00
|
|
|
|
|
|
|
auto memInfo = memoryInfo.get();
|
|
|
|
|
|
|
|
if (!memInfo) {
|
2022-01-12 23:32:14 +08:00
|
|
|
this->engineInfo.reset(new EngineInfo(this, hwInfo, engines));
|
|
|
|
return true;
|
2022-01-04 22:48:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
auto &memoryRegions = memInfo->getDrmRegionInfos();
|
|
|
|
|
|
|
|
auto tileCount = 0u;
|
|
|
|
std::vector<DistanceInfo> distanceInfos;
|
|
|
|
for (const auto ®ion : memoryRegions) {
|
|
|
|
if (I915_MEMORY_CLASS_DEVICE == region.region.memoryClass) {
|
|
|
|
tileCount++;
|
|
|
|
DistanceInfo distanceInfo{};
|
|
|
|
distanceInfo.region = region.region;
|
|
|
|
|
|
|
|
for (const auto &engine : engines) {
|
|
|
|
switch (engine.engine.engineClass) {
|
|
|
|
case I915_ENGINE_CLASS_RENDER:
|
|
|
|
case I915_ENGINE_CLASS_COPY:
|
|
|
|
distanceInfo.engine = engine.engine;
|
|
|
|
distanceInfos.push_back(distanceInfo);
|
|
|
|
break;
|
|
|
|
case I915_ENGINE_CLASS_VIDEO:
|
|
|
|
case I915_ENGINE_CLASS_VIDEO_ENHANCE:
|
|
|
|
if (isSysmanEnabled == true) {
|
|
|
|
distanceInfo.engine = engine.engine;
|
|
|
|
distanceInfos.push_back(distanceInfo);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (engine.engine.engineClass == ioctlHelper->getComputeEngineClass()) {
|
|
|
|
distanceInfo.engine = engine.engine;
|
|
|
|
distanceInfos.push_back(distanceInfo);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tileCount == 0u) {
|
|
|
|
this->engineInfo.reset(new EngineInfo(this, hwInfo, engines));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<drm_i915_query_item> queryItems{distanceInfos.size()};
|
|
|
|
auto ret = ioctlHelper->queryDistances(this, queryItems, distanceInfos);
|
|
|
|
if (ret != 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const bool queryUnsupported = std::all_of(queryItems.begin(), queryItems.end(),
|
|
|
|
[](const drm_i915_query_item &item) { return item.length == -EINVAL; });
|
|
|
|
if (queryUnsupported) {
|
|
|
|
DEBUG_BREAK_IF(tileCount != 1);
|
|
|
|
this->engineInfo.reset(new EngineInfo(this, hwInfo, engines));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
memInfo->assignRegionsFromDistances(distanceInfos);
|
|
|
|
|
|
|
|
auto &multiTileArchInfo = const_cast<GT_MULTI_TILE_ARCH_INFO &>(hwInfo->gtSystemInfo.MultiTileArchInfo);
|
|
|
|
multiTileArchInfo.IsValid = true;
|
|
|
|
multiTileArchInfo.TileCount = tileCount;
|
|
|
|
multiTileArchInfo.TileMask = static_cast<uint8_t>(maxNBitValue(tileCount));
|
|
|
|
|
|
|
|
this->engineInfo.reset(new EngineInfo(this, hwInfo, tileCount, distanceInfos, queryItems, engines));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-01-21 02:13:07 +08:00
|
|
|
bool Drm::completionFenceSupport() {
|
|
|
|
std::call_once(checkCompletionFenceOnce, [this]() {
|
2022-01-21 20:39:11 +08:00
|
|
|
bool support = ioctlHelper->completionFenceExtensionSupported(*this, *getRootDeviceEnvironment().getHardwareInfo());
|
2022-01-21 02:13:07 +08:00
|
|
|
int32_t overrideCompletionFence = DebugManager.flags.EnableDrmCompletionFence.get();
|
|
|
|
if (overrideCompletionFence != -1) {
|
|
|
|
support = !!overrideCompletionFence;
|
|
|
|
}
|
|
|
|
|
|
|
|
completionFenceSupported = support;
|
|
|
|
});
|
|
|
|
return completionFenceSupported;
|
|
|
|
}
|
|
|
|
|
2022-01-29 05:00:05 +08:00
|
|
|
void Drm::setupIoctlHelper(const PRODUCT_FAMILY productFamily) {
|
2022-01-21 20:39:11 +08:00
|
|
|
std::string prelimVersion = "";
|
|
|
|
getPrelimVersion(prelimVersion);
|
2022-01-29 05:00:05 +08:00
|
|
|
this->ioctlHelper.reset(IoctlHelper::get(productFamily, prelimVersion));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Drm::queryTopology(const HardwareInfo &hwInfo, QueryTopologyData &topologyData) {
|
|
|
|
topologyData.sliceCount = 0;
|
|
|
|
topologyData.subSliceCount = 0;
|
|
|
|
topologyData.euCount = 0;
|
|
|
|
|
|
|
|
int sliceCount = 0;
|
|
|
|
int subSliceCount = 0;
|
|
|
|
int euCount = 0;
|
|
|
|
|
|
|
|
const auto queryComputeSlicesIoctl = ioctlHelper->getComputeSlicesIoctlVal();
|
|
|
|
if (DebugManager.flags.UseNewQueryTopoIoctl.get() && this->engineInfo && hwInfo.gtSystemInfo.MultiTileArchInfo.TileCount > 0 && queryComputeSlicesIoctl != 0) {
|
|
|
|
bool success = true;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < hwInfo.gtSystemInfo.MultiTileArchInfo.TileCount; i++) {
|
|
|
|
auto classInstance = this->engineInfo->getEngineInstance(i, hwInfo.capabilityTable.defaultEngineType);
|
|
|
|
UNRECOVERABLE_IF(!classInstance);
|
|
|
|
|
|
|
|
uint32_t flags = classInstance->engineClass;
|
|
|
|
flags |= (classInstance->engineInstance << 8);
|
|
|
|
|
|
|
|
auto dataQuery = this->query(queryComputeSlicesIoctl, flags);
|
|
|
|
if (dataQuery.empty()) {
|
|
|
|
success = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
auto data = reinterpret_cast<drm_i915_query_topology_info *>(dataQuery.data());
|
|
|
|
|
|
|
|
QueryTopologyData tileTopologyData = {};
|
|
|
|
TopologyMapping mapping;
|
|
|
|
if (!translateTopologyInfo(data, tileTopologyData, mapping)) {
|
|
|
|
success = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// pick smallest config
|
|
|
|
sliceCount = (sliceCount == 0) ? tileTopologyData.sliceCount : std::min(sliceCount, tileTopologyData.sliceCount);
|
|
|
|
subSliceCount = (subSliceCount == 0) ? tileTopologyData.subSliceCount : std::min(subSliceCount, tileTopologyData.subSliceCount);
|
|
|
|
euCount = (euCount == 0) ? tileTopologyData.euCount : std::min(euCount, tileTopologyData.euCount);
|
|
|
|
|
|
|
|
topologyData.maxSliceCount = std::max(topologyData.maxSliceCount, tileTopologyData.maxSliceCount);
|
|
|
|
topologyData.maxSubSliceCount = std::max(topologyData.maxSubSliceCount, tileTopologyData.maxSubSliceCount);
|
|
|
|
topologyData.maxEuCount = std::max(topologyData.maxEuCount, static_cast<int>(data->max_eus_per_subslice));
|
|
|
|
|
|
|
|
this->topologyMap[i] = mapping;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
topologyData.sliceCount = sliceCount;
|
|
|
|
topologyData.subSliceCount = subSliceCount;
|
|
|
|
topologyData.euCount = euCount;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// fallback to DRM_I915_QUERY_TOPOLOGY_INFO
|
|
|
|
|
|
|
|
auto dataQuery = this->query(DRM_I915_QUERY_TOPOLOGY_INFO, DrmQueryItemFlags::topology);
|
|
|
|
if (dataQuery.empty()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto data = reinterpret_cast<drm_i915_query_topology_info *>(dataQuery.data());
|
|
|
|
|
|
|
|
TopologyMapping mapping;
|
|
|
|
auto retVal = translateTopologyInfo(data, topologyData, mapping);
|
|
|
|
topologyData.maxEuCount = data->max_eus_per_subslice;
|
|
|
|
|
|
|
|
this->topologyMap.clear();
|
|
|
|
this->topologyMap[0] = mapping;
|
|
|
|
|
|
|
|
return retVal;
|
2022-01-21 20:39:11 +08:00
|
|
|
}
|
|
|
|
|
2022-02-11 00:16:37 +08:00
|
|
|
void Drm::queryPageFaultSupport() {
|
|
|
|
|
|
|
|
if (const auto paramId = ioctlHelper->getHasPageFaultParamId(); paramId) {
|
|
|
|
int support = 0;
|
|
|
|
const auto ret = getParamIoctl(*paramId, &support);
|
|
|
|
pageFaultSupported = (0 == ret) && (support > 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Drm::hasPageFaultSupport() const {
|
|
|
|
if (DebugManager.flags.EnableRecoverablePageFaults.get() != -1) {
|
|
|
|
return DebugManager.flags.EnableRecoverablePageFaults.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
return pageFaultSupported;
|
|
|
|
}
|
|
|
|
|
2022-02-11 21:46:23 +08:00
|
|
|
unsigned int Drm::bindDrmContext(uint32_t drmContextId, uint32_t deviceIndex, aub_stream::EngineType engineType, bool engineInstancedDevice) {
|
|
|
|
auto engineInfo = this->engineInfo.get();
|
|
|
|
if (!engineInfo) {
|
|
|
|
return DrmEngineMapper::engineNodeMap(engineType);
|
|
|
|
}
|
|
|
|
auto engine = engineInfo->getEngineInstance(deviceIndex, engineType);
|
|
|
|
if (!engine) {
|
|
|
|
return DrmEngineMapper::engineNodeMap(engineType);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool useVirtualEnginesForCcs = !engineInstancedDevice;
|
|
|
|
if (DebugManager.flags.UseDrmVirtualEnginesForCcs.get() != -1) {
|
|
|
|
useVirtualEnginesForCcs = !!DebugManager.flags.UseDrmVirtualEnginesForCcs.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto numberOfCCS = rootDeviceEnvironment.getHardwareInfo()->gtSystemInfo.CCSInfo.NumberOfCCSEnabled;
|
|
|
|
constexpr uint32_t maxEngines = 9u;
|
|
|
|
|
|
|
|
bool useVirtualEnginesForBcs = EngineHelpers::isBcsVirtualEngineEnabled();
|
|
|
|
auto numberOfBCS = rootDeviceEnvironment.getHardwareInfo()->featureTable.ftrBcsInfo.count();
|
|
|
|
|
|
|
|
if (DebugManager.flags.LimitEngineCountForVirtualBcs.get() != -1) {
|
|
|
|
numberOfBCS = DebugManager.flags.LimitEngineCountForVirtualBcs.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DebugManager.flags.LimitEngineCountForVirtualCcs.get() != -1) {
|
|
|
|
numberOfCCS = DebugManager.flags.LimitEngineCountForVirtualCcs.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t numEnginesInContext = 1;
|
|
|
|
|
|
|
|
I915_DEFINE_CONTEXT_PARAM_ENGINES(contextEngines, 1 + maxEngines){};
|
|
|
|
I915_DEFINE_CONTEXT_ENGINES_LOAD_BALANCE(balancer, maxEngines){};
|
|
|
|
|
|
|
|
contextEngines.engines[0] = {engine->engineClass, engine->engineInstance};
|
|
|
|
|
|
|
|
bool setupVirtualEngines = false;
|
|
|
|
unsigned int engineCount = static_cast<unsigned int>(numberOfCCS);
|
|
|
|
if (useVirtualEnginesForCcs && engine->engineClass == ioctlHelper->getComputeEngineClass() && numberOfCCS > 1u) {
|
|
|
|
numEnginesInContext = numberOfCCS + 1;
|
|
|
|
balancer.num_siblings = numberOfCCS;
|
|
|
|
setupVirtualEngines = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool includeMainCopyEngineInGroup = false;
|
|
|
|
if (useVirtualEnginesForBcs && engine->engineClass == I915_ENGINE_CLASS_COPY && numberOfBCS > 1u) {
|
|
|
|
numEnginesInContext = static_cast<uint32_t>(numberOfBCS) + 1;
|
|
|
|
balancer.num_siblings = numberOfBCS;
|
|
|
|
setupVirtualEngines = true;
|
|
|
|
engineCount = static_cast<unsigned int>(rootDeviceEnvironment.getHardwareInfo()->featureTable.ftrBcsInfo.size());
|
|
|
|
if (EngineHelpers::getBcsIndex(engineType) == 0u) {
|
|
|
|
includeMainCopyEngineInGroup = true;
|
|
|
|
} else {
|
|
|
|
engineCount--;
|
|
|
|
balancer.num_siblings = numberOfBCS - 1;
|
|
|
|
numEnginesInContext = static_cast<uint32_t>(numberOfBCS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setupVirtualEngines) {
|
|
|
|
balancer.base.name = I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE;
|
|
|
|
contextEngines.extensions = castToUint64(&balancer);
|
|
|
|
contextEngines.engines[0].engine_class = I915_ENGINE_CLASS_INVALID;
|
|
|
|
contextEngines.engines[0].engine_instance = I915_ENGINE_CLASS_INVALID_NONE;
|
|
|
|
|
|
|
|
for (auto engineIndex = 0u; engineIndex < engineCount; engineIndex++) {
|
|
|
|
if (useVirtualEnginesForBcs && engine->engineClass == I915_ENGINE_CLASS_COPY) {
|
|
|
|
auto mappedBcsEngineType = static_cast<aub_stream::EngineType>(EngineHelpers::mapBcsIndexToEngineType(engineIndex, includeMainCopyEngineInGroup));
|
|
|
|
bool isBcsEnabled = rootDeviceEnvironment.getHardwareInfo()->featureTable.ftrBcsInfo.test(EngineHelpers::getBcsIndex(mappedBcsEngineType));
|
|
|
|
|
|
|
|
if (!isBcsEnabled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
engine = engineInfo->getEngineInstance(deviceIndex, mappedBcsEngineType);
|
|
|
|
}
|
|
|
|
UNRECOVERABLE_IF(!engine);
|
|
|
|
|
|
|
|
if (useVirtualEnginesForCcs && engine->engineClass == ioctlHelper->getComputeEngineClass()) {
|
|
|
|
engine = engineInfo->getEngineInstance(deviceIndex, static_cast<aub_stream::EngineType>(EngineHelpers::mapCcsIndexToEngineType(engineIndex)));
|
|
|
|
}
|
|
|
|
UNRECOVERABLE_IF(!engine);
|
|
|
|
balancer.engines[engineIndex] = {engine->engineClass, engine->engineInstance};
|
|
|
|
contextEngines.engines[1 + engineIndex] = {engine->engineClass, engine->engineInstance};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
drm_i915_gem_context_param param{};
|
|
|
|
param.ctx_id = drmContextId;
|
|
|
|
param.size = static_cast<uint32_t>(ptrDiff(contextEngines.engines + numEnginesInContext, &contextEngines));
|
|
|
|
param.param = I915_CONTEXT_PARAM_ENGINES;
|
|
|
|
param.value = castToUint64(&contextEngines);
|
|
|
|
|
|
|
|
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, ¶m);
|
|
|
|
UNRECOVERABLE_IF(retVal != 0);
|
|
|
|
|
|
|
|
return I915_EXEC_DEFAULT;
|
|
|
|
}
|
|
|
|
|
2022-02-11 23:03:58 +08:00
|
|
|
void Drm::waitForBind(uint32_t vmHandleId) {
|
|
|
|
if (pagingFence[vmHandleId] >= fenceVal[vmHandleId]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto lock = this->lockBindFenceMutex();
|
|
|
|
waitUserFence(0u, castToUint64(&this->pagingFence[vmHandleId]), this->fenceVal[vmHandleId], ValueWidth::U64, -1, ioctlHelper->getWaitUserFenceSoftFlag());
|
|
|
|
}
|
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
} // namespace NEO
|