diff --git a/opencl/source/dll/linux/options_linux.cpp b/opencl/source/dll/linux/options_linux.cpp index 4964d3a05d..df4646f187 100644 --- a/opencl/source/dll/linux/options_linux.cpp +++ b/opencl/source/dll/linux/options_linux.cpp @@ -17,6 +17,7 @@ const char *libvaDllName = "libva.so.2"; const char *sysFsPciPathPrefix = "/sys/bus/pci/devices/0000:"; const char *pciDevicesDirectory = "/dev/dri/by-path"; +const char *sysFsProcPathPrefix = "/proc"; const char *tbxLibName = "libtbxAccess.so"; // Metrics Library name diff --git a/opencl/test/unit_test/os_interface/linux/drm_os_memory_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_os_memory_tests.cpp index 905c8f4499..eb737fa792 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_os_memory_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_os_memory_tests.cpp @@ -6,6 +6,7 @@ */ #include "shared/source/helpers/constants.h" +#include "shared/source/helpers/file_io.h" #include "shared/source/os_interface/linux/os_memory_linux.h" #include "gmock/gmock.h" @@ -79,4 +80,25 @@ TEST(OSMemoryLinux, givenOSMemoryLinuxWhenReserveCpuAddressRangeIsCalledAndBaseA mockOSMemoryLinux->releaseCpuAddressRange(reservedCpuRange); } +TEST(OSMemoryLinux, GivenProcSelfMapsFileExistsWhenGetMemoryMapsIsQueriedThenValidValueIsReturned) { + auto mockOSMemoryLinux = MockOSMemoryLinux::create(); + + std::string mapsFile = "test_files/linux/proc/self/maps"; + EXPECT_TRUE(fileExists(mapsFile)); + + OSMemory::MemoryMaps memoryMaps; + mockOSMemoryLinux->getMemoryMaps(memoryMaps); + + static const OSMemory::MappedRegion referenceMaps[] = { + {0x564fcd1fa000, 0x564fcd202000}, {0x564fcd401000, 0x564fcd402000}, {0x564fcd402000, 0x564fcd403000}, {0x564fcdf40000, 0x564fcdf61000}, {0x7fded3d79000, 0x7fded4879000}, {0x7fded4879000, 0x7fded4a60000}, {0x7fded4a60000, 0x7fded4c60000}, {0x7fded4c60000, 0x7fded4c64000}, {0x7fded4c64000, 0x7fded4c66000}, {0x7fded4c66000, 0x7fded4c6a000}, {0x7fded4c6a000, 0x7fded4c91000}, {0x7fded4e54000, 0x7fded4e78000}, {0x7fded4e91000, 0x7fded4e92000}, {0x7fded4e92000, 0x7fded4e93000}, {0x7fded4e93000, 0x7fded4e94000}, {0x7ffd6dfa2000, 0x7ffd6dfc3000}, {0x7ffd6dfe8000, 0x7ffd6dfeb000}, {0x7ffd6dfeb000, 0x7ffd6dfec000}, {0xffffffffff600000, 0xffffffffff601000}}; + + EXPECT_FALSE(memoryMaps.empty()); + EXPECT_EQ(memoryMaps.size(), GTEST_ARRAY_SIZE_(referenceMaps)); + + for (size_t i = 0; i < memoryMaps.size(); ++i) { + EXPECT_EQ(memoryMaps[i].start, referenceMaps[i].start); + EXPECT_EQ(memoryMaps[i].end, referenceMaps[i].end); + } +} + }; // namespace NEO diff --git a/opencl/test/unit_test/os_interface/linux/options.cpp b/opencl/test/unit_test/os_interface/linux/options.cpp index 5168dc5286..5a1e5a9615 100644 --- a/opencl/test/unit_test/os_interface/linux/options.cpp +++ b/opencl/test/unit_test/os_interface/linux/options.cpp @@ -27,6 +27,7 @@ const char *metricsLibraryDllName = ""; #endif const char *sysFsPciPathPrefix = "./test_files/linux/devices/"; const char *pciDevicesDirectory = "./test_files/linux/by-path"; +const char *sysFsProcPathPrefix = "./test_files/linux/proc/"; } // namespace Os NEO::OsLibrary *setAdapterInfo(const PLATFORM *platform, const GT_SYSTEM_INFO *gtSystemInfo, uint64_t gpuAddressSpace) { diff --git a/opencl/test/unit_test/test_files/linux/proc/self/maps b/opencl/test/unit_test/test_files/linux/proc/self/maps new file mode 100644 index 0000000000..a302963d5f --- /dev/null +++ b/opencl/test/unit_test/test_files/linux/proc/self/maps @@ -0,0 +1,19 @@ +564fcd1fa000-564fcd202000 r-xp 00000000 08:03 3670041 /bin/cat +564fcd401000-564fcd402000 r--p 00007000 08:03 3670041 /bin/cat +564fcd402000-564fcd403000 rw-p 00008000 08:03 3670041 /bin/cat +564fcdf40000-564fcdf61000 rw-p 00000000 00:00 0 [heap] +7fded3d79000-7fded4879000 r--p 00000000 08:03 3938831 /usr/lib/locale/locale-archive +7fded4879000-7fded4a60000 r-xp 00000000 08:03 4199137 /lib/x86_64-linux-gnu/libc-2.27.so +7fded4a60000-7fded4c60000 ---p 001e7000 08:03 4199137 /lib/x86_64-linux-gnu/libc-2.27.so +7fded4c60000-7fded4c64000 r--p 001e7000 08:03 4199137 /lib/x86_64-linux-gnu/libc-2.27.so +7fded4c64000-7fded4c66000 rw-p 001eb000 08:03 4199137 /lib/x86_64-linux-gnu/libc-2.27.so +7fded4c66000-7fded4c6a000 rw-p 00000000 00:00 0 +7fded4c6a000-7fded4c91000 r-xp 00000000 08:03 4199109 /lib/x86_64-linux-gnu/ld-2.27.so +7fded4e54000-7fded4e78000 rw-p 00000000 00:00 0 +7fded4e91000-7fded4e92000 r--p 00027000 08:03 4199109 /lib/x86_64-linux-gnu/ld-2.27.so +7fded4e92000-7fded4e93000 rw-p 00028000 08:03 4199109 /lib/x86_64-linux-gnu/ld-2.27.so +7fded4e93000-7fded4e94000 rw-p 00000000 00:00 0 +7ffd6dfa2000-7ffd6dfc3000 rw-p 00000000 00:00 0 [stack] +7ffd6dfe8000-7ffd6dfeb000 r--p 00000000 00:00 0 [vvar] +7ffd6dfeb000-7ffd6dfec000 r-xp 00000000 00:00 0 [vdso] +ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall] diff --git a/shared/source/os_interface/linux/os_inc.h b/shared/source/os_interface/linux/os_inc.h index b213052107..80b5d15805 100644 --- a/shared/source/os_interface/linux/os_inc.h +++ b/shared/source/os_interface/linux/os_inc.h @@ -13,4 +13,6 @@ namespace Os { // Pci Path extern const char *sysFsPciPathPrefix; extern const char *pciDevicesDirectory; +// Proc Path +extern const char *sysFsProcPathPrefix; } // namespace Os diff --git a/shared/source/os_interface/linux/os_memory_linux.cpp b/shared/source/os_interface/linux/os_memory_linux.cpp index 906c6d0de2..c04f3a92ed 100644 --- a/shared/source/os_interface/linux/os_memory_linux.cpp +++ b/shared/source/os_interface/linux/os_memory_linux.cpp @@ -7,6 +7,10 @@ #include "shared/source/os_interface/linux/os_memory_linux.h" +#include "shared/source/os_interface/linux/os_inc.h" + +#include + namespace NEO { std::unique_ptr OSMemory::create() { @@ -29,4 +33,29 @@ int OSMemoryLinux::munmapWrapper(void *addr, size_t size) { return munmap(addr, size); } +void OSMemoryLinux::getMemoryMaps(MemoryMaps &memoryMaps) { + + /* + ============ =============================================================== + + The /proc/PID/maps file contains the currently mapped memory regions and + their access permissions. + + The format is:: + + address perms offset dev inode pathname + + 08048000-08049000 r-xp 00000000 03:00 8312 /opt/test + + */ + + std::ifstream ifs(std::string(Os::sysFsProcPathPrefix) + "/self/maps"); + std::string line; + while (std::getline(ifs, line)) { + uint64_t start = 0, end = 0; + sscanf(line.c_str(), "%lx-%lx", &start, &end); + memoryMaps.push_back({start, end}); + } +} + } // namespace NEO diff --git a/shared/source/os_interface/linux/os_memory_linux.h b/shared/source/os_interface/linux/os_memory_linux.h index 0c1bb44086..788e64b179 100644 --- a/shared/source/os_interface/linux/os_memory_linux.h +++ b/shared/source/os_interface/linux/os_memory_linux.h @@ -16,6 +16,8 @@ class OSMemoryLinux : public OSMemory { public: OSMemoryLinux() = default; + void getMemoryMaps(MemoryMaps &memoryMaps) override; + protected: void *osReserveCpuAddressRange(void *baseAddress, size_t sizeToReserve) override; void osReleaseCpuAddressRange(void *reservedCpuAddressRange, size_t reservedSize) override; diff --git a/shared/source/os_interface/os_memory.h b/shared/source/os_interface/os_memory.h index 914ce3e3d1..765785715d 100644 --- a/shared/source/os_interface/os_memory.h +++ b/shared/source/os_interface/os_memory.h @@ -8,6 +8,7 @@ #pragma once #include #include +#include namespace NEO { @@ -19,6 +20,12 @@ struct OSMemory { size_t actualReservedSize = 0; }; + struct MappedRegion { + uint64_t start = 0, end = 0; + }; + + using MemoryMaps = std::vector; + public: static std::unique_ptr create(); @@ -27,6 +34,7 @@ struct OSMemory { MOCKABLE_VIRTUAL ReservedCpuAddressRange reserveCpuAddressRange(size_t sizeToReserve, size_t alignment); MOCKABLE_VIRTUAL ReservedCpuAddressRange reserveCpuAddressRange(void *baseAddress, size_t sizeToReserve, size_t alignment); MOCKABLE_VIRTUAL void releaseCpuAddressRange(const ReservedCpuAddressRange &reservedCpuAddressRange); + virtual void getMemoryMaps(MemoryMaps &memoryMaps) = 0; protected: virtual void *osReserveCpuAddressRange(void *baseAddress, size_t sizeToReserve) = 0; diff --git a/shared/source/os_interface/windows/os_memory_win.h b/shared/source/os_interface/windows/os_memory_win.h index f62e5ef423..8ecba26d08 100644 --- a/shared/source/os_interface/windows/os_memory_win.h +++ b/shared/source/os_interface/windows/os_memory_win.h @@ -15,6 +15,8 @@ class OSMemoryWindows : public OSMemory { public: OSMemoryWindows() = default; + void getMemoryMaps(MemoryMaps &memoryMaps) override {} + protected: void *osReserveCpuAddressRange(void *baseAddress, size_t sizeToReserve) override; void osReleaseCpuAddressRange(void *reservedCpuAddressRange, size_t reservedSize) override;