Discover GPU topology from i915

Resolves: NEO-4718

Change-Id: I0547c109b961c3732e64b6f22ec761a5943c65ef
Signed-off-by: Bartosz Dunajski <bartosz.dunajski@intel.com>
This commit is contained in:
Bartosz Dunajski
2020-06-09 15:51:26 +02:00
committed by sys_ocldev
parent 59da9598aa
commit 5af401b7bb
24 changed files with 223 additions and 66 deletions

View File

@@ -12,6 +12,7 @@
#include "shared/source/helpers/constants.h"
#include "shared/source/helpers/debug_helpers.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/helpers/ptr_math.h"
#include "shared/source/os_interface/linux/hw_device_id.h"
#include "shared/source/os_interface/linux/os_inc.h"
#include "shared/source/os_interface/linux/sys_calls.h"
@@ -230,23 +231,33 @@ int Drm::getErrno() {
int Drm::setupHardwareInfo(DeviceDescriptor *device, bool setupFeatureTableAndWorkaroundTable) {
HardwareInfo *hwInfo = const_cast<HardwareInfo *>(device->pHwInfo);
int ret;
int sliceTotal;
int subSliceTotal;
int euTotal;
int subsliceTotal;
ret = getEuTotal(euTotal);
if (ret != 0) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query EU total parameter!\n");
return ret;
}
ret = getSubsliceTotal(subsliceTotal);
if (ret != 0) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query subslice total parameter!\n");
return ret;
bool status = queryTopology(sliceTotal, subSliceTotal, euTotal);
if (!status) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "WARNING: Topology query failed!\n");
sliceTotal = hwInfo->gtSystemInfo.SliceCount;
ret = getEuTotal(euTotal);
if (ret != 0) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query EU total parameter!\n");
return ret;
}
ret = getSubsliceTotal(subSliceTotal);
if (ret != 0) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query subslice total parameter!\n");
return ret;
}
}
hwInfo->gtSystemInfo.SliceCount = static_cast<uint32_t>(sliceTotal);
hwInfo->gtSystemInfo.SubSliceCount = static_cast<uint32_t>(subSliceTotal);
hwInfo->gtSystemInfo.EUCount = static_cast<uint32_t>(euTotal);
hwInfo->gtSystemInfo.SubSliceCount = static_cast<uint32_t>(subsliceTotal);
device->setupHardwareInfo(hwInfo, setupFeatureTableAndWorkaroundTable);
return 0;
}
@@ -329,6 +340,71 @@ bool Drm::isi915Version(int fileDescriptor) {
return strcmp(name, "i915") == 0;
}
std::unique_ptr<uint8_t[]> Drm::query(uint32_t queryId, int32_t &length) {
drm_i915_query query{};
drm_i915_query_item queryItem{};
queryItem.query_id = queryId;
queryItem.length = 0; // query length first
query.items_ptr = reinterpret_cast<__u64>(&queryItem);
query.num_items = 1;
length = 0;
auto ret = this->ioctl(DRM_IOCTL_I915_QUERY, &query);
if (ret != 0 || queryItem.length <= 0) {
return nullptr;
}
auto data = std::make_unique<uint8_t[]>(queryItem.length);
memset(data.get(), 0, queryItem.length);
queryItem.data_ptr = castToUint64(data.get());
ret = this->ioctl(DRM_IOCTL_I915_QUERY, &query);
if (ret != 0 || queryItem.length <= 0) {
return nullptr;
}
length = queryItem.length;
return data;
}
bool Drm::queryTopology(int &sliceCount, int &subSliceCount, int &euCount) {
int32_t length;
auto dataQuery = this->query(DRM_I915_QUERY_TOPOLOGY_INFO, length);
auto data = reinterpret_cast<drm_i915_query_topology_info *>(dataQuery.get());
if (!data) {
return false;
}
sliceCount = 0;
subSliceCount = 0;
euCount = 0;
for (int x = 0; x < data->max_slices; x++) {
bool isSliceEnable = (data->data[x / 8] >> (x % 8)) & 1;
if (!isSliceEnable) {
continue;
}
sliceCount++;
for (int y = 0; y < data->max_subslices; y++) {
bool isSubSliceEnabled = (data->data[data->subslice_offset + x * data->subslice_stride + y / 8] >> (y % 8)) & 1;
if (!isSubSliceEnabled) {
continue;
}
subSliceCount++;
for (int z = 0; z < data->max_eus_per_subslice; z++) {
bool isEUEnabled = (data->data[data->eu_offset + (x * data->max_subslices + y) * data->eu_stride + z / 8] >> (z % 8)) & 1;
if (!isEUEnabled) {
continue;
}
euCount++;
}
}
}
return true;
}
Drm::~Drm() = default;
} // namespace NEO

