diff --git a/opencl/test/unit_test/memory_manager/gfx_partition_tests.inl b/opencl/test/unit_test/memory_manager/gfx_partition_tests.inl index 34aa5e3a0f..10e0e7a52c 100644 --- a/opencl/test/unit_test/memory_manager/gfx_partition_tests.inl +++ b/opencl/test/unit_test/memory_manager/gfx_partition_tests.inl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2020 Intel Corporation + * Copyright (C) 2019-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -9,11 +9,52 @@ #include "shared/source/helpers/basic_math.h" #include "shared/source/helpers/ptr_math.h" #include "shared/source/os_interface/os_memory.h" +#include "shared/source/utilities/cpu_info.h" #include "opencl/test/unit_test/mocks/mock_gfx_partition.h" #include "gtest/gtest.h" +#include + +static std::string mockCpuFlags; +static void mockGetCpuFlagsFunc(std::string &cpuFlags) { cpuFlags = mockCpuFlags; } +static void (*getCpuFlagsFuncSave)(std::string &) = nullptr; + +// CpuInfo is a singleton object so we have to patch it in place +class CpuInfoOverrideVirtualAddressSizeAndFlags { + public: + class MockCpuInfo : public CpuInfo { + public: + using CpuInfo::cpuFlags; + using CpuInfo::virtualAddressSize; + } *mockCpuInfo = reinterpret_cast(const_cast(&CpuInfo::getInstance())); + + CpuInfoOverrideVirtualAddressSizeAndFlags(uint32_t newCpuVirtualAddressSize, const char *newCpuFlags = "") { + virtualAddressSizeSave = mockCpuInfo->getVirtualAddressSize(); + mockCpuInfo->virtualAddressSize = newCpuVirtualAddressSize; + + getCpuFlagsFuncSave = mockCpuInfo->getCpuFlagsFunc; + mockCpuInfo->getCpuFlagsFunc = mockGetCpuFlagsFunc; + resetCpuFlags(); + mockCpuFlags = newCpuFlags; + } + + ~CpuInfoOverrideVirtualAddressSizeAndFlags() { + mockCpuInfo->virtualAddressSize = virtualAddressSizeSave; + resetCpuFlags(); + mockCpuInfo->getCpuFlagsFunc = getCpuFlagsFuncSave; + getCpuFlagsFuncSave = nullptr; + } + + void resetCpuFlags() { + mockCpuFlags = ""; + mockCpuInfo->getCpuFlagsFunc(mockCpuInfo->cpuFlags); + } + + uint32_t virtualAddressSizeSave = 0; +}; + using namespace NEO; constexpr size_t reservedCpuAddressRangeSize = is64bit ? (6 * 4 * GB) : 0; @@ -132,7 +173,7 @@ TEST(GfxPartitionTest, GivenLimitedRangeWhenTestingGfxPartitionThenAllExpectatio testGfxPartition(gfxPartition, gfxBase, gfxTop, svmTop); } -TEST(GfxPartitionTest, GivenUnsupportedRangeThenGfxPartitionIsNotInitialized) { +TEST(GfxPartitionTest, GivenUnsupportedGpuRangeThenGfxPartitionIsNotInitialized) { if (is32bit) { GTEST_SKIP(); } @@ -141,6 +182,16 @@ TEST(GfxPartitionTest, GivenUnsupportedRangeThenGfxPartitionIsNotInitialized) { EXPECT_FALSE(gfxPartition.init(maxNBitValue(48 + 1), reservedCpuAddressRangeSize, 0, 1)); } +TEST(GfxPartitionTest, GivenUnsupportedCpuRangeThenGfxPartitionIsNotInitialize) { + if (is32bit) { + GTEST_SKIP(); + } + + CpuInfoOverrideVirtualAddressSizeAndFlags overrideCpuInfo(48 + 1); + MockGfxPartition gfxPartition; + EXPECT_FALSE(gfxPartition.init(maxNBitValue(48), reservedCpuAddressRangeSize, 0, 1)); +} + TEST(GfxPartitionTest, GivenFullRange48BitSvmHeap64KbSplitWhenTestingGfxPartitionThenAllExpectationsAreMet) { uint32_t rootDeviceIndex = 3; size_t numRootDevices = 5; @@ -330,4 +381,4 @@ TEST(GfxPartitionTest, givenInternalHeapWhenAllocatingSmallOrBigChunkThenAddress EXPECT_EQ(gfxPartition.getHeapBase(heaps[i]) + GfxPartition::internalFrontWindowPoolSize, address); gfxPartition.heapFree(heaps[i], address, sizeToAlloc); } -} \ No newline at end of file +} diff --git a/opencl/test/unit_test/test_files/linux/proc/cpuinfo b/opencl/test/unit_test/test_files/linux/proc/cpuinfo deleted file mode 100644 index abbe64bf12..0000000000 --- a/opencl/test/unit_test/test_files/linux/proc/cpuinfo +++ /dev/null @@ -1,108 +0,0 @@ -processor : 0 -vendor_id : GenuineIntel -cpu family : 6 -model : 94 -model name : Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz -stepping : 3 -microcode : 0xdc -cpu MHz : 900.565 -cache size : 6144 KB -physical id : 0 -siblings : 4 -core id : 0 -cpu cores : 4 -apicid : 0 -initial apicid : 0 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit srbds -bogomips : 6399.96 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 1 -vendor_id : GenuineIntel -cpu family : 6 -model : 94 -model name : Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz -stepping : 3 -microcode : 0xdc -cpu MHz : 900.224 -cache size : 6144 KB -physical id : 0 -siblings : 4 -core id : 1 -cpu cores : 4 -apicid : 2 -initial apicid : 2 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit srbds -bogomips : 6399.96 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 2 -vendor_id : GenuineIntel -cpu family : 6 -model : 94 -model name : Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz -stepping : 3 -microcode : 0xdc -cpu MHz : 900.065 -cache size : 6144 KB -physical id : 0 -siblings : 4 -core id : 2 -cpu cores : 4 -apicid : 4 -initial apicid : 4 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit srbds -bogomips : 6399.96 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 3 -vendor_id : GenuineIntel -cpu family : 6 -model : 94 -model name : Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz -stepping : 3 -microcode : 0xdc -cpu MHz : 900.670 -cache size : 6144 KB -physical id : 0 -siblings : 4 -core id : 3 -cpu cores : 4 -apicid : 6 -initial apicid : 6 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit srbds -bogomips : 6399.96 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - diff --git a/shared/source/memory_manager/gfx_partition.cpp b/shared/source/memory_manager/gfx_partition.cpp index 9b959a5e45..5f9a7d231b 100644 --- a/shared/source/memory_manager/gfx_partition.cpp +++ b/shared/source/memory_manager/gfx_partition.cpp @@ -10,6 +10,7 @@ #include "shared/source/helpers/aligned_memory.h" #include "shared/source/helpers/heap_assigner.h" #include "shared/source/memory_manager/memory_manager.h" +#include "shared/source/utilities/cpu_info.h" namespace NEO { @@ -138,7 +139,8 @@ bool GfxPartition::init(uint64_t gpuAddressSpace, size_t cpuAddressRangeSizeToRe gfxBase = maxNBitValue(32) + 1; heapInit(HeapIndex::HEAP_SVM, 0ull, gfxBase); } else { - if (gpuAddressSpace == maxNBitValue(48)) { + auto cpuVirtualAddressSize = CpuInfo::getInstance().getVirtualAddressSize(); + if (cpuVirtualAddressSize == 48 && gpuAddressSpace == maxNBitValue(48)) { gfxBase = maxNBitValue(48 - 1) + 1; heapInit(HeapIndex::HEAP_SVM, 0ull, gfxBase); } else if (gpuAddressSpace == maxNBitValue(47)) { @@ -161,7 +163,7 @@ bool GfxPartition::init(uint64_t gpuAddressSpace, size_t cpuAddressRangeSizeToRe gfxBase = 0ull; heapInit(HeapIndex::HEAP_SVM, 0ull, 0ull); } else { - if (!initAdditionalRange(gpuAddressSpace, gfxBase, gfxTop, rootDeviceIndex, numRootDevices)) { + if (!initAdditionalRange(cpuVirtualAddressSize, gpuAddressSpace, gfxBase, gfxTop, rootDeviceIndex, numRootDevices)) { return false; } } diff --git a/shared/source/memory_manager/gfx_partition.h b/shared/source/memory_manager/gfx_partition.h index 51a63754ad..d6c090edeb 100644 --- a/shared/source/memory_manager/gfx_partition.h +++ b/shared/source/memory_manager/gfx_partition.h @@ -107,7 +107,7 @@ class GfxPartition { static const std::array heapNonSvmNames; protected: - bool initAdditionalRange(uint64_t gpuAddressSpace, uint64_t &gfxBase, uint64_t &gfxTop, uint32_t rootDeviceIndex, size_t numRootDevices); + bool initAdditionalRange(uint32_t cpuAddressWidth, uint64_t gpuAddressSpace, uint64_t &gfxBase, uint64_t &gfxTop, uint32_t rootDeviceIndex, size_t numRootDevices); class Heap { public: diff --git a/shared/source/memory_manager/gfx_partition_init_additional_range.cpp b/shared/source/memory_manager/gfx_partition_init_additional_range.cpp index cfef320773..38c127d4e8 100644 --- a/shared/source/memory_manager/gfx_partition_init_additional_range.cpp +++ b/shared/source/memory_manager/gfx_partition_init_additional_range.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2020 Intel Corporation + * Copyright (C) 2019-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -9,7 +9,7 @@ namespace NEO { -bool GfxPartition::initAdditionalRange(uint64_t gpuAddressSpace, uint64_t &gfxBase, uint64_t &gfxTop, uint32_t rootDeviceIndex, size_t numRootDevices) { +bool GfxPartition::initAdditionalRange(uint32_t cpuVirtualAddressSize, uint64_t gpuAddressSpace, uint64_t &gfxBase, uint64_t &gfxTop, uint32_t rootDeviceIndex, size_t numRootDevices) { return false; } diff --git a/shared/source/utilities/cpu_info.h b/shared/source/utilities/cpu_info.h index bfcc44b263..d4157929c4 100644 --- a/shared/source/utilities/cpu_info.h +++ b/shared/source/utilities/cpu_info.h @@ -9,6 +9,7 @@ #include "shared/source/helpers/constants.h" #include +#include #ifndef BIT #define BIT(x) (1ull << (x)) @@ -213,18 +214,26 @@ struct CpuInfo { return virtualAddressSize; } + bool isCpuFlagPresent(const char *cpuFlag) const { + if (cpuFlags.empty()) { + getCpuFlagsFunc(cpuFlags); + } + + return cpuFlags.find(cpuFlag) != std::string::npos; + } + static const CpuInfo &getInstance() { return instance; } - bool isCpuFlagPresent(const char *cpuFlag); - static void (*cpuidexFunc)(int *, int, int); static void (*cpuidFunc)(int[4], int); + static void (*getCpuFlagsFunc)(std::string &); protected: mutable uint64_t features; mutable uint32_t virtualAddressSize = is32bit ? 32 : 48; + mutable std::string cpuFlags; static const CpuInfo instance; }; diff --git a/shared/source/utilities/linux/cpu_info.cpp b/shared/source/utilities/linux/cpu_info.cpp index 566bb31e38..fc7c496476 100644 --- a/shared/source/utilities/linux/cpu_info.cpp +++ b/shared/source/utilities/linux/cpu_info.cpp @@ -11,8 +11,6 @@ #include #include -#include -#include namespace NEO { @@ -24,8 +22,20 @@ void cpuidex_linux_wrapper(int *cpuInfo, int functionId, int subfunctionId) { __cpuid_count(functionId, subfunctionId, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]); } +void get_cpu_flags_linux(std::string &cpuFlags) { + std::ifstream cpuinfo(std::string(Os::sysFsProcPathPrefix) + "/cpuinfo"); + std::string line; + while (std::getline(cpuinfo, line)) { + if (line.substr(0, 5) == "flags") { + cpuFlags = line; + break; + } + } +} + void (*CpuInfo::cpuidexFunc)(int *, int, int) = cpuidex_linux_wrapper; void (*CpuInfo::cpuidFunc)(int[4], int) = cpuid_linux_wrapper; +void (*CpuInfo::getCpuFlagsFunc)(std::string &) = get_cpu_flags_linux; const CpuInfo CpuInfo::instance; @@ -42,22 +52,4 @@ void CpuInfo::cpuidex( cpuidexFunc(reinterpret_cast(cpuInfo), functionId, subfunctionId); } -bool CpuInfo::isCpuFlagPresent(const char *cpuFlag) { - std::ifstream ifs(std::string(Os::sysFsProcPathPrefix) + "/cpuinfo"); - std::string line; - while (std::getline(ifs, line)) { - if (line.substr(0, 5) == "flags") { - std::stringstream ss(line); - std::string flag; - while (ss >> flag) { - if (flag == cpuFlag) { - return true; - } - } - } - } - - return false; -} - } // namespace NEO diff --git a/shared/source/utilities/windows/cpu_info.cpp b/shared/source/utilities/windows/cpu_info.cpp index 168d2884b9..094d1c2206 100644 --- a/shared/source/utilities/windows/cpu_info.cpp +++ b/shared/source/utilities/windows/cpu_info.cpp @@ -19,8 +19,11 @@ void cpuidex_windows_wrapper(int *cpuInfo, int functionId, int subfunctionId) { __cpuidex(cpuInfo, functionId, subfunctionId); } +void get_cpu_flags_windows(std::string &cpuFlags) {} + void (*CpuInfo::cpuidexFunc)(int *, int, int) = cpuidex_windows_wrapper; void (*CpuInfo::cpuidFunc)(int[4], int) = cpuid_windows_wrapper; +void (*CpuInfo::getCpuFlagsFunc)(std::string &) = get_cpu_flags_windows; const CpuInfo CpuInfo::instance; @@ -37,8 +40,4 @@ void CpuInfo::cpuidex( cpuidexFunc(reinterpret_cast(cpuInfo), functionId, subfunctionId); } -bool CpuInfo::isCpuFlagPresent(const char *cpuFlag) { - return false; -} - } // namespace NEO diff --git a/shared/test/unit_test/utilities/linux/cpuinfo_tests_linux.cpp b/shared/test/unit_test/utilities/linux/cpuinfo_tests_linux.cpp index 7bedd47582..9fd1e6be98 100644 --- a/shared/test/unit_test/utilities/linux/cpuinfo_tests_linux.cpp +++ b/shared/test/unit_test/utilities/linux/cpuinfo_tests_linux.cpp @@ -10,14 +10,36 @@ #include "gtest/gtest.h" +#include +#include + using namespace NEO; TEST(CpuInfo, givenProcCpuinfoFileExistsWhenIsCpuFlagPresentIsCalledThenValidValueIsReturned) { std::string cpuinfoFile = "test_files/linux/proc/cpuinfo"; + EXPECT_FALSE(fileExists(cpuinfoFile)); + + { + std::ofstream cpuinfo(cpuinfoFile); + cpuinfo << "processor\t\t: 0\nflags\t\t: flag1 flag2 flag3\n"; + } + EXPECT_TRUE(fileExists(cpuinfoFile)); CpuInfo testCpuInfo; - EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("fpu")); - EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("vme")); + EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("flag1")); + EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("flag2")); + EXPECT_FALSE(testCpuInfo.isCpuFlagPresent("nonExistingCpuFlag")); + + std::remove(cpuinfoFile.c_str()); +} + +TEST(CpuInfo, givenProcCpuinfoFileIsNotExistsWhenIsCpuFlagPresentIsCalledThenValidValueIsReturned) { + std::string cpuinfoFile = "test_files/linux/proc/cpuinfo"; + EXPECT_FALSE(fileExists(cpuinfoFile)); + + CpuInfo testCpuInfo; + EXPECT_FALSE(testCpuInfo.isCpuFlagPresent("flag1")); + EXPECT_FALSE(testCpuInfo.isCpuFlagPresent("flag2")); EXPECT_FALSE(testCpuInfo.isCpuFlagPresent("nonExistingCpuFlag")); }