Files
compute-runtime/shared/source/os_interface/linux/ioctl_helper_prelim.cpp
Szymon Morek 242b08d72b Add advise for atomic and preferred location
If supported, allow atomic and preferred location
advises. Hide this logic under IoctlHelper.

Signed-off-by: Szymon Morek <szymon.morek@intel.com>
2021-12-15 16:02:19 +01:00

167 lines
6.0 KiB
C++

/*
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/helpers/debug_helpers.h"
#include "shared/source/os_interface/linux/cache_info.h"
#include "shared/source/os_interface/linux/ioctl_helper.h"
#include "third_party/uapi/prelim/drm/i915_drm.h"
#include <cerrno>
#include <cstring>
#include <sys/ioctl.h>
namespace NEO {
uint32_t IoctlHelperPrelim20::createGemExt(Drm *drm, void *data, uint32_t dataSize, size_t allocSize, uint32_t &handle) {
prelim_drm_i915_gem_object_param regionParam{};
regionParam.size = dataSize;
regionParam.data = reinterpret_cast<uintptr_t>(data);
regionParam.param = PRELIM_I915_OBJECT_PARAM | PRELIM_I915_PARAM_MEMORY_REGIONS;
prelim_drm_i915_gem_create_ext_setparam setparamRegion{};
setparamRegion.base.name = PRELIM_I915_GEM_CREATE_EXT_SETPARAM;
setparamRegion.param = regionParam;
prelim_drm_i915_gem_create_ext createExt{};
createExt.size = allocSize;
createExt.extensions = reinterpret_cast<uintptr_t>(&setparamRegion);
printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "Performing GEM_CREATE_EXT with { size: %lu, param: 0x%llX",
allocSize, regionParam.param);
if (DebugManager.flags.PrintBOCreateDestroyResult.get()) {
for (uint32_t i = 0; i < dataSize; i++) {
auto region = reinterpret_cast<prelim_drm_i915_gem_memory_class_instance *>(data)[i];
printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, ", memory class: %d, memory instance: %d",
region.memory_class, region.memory_instance);
}
printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "%s", " }\n");
}
auto ret = IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_CREATE_EXT, &createExt);
printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "GEM_CREATE_EXT has returned: %d BO-%u with size: %lu\n", ret, createExt.handle, createExt.size);
handle = createExt.handle;
return ret;
}
std::unique_ptr<uint8_t[]> IoctlHelperPrelim20::translateIfRequired(uint8_t *dataQuery, int32_t length) {
return std::unique_ptr<uint8_t[]>(dataQuery);
}
CacheRegion IoctlHelperPrelim20::closAlloc(Drm *drm) {
struct prelim_drm_i915_gem_clos_reserve clos = {};
int ret = IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_CLOS_RESERVE, &clos);
if (ret != 0) {
int err = errno;
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(I915_GEM_CLOS_RESERVE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err));
DEBUG_BREAK_IF(true);
return CacheRegion::None;
}
return static_cast<CacheRegion>(clos.clos_index);
}
uint16_t IoctlHelperPrelim20::closAllocWays(Drm *drm, CacheRegion closIndex, uint16_t cacheLevel, uint16_t numWays) {
struct prelim_drm_i915_gem_cache_reserve cache = {};
cache.clos_index = static_cast<uint16_t>(closIndex);
cache.cache_level = cacheLevel;
cache.num_ways = numWays;
int ret = IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_CACHE_RESERVE, &cache);
if (ret != 0) {
int err = errno;
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(I915_GEM_CACHE_RESERVE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err));
return 0;
}
return cache.num_ways;
}
CacheRegion IoctlHelperPrelim20::closFree(Drm *drm, CacheRegion closIndex) {
struct prelim_drm_i915_gem_clos_free clos = {};
clos.clos_index = static_cast<uint16_t>(closIndex);
int ret = IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_CLOS_FREE, &clos);
if (ret != 0) {
int err = errno;
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(I915_GEM_CLOS_FREE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err));
DEBUG_BREAK_IF(true);
return CacheRegion::None;
}
return closIndex;
}
int IoctlHelperPrelim20::waitUserFence(Drm *drm, uint32_t ctxId, uint64_t address,
uint64_t value, uint32_t dataWidth, int64_t timeout, uint16_t flags) {
prelim_drm_i915_gem_wait_user_fence wait = {};
wait.ctx_id = ctxId;
wait.flags = flags;
switch (dataWidth) {
case 3u:
wait.mask = PRELIM_I915_UFENCE_WAIT_U64;
break;
case 2u:
wait.mask = PRELIM_I915_UFENCE_WAIT_U32;
break;
case 1u:
wait.mask = PRELIM_I915_UFENCE_WAIT_U16;
break;
default:
wait.mask = PRELIM_I915_UFENCE_WAIT_U8;
break;
}
wait.op = PRELIM_I915_UFENCE_WAIT_GTE;
wait.addr = address;
wait.value = value;
wait.timeout = timeout;
return IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_WAIT_USER_FENCE, &wait);
}
uint32_t IoctlHelperPrelim20::getHwConfigIoctlVal() {
return PRELIM_DRM_I915_QUERY_HWCONFIG_TABLE;
}
uint32_t IoctlHelperPrelim20::getAtomicAdvise(bool isNonAtomic) {
return isNonAtomic ? PRELIM_I915_VM_ADVISE_ATOMIC_NONE : PRELIM_I915_VM_ADVISE_ATOMIC_SYSTEM;
}
uint32_t IoctlHelperPrelim20::getPreferredLocationAdvise() {
return PRELIM_I915_VM_ADVISE_PREFERRED_LOCATION;
}
bool IoctlHelperPrelim20::setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) {
prelim_drm_i915_gem_vm_advise vmAdvise{};
vmAdvise.handle = handle;
vmAdvise.attribute = attribute;
if (region != nullptr) {
vmAdvise.region = *reinterpret_cast<prelim_drm_i915_gem_memory_class_instance *>(region);
}
int ret = IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_VM_ADVISE, &vmAdvise);
if (ret != 0) {
int err = errno;
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(PRELIM_DRM_I915_GEM_VM_ADVISE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err));
DEBUG_BREAK_IF(true);
return false;
}
return true;
}
} // namespace NEO