View File

@@ -79,6 +79,7 @@ class Drm {
uint64_t getSliceMask(uint64_t sliceCount);
bool queryEngineInfo();
bool queryMemoryInfo();
bool queryTopology(int &sliceCount, int &subSliceCount, int &euCount);
int setupHardwareInfo(DeviceDescriptor *, bool);
bool areNonPersistentContextsSupported() const { return nonPersistentContextsSupported; }

View File

@@ -19,7 +19,7 @@ class DrmNullDevice : public Drm {
public:
int ioctl(unsigned long request, void *arg) override {
if (request == DRM_IOCTL_I915_GETPARAM) {
if (request == DRM_IOCTL_I915_GETPARAM || request == DRM_IOCTL_I915_QUERY) {
return Drm::ioctl(request, arg);
} else if (request == DRM_IOCTL_I915_REG_READ) {
struct drm_i915_reg_read *regArg = static_cast<struct drm_i915_reg_read *>(arg);

View File

@@ -29,11 +29,6 @@ int Drm::getMaxGpuFrequency(HardwareInfo &hwInfo, int &maxGpuFrequency) {
return 0;
}
std::unique_ptr<uint8_t[]> Drm::query(uint32_t queryId, int32_t &length) {
length = 0;
return nullptr;
}
bool Drm::queryEngineInfo() {
return true;
}

View File

@@ -89,23 +89,36 @@ int HwInfoConfig::configureHwInfo(const HardwareInfo *inHwInfo, HardwareInfo *ou
}
platform->usRevId = static_cast<unsigned short>(val);
int euCount;
ret = drm->getEuTotal(euCount);
if (ret != 0) {
*outHwInfo = {};
return ret;
}
gtSystemInfo->EUCount = static_cast<uint32_t>(euCount);
gtSystemInfo->ThreadCount = this->threadsPerEu * gtSystemInfo->EUCount;
int sliceCount;
int subSliceCount;
ret = drm->getSubsliceTotal(subSliceCount);
if (ret != 0) {
*outHwInfo = {};
return ret;
int euCount;
bool status = drm->queryTopology(sliceCount, subSliceCount, euCount);
if (!status) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "WARNING: Topology query failed!\n");
sliceCount = gtSystemInfo->SliceCount;
ret = drm->getEuTotal(euCount);
if (ret != 0) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query EU total parameter!\n");
*outHwInfo = {};
return ret;
}
ret = drm->getSubsliceTotal(subSliceCount);
if (ret != 0) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query subslice total parameter!\n");
*outHwInfo = {};
return ret;
}
}
gtSystemInfo->SliceCount = static_cast<uint32_t>(sliceCount);
gtSystemInfo->SubSliceCount = static_cast<uint32_t>(subSliceCount);
gtSystemInfo->EUCount = static_cast<uint32_t>(euCount);
gtSystemInfo->ThreadCount = this->threadsPerEu * gtSystemInfo->EUCount;
uint64_t gttSizeQuery = 0;
featureTable->ftrSVM = true;