From 6258575e5e18065fa7fa30652cc365660d953d7e Mon Sep 17 00:00:00 2001 From: Szymon Morek Date: Mon, 3 Jan 2022 14:16:00 +0000 Subject: [PATCH] Use queryEngineInfo with prelim ioctls If prelim kernel is being used, query engines with prelim ioctls. Signed-off-by: Szymon Morek --- .../sysman/engine/linux/os_engine_imp.cpp | 6 +-- .../sources/sysman/engine/linux/mock_engine.h | 30 +++++------ .../linux/ioctl_helper_tests_prelim.cpp | 51 ++++++++++++++++++- .../linux/ioctl_helper_tests_upstream.cpp | 23 ++++++++- .../os_interface/linux/prelim_helper_func.cpp | 29 ++++++++++- .../source/os_interface/linux/drm_query.cpp | 9 ++-- .../os_interface/linux/engine_info_impl.h | 7 +-- .../source/os_interface/linux/ioctl_helper.h | 17 ++++++- .../linux/ioctl_helper_prelim.cpp | 51 ++++++++++++++++++- .../linux/ioctl_helper_upstream.cpp | 26 +++++++++- 10 files changed, 218 insertions(+), 31 deletions(-) diff --git a/level_zero/tools/source/sysman/engine/linux/os_engine_imp.cpp b/level_zero/tools/source/sysman/engine/linux/os_engine_imp.cpp index 01fac918d8..17776bfbc8 100644 --- a/level_zero/tools/source/sysman/engine/linux/os_engine_imp.cpp +++ b/level_zero/tools/source/sysman/engine/linux/os_engine_imp.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2021 Intel Corporation + * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -36,10 +36,10 @@ ze_result_t OsEngine::getNumEngineTypeAndInstances(std::set(pDrm->getEngineInfo()); for (auto itr = engineInfo->engines.begin(); itr != engineInfo->engines.end(); ++itr) { - auto i915ToEngineMapRange = i915ToEngineMap.equal_range(static_cast<__u16>(itr->engine.engine_class)); + auto i915ToEngineMapRange = i915ToEngineMap.equal_range(static_cast<__u16>(itr->engine.engineClass)); for (auto L0EngineEntryInMap = i915ToEngineMapRange.first; L0EngineEntryInMap != i915ToEngineMapRange.second; L0EngineEntryInMap++) { auto L0EngineType = L0EngineEntryInMap->second; - engineGroupInstance.insert({L0EngineType, {static_cast(itr->engine.engine_instance), 0}}); + engineGroupInstance.insert({L0EngineType, {static_cast(itr->engine.engineInstance), 0}}); } } return ZE_RESULT_SUCCESS; diff --git a/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine.h b/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine.h index f3b54c2933..f8ee8a5703 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2021 Intel Corporation + * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -40,21 +40,21 @@ struct Mock : public EngineNeoDrm { Mock(RootDeviceEnvironment &rootDeviceEnvironment) : EngineNeoDrm(rootDeviceEnvironment) {} bool queryEngineInfoMockPositiveTest() { - drm_i915_engine_info i915engineInfo[6] = {}; - i915engineInfo[0].engine.engine_class = I915_ENGINE_CLASS_RENDER; - i915engineInfo[0].engine.engine_instance = 0; - i915engineInfo[1].engine.engine_class = I915_ENGINE_CLASS_RENDER; - i915engineInfo[1].engine.engine_instance = 1; - i915engineInfo[2].engine.engine_class = I915_ENGINE_CLASS_VIDEO; - i915engineInfo[2].engine.engine_instance = 1; - i915engineInfo[3].engine.engine_class = I915_ENGINE_CLASS_COPY; - i915engineInfo[3].engine.engine_instance = 0; - i915engineInfo[4].engine.engine_class = I915_ENGINE_CLASS_VIDEO_ENHANCE; - i915engineInfo[4].engine.engine_instance = 0; - i915engineInfo[5].engine.engine_class = I915_INVALID_ENGINE_CLASS; - i915engineInfo[5].engine.engine_instance = 0; + std::vector i915engineInfo(6); + i915engineInfo[0].engine.engineClass = I915_ENGINE_CLASS_RENDER; + i915engineInfo[0].engine.engineInstance = 0; + i915engineInfo[1].engine.engineClass = I915_ENGINE_CLASS_RENDER; + i915engineInfo[1].engine.engineInstance = 1; + i915engineInfo[2].engine.engineClass = I915_ENGINE_CLASS_VIDEO; + i915engineInfo[2].engine.engineInstance = 1; + i915engineInfo[3].engine.engineClass = I915_ENGINE_CLASS_COPY; + i915engineInfo[3].engine.engineInstance = 0; + i915engineInfo[4].engine.engineClass = I915_ENGINE_CLASS_VIDEO_ENHANCE; + i915engineInfo[4].engine.engineInstance = 0; + i915engineInfo[5].engine.engineClass = I915_INVALID_ENGINE_CLASS; + i915engineInfo[5].engine.engineInstance = 0; - this->engineInfo.reset(new EngineInfoImpl(i915engineInfo, 6)); + this->engineInfo.reset(new EngineInfoImpl(i915engineInfo)); return true; } diff --git a/opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp b/opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp index 0392dd8fc6..9b34c82a33 100644 --- a/opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp +++ b/opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -17,6 +17,7 @@ using namespace NEO; extern int handlePrelimRequests(unsigned long request, void *arg, int ioctlRetVal); extern std::vector getRegionInfo(const std::vector &inputRegions); +extern std::vector getEngineInfo(const std::vector &inputEngines); class DrmPrelimMock : public DrmMock { public: @@ -307,3 +308,51 @@ TEST(IoctlHelperTestsPrelim, givenPrelimsWhenGetMemRegionsIoctlValThenCorrectVal int32_t ioctlVal = (1 << 16) | 4; EXPECT_EQ(ioctlVal, IoctlHelper::get(drm.get())->getMemRegionsIoctlVal()); } + +TEST(IoctlHelperTestsPrelim, givenPrelimsWhenGetEngineInfoIoctlValThenCorrectValueReturned) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + + int32_t ioctlVal = (1 << 16) | 13; + EXPECT_EQ(ioctlVal, IoctlHelper::get(drm.get())->getEngineInfoIoctlVal()); +} + +TEST(IoctlHelperTestsPrelim, givenPrelimsWhenTranslateToEngineCapsThenReturnSameData) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + std::vector expectedEngines(2); + expectedEngines[0] = {{I915_ENGINE_CLASS_RENDER, 0}, 0}; + expectedEngines[1] = {{I915_ENGINE_CLASS_COPY, 1}, 0}; + + auto engineInfo = getEngineInfo(expectedEngines); + + auto ioctlHelper = IoctlHelper::get(drm.get()); + auto engines = ioctlHelper->translateToEngineCaps(engineInfo); + EXPECT_EQ(2u, engines.size()); + for (uint32_t i = 0; i < engines.size(); i++) { + EXPECT_EQ(expectedEngines[i].engine.engineClass, engines[i].engine.engineClass); + EXPECT_EQ(expectedEngines[i].engine.engineInstance, engines[i].engine.engineInstance); + EXPECT_EQ(expectedEngines[i].capabilities, engines[i].capabilities); + } +} + +TEST(IoctlHelperTestsPrelim, givenPrelimsWhenQueryDistancesThenCorrectDistanceSet) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + std::vector distances(3); + distances[0].engine = {I915_ENGINE_CLASS_RENDER, 0}; + distances[0].region = {I915_MEMORY_CLASS_DEVICE, 0}; + distances[1].engine = {I915_ENGINE_CLASS_RENDER, 1}; + distances[1].region = {I915_MEMORY_CLASS_DEVICE, 1}; + distances[2].engine = {I915_ENGINE_CLASS_COPY, 4}; + distances[2].region = {I915_MEMORY_CLASS_DEVICE, 2}; + std::vector queryItems(distances.size()); + auto ret = IoctlHelper::get(drm.get())->queryDistances(drm.get(), queryItems, distances); + EXPECT_EQ(0u, ret); + EXPECT_EQ(0, distances[0].distance); + EXPECT_EQ(0, distances[1].distance); + EXPECT_EQ(100, distances[2].distance); +} diff --git a/opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp b/opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp index 177be77658..e82aa55279 100644 --- a/opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp +++ b/opencl/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -124,3 +124,24 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenGetMemRegionsIoctlValThenCorrect EXPECT_EQ(DRM_I915_QUERY_MEMORY_REGIONS, IoctlHelper::get(drm.get())->getMemRegionsIoctlVal()); } + +TEST(IoctlHelperTestsUpstream, givenUpstreamWhenGetEngineInfoIoctlValThenCorrectValueReturned) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + + EXPECT_EQ(DRM_I915_QUERY_ENGINE_INFO, IoctlHelper::get(drm.get())->getEngineInfoIoctlVal()); +} + +TEST(IoctlHelperTestsUpstream, givenUpstreamWhenQueryDistancesThenReturnEinval) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + std::vector distanceInfos; + std::vector queries(4); + auto ret = IoctlHelper::get(drm.get())->queryDistances(drm.get(), queries, distanceInfos); + EXPECT_EQ(0u, ret); + const bool queryUnsupported = std::all_of(queries.begin(), queries.end(), + [](const drm_i915_query_item &item) { return item.length == -EINVAL; }); + EXPECT_TRUE(queryUnsupported); +} diff --git a/opencl/test/unit_test/os_interface/linux/prelim_helper_func.cpp b/opencl/test/unit_test/os_interface/linux/prelim_helper_func.cpp index a58eeaed2f..5ee61d9b9f 100644 --- a/opencl/test/unit_test/os_interface/linux/prelim_helper_func.cpp +++ b/opencl/test/unit_test/os_interface/linux/prelim_helper_func.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -45,6 +45,18 @@ int handlePrelimRequests(unsigned long request, void *arg, int ioctlRetVal) { } else if (request == PRELIM_DRM_IOCTL_I915_GEM_CLOS_RESERVE) { auto closReserveArg = static_cast(arg); closReserveArg->clos_index = 1u; + } else if (request == DRM_IOCTL_I915_QUERY) { + auto query = static_cast(arg); + if (query->items_ptr == 0) { + return EINVAL; + } + for (auto i = 0u; i < query->num_items; i++) { + auto queryItemPtr = reinterpret_cast(query->items_ptr) + i; + if (queryItemPtr->query_id == PRELIM_DRM_I915_QUERY_DISTANCE_INFO) { + auto distance = reinterpret_cast(queryItemPtr->data_ptr); + distance->distance = (distance->engine.engine_instance == distance->region.memory_instance) ? 0 : 100; + } + } } return ioctlRetVal; } @@ -64,3 +76,18 @@ std::vector getRegionInfo(const std::vector &inputRegions } return data; } + +std::vector getEngineInfo(const std::vector &inputEngines) { + auto inputSize = static_cast(inputEngines.size()); + int length = sizeof(prelim_drm_i915_query_engine_info) + inputSize * sizeof(prelim_drm_i915_engine_info); + auto data = std::vector(length); + auto memoryRegions = reinterpret_cast(data.data()); + memoryRegions->num_engines = inputSize; + + for (uint32_t i = 0; i < inputSize; i++) { + memoryRegions->engines[i].engine.engine_class = inputEngines[i].engine.engineClass; + memoryRegions->engines[i].engine.engine_instance = inputEngines[i].engine.engineInstance; + memoryRegions->engines[i].capabilities = inputEngines[i].capabilities; + } + return data; +} diff --git a/shared/source/os_interface/linux/drm_query.cpp b/shared/source/os_interface/linux/drm_query.cpp index 1647d65aba..fceb37e8a7 100644 --- a/shared/source/os_interface/linux/drm_query.cpp +++ b/shared/source/os_interface/linux/drm_query.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2021 Intel Corporation + * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -33,12 +33,13 @@ std::string getIoctlParamStringRemaining(int param) { } // namespace IoctlToStringHelper bool Drm::queryEngineInfo(bool isSysmanEnabled) { - auto dataQuery = this->query(DRM_I915_QUERY_ENGINE_INFO, DrmQueryItemFlags::empty); + auto ioctlHelper = IoctlHelper::get(this); + auto dataQuery = this->query(ioctlHelper->getEngineInfoIoctlVal(), DrmQueryItemFlags::empty); if (dataQuery.empty()) { return false; } - auto data = reinterpret_cast(dataQuery.data()); - this->engineInfo.reset(new EngineInfoImpl(data->engines, data->num_engines)); + auto engines = ioctlHelper->translateToEngineCaps(dataQuery); + this->engineInfo.reset(new EngineInfoImpl(engines)); return true; } diff --git a/shared/source/os_interface/linux/engine_info_impl.h b/shared/source/os_interface/linux/engine_info_impl.h index cdac137a3c..93fde4af22 100644 --- a/shared/source/os_interface/linux/engine_info_impl.h +++ b/shared/source/os_interface/linux/engine_info_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -10,6 +10,7 @@ #include "shared/source/helpers/debug_helpers.h" #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/source/os_interface/linux/engine_info.h" +#include "shared/source/os_interface/linux/ioctl_helper.h" #include "drm/i915_drm.h" @@ -22,10 +23,10 @@ namespace NEO { struct EngineInfoImpl : public EngineInfo { ~EngineInfoImpl() override = default; - EngineInfoImpl(const drm_i915_engine_info *engineInfo, size_t count) : engines(engineInfo, engineInfo + count) { + EngineInfoImpl(const std::vector &engineInfos) : engines(engineInfos) { } - std::vector engines; + std::vector engines; }; } // namespace NEO diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index f867baf4aa..6786fcd4de 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -13,6 +13,7 @@ #include #include +struct drm_i915_query_item; namespace NEO { class Drm; class IoctlHelper; @@ -36,6 +37,11 @@ struct MemoryRegion { uint64_t unallocatedSize; }; +struct EngineCapabilities { + EngineClassInstance engine; + uint64_t capabilities; +}; + struct DistanceInfo { MemoryClassInstance region; EngineClassInstance engine; @@ -61,6 +67,9 @@ class IoctlHelper { virtual bool setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) = 0; virtual uint32_t getDirectSubmissionFlag() = 0; virtual int32_t getMemRegionsIoctlVal() = 0; + virtual int32_t getEngineInfoIoctlVal() = 0; + virtual std::vector translateToEngineCaps(const std::vector &data) = 0; + virtual uint32_t queryDistances(Drm *drm, std::vector &queryItems, std::vector &distanceInfos) = 0; }; class IoctlHelperUpstream : public IoctlHelper { @@ -78,6 +87,9 @@ class IoctlHelperUpstream : public IoctlHelper { bool setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) override; uint32_t getDirectSubmissionFlag() override; int32_t getMemRegionsIoctlVal() override; + int32_t getEngineInfoIoctlVal() override; + std::vector translateToEngineCaps(const std::vector &data) override; + uint32_t queryDistances(Drm *drm, std::vector &queryItems, std::vector &distanceInfos) override; }; template @@ -106,6 +118,9 @@ class IoctlHelperPrelim20 : public IoctlHelper { bool setVmBoAdvise(Drm *drm, int32_t handle, uint32_t attribute, void *region) override; uint32_t getDirectSubmissionFlag() override; int32_t getMemRegionsIoctlVal() override; + int32_t getEngineInfoIoctlVal() override; + std::vector translateToEngineCaps(const std::vector &data) override; + uint32_t queryDistances(Drm *drm, std::vector &queryItems, std::vector &distanceInfos) override; }; } // namespace NEO diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 3570ebb69f..44405cc51f 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -12,6 +12,7 @@ #include "third_party/uapi/prelim/drm/i915_drm.h" +#include #include #include #include @@ -185,4 +186,52 @@ int32_t IoctlHelperPrelim20::getMemRegionsIoctlVal() { return PRELIM_DRM_I915_QUERY_MEMORY_REGIONS; } +int32_t IoctlHelperPrelim20::getEngineInfoIoctlVal() { + return PRELIM_DRM_I915_QUERY_ENGINE_INFO; +} + +std::vector IoctlHelperPrelim20::translateToEngineCaps(const std::vector &data) { + auto engineInfo = reinterpret_cast(data.data()); + std::vector engines; + for (uint32_t i = 0; i < engineInfo->num_engines; i++) { + EngineCapabilities engine{}; + engine.capabilities = engineInfo->engines[i].capabilities; + engine.engine.engineClass = engineInfo->engines[i].engine.engine_class; + engine.engine.engineInstance = engineInfo->engines[i].engine.engine_instance; + engines.push_back(engine); + } + return engines; +} + +prelim_drm_i915_query_distance_info translateToi915(const DistanceInfo &distanceInfo) { + prelim_drm_i915_query_distance_info dist{}; + dist.engine.engine_class = distanceInfo.engine.engineClass; + dist.engine.engine_instance = distanceInfo.engine.engineInstance; + + dist.region.memory_class = distanceInfo.region.memoryClass; + dist.region.memory_instance = distanceInfo.region.memoryInstance; + return dist; +} + +uint32_t IoctlHelperPrelim20::queryDistances(Drm *drm, std::vector &queryItems, std::vector &distanceInfos) { + std::vector i915Distances(distanceInfos.size()); + std::transform(distanceInfos.begin(), distanceInfos.end(), i915Distances.begin(), translateToi915); + + for (auto i = 0u; i < i915Distances.size(); i++) { + queryItems[i].query_id = PRELIM_DRM_I915_QUERY_DISTANCE_INFO; + queryItems[i].length = sizeof(prelim_drm_i915_query_distance_info); + queryItems[i].flags = 0u; + queryItems[i].data_ptr = reinterpret_cast<__u64>(&i915Distances[i]); + } + + drm_i915_query query{}; + query.items_ptr = reinterpret_cast<__u64>(queryItems.data()); + query.num_items = static_cast(queryItems.size()); + auto ret = IoctlHelper::ioctl(drm, DRM_IOCTL_I915_QUERY, &query); + for (auto i = 0u; i < i915Distances.size(); i++) { + distanceInfos[i].distance = i915Distances[i].distance; + } + return ret; +} + } // namespace NEO diff --git a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp index fd79910149..b9d327d39a 100644 --- a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -101,4 +101,28 @@ int32_t IoctlHelperUpstream::getMemRegionsIoctlVal() { return DRM_I915_QUERY_MEMORY_REGIONS; } +int32_t IoctlHelperUpstream::getEngineInfoIoctlVal() { + return DRM_I915_QUERY_ENGINE_INFO; +} + +std::vector IoctlHelperUpstream::translateToEngineCaps(const std::vector &data) { + auto engineInfo = reinterpret_cast(data.data()); + std::vector engines; + for (uint32_t i = 0; i < engineInfo->num_engines; i++) { + EngineCapabilities engine{}; + engine.capabilities = engineInfo->engines[i].capabilities; + engine.engine.engineClass = engineInfo->engines[i].engine.engine_class; + engine.engine.engineInstance = engineInfo->engines[i].engine.engine_instance; + engines.push_back(engine); + } + return engines; +} + +uint32_t IoctlHelperUpstream::queryDistances(Drm *drm, std::vector &queryItems, std::vector &distanceInfos) { + for (auto &query : queryItems) { + query.length = -EINVAL; + } + return 0; +} + } // namespace NEO