From 6975f7bb8d76ea3f6dc912f4efde4b22f09310f7 Mon Sep 17 00:00:00 2001 From: Aleksandra Nizio Date: Mon, 7 Jul 2025 08:43:54 +0000 Subject: [PATCH] fix: Disable compiler cache if any IGC_ env is set Related-To: NEO-12721 Signed-off-by: Aleksandra Nizio --- .../default_cache_config.cpp | 9 +++- .../linux/os_compiler_cache_helper.cpp | 14 ++++- .../os_compiler_cache_helper.h | 3 +- .../windows/os_compiler_cache_helper.cpp | 23 +++++++- shared/source/os_interface/linux/sys_calls.h | 1 + .../os_interface/linux/sys_calls_linux.cpp | 4 +- .../source/os_interface/windows/sys_calls.cpp | 8 ++- .../source/os_interface/windows/sys_calls.h | 7 ++- .../linux/sys_calls_linux_ult.cpp | 17 ++++++ .../os_interface/linux/sys_calls_linux_ult.h | 8 +++ .../common/os_interface/windows/sys_calls.cpp | 10 +++- .../linux/default_cl_cache_config_tests.cpp | 54 +++++++++++++++++++ .../windows/default_cl_cache_config_tests.cpp | 29 ++++++++++ 13 files changed, 176 insertions(+), 11 deletions(-) diff --git a/shared/source/compiler_interface/default_cache_config.cpp b/shared/source/compiler_interface/default_cache_config.cpp index 1543a293fa..74587769ff 100644 --- a/shared/source/compiler_interface/default_cache_config.cpp +++ b/shared/source/compiler_interface/default_cache_config.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -31,6 +31,12 @@ CompilerCacheConfig getDefaultCompilerCacheConfig() { if (envReader.getSetting(neoCachePersistent.c_str(), ApiSpecificConfig::compilerCacheDefaultEnabled()) != 0) { ret.enabled = true; + + if (isAnyIgcEnvVarSet()) { + ret.enabled = false; + return ret; + } + std::string emptyString = ""; ret.cacheDir = envReader.getSetting(neoCacheDir.c_str(), emptyString); @@ -62,5 +68,4 @@ CompilerCacheConfig getDefaultCompilerCacheConfig() { return ret; } - } // namespace NEO diff --git a/shared/source/compiler_interface/linux/os_compiler_cache_helper.cpp b/shared/source/compiler_interface/linux/os_compiler_cache_helper.cpp index 17c814184d..71ccfe61c0 100644 --- a/shared/source/compiler_interface/linux/os_compiler_cache_helper.cpp +++ b/shared/source/compiler_interface/linux/os_compiler_cache_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -14,8 +14,10 @@ #include "os_inc.h" +#include #include #include +#include namespace NEO { bool createCompilerCachePath(std::string &cacheDir) { @@ -81,4 +83,14 @@ size_t getFileSize(const std::string &path) { } return 0u; } + +bool isAnyIgcEnvVarSet() { + char **envp = NEO::SysCalls::getEnviron(); + for (int i = 0; envp && envp[i] != nullptr; i++) { + if (strncmp(envp[i], "IGC_", 4) == 0) { + return true; + } + } + return false; +} } // namespace NEO \ No newline at end of file diff --git a/shared/source/compiler_interface/os_compiler_cache_helper.h b/shared/source/compiler_interface/os_compiler_cache_helper.h index 5f76bf69aa..7c9f52d6dc 100644 --- a/shared/source/compiler_interface/os_compiler_cache_helper.h +++ b/shared/source/compiler_interface/os_compiler_cache_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -13,4 +13,5 @@ class EnvironmentVariableReader; bool checkDefaultCacheDirSettings(std::string &cacheDir, NEO::EnvironmentVariableReader &reader); time_t getFileModificationTime(const std::string &path); size_t getFileSize(const std::string &path); +bool isAnyIgcEnvVarSet(); } // namespace NEO \ No newline at end of file diff --git a/shared/source/compiler_interface/windows/os_compiler_cache_helper.cpp b/shared/source/compiler_interface/windows/os_compiler_cache_helper.cpp index 3b3ba61d0c..6711052d98 100644 --- a/shared/source/compiler_interface/windows/os_compiler_cache_helper.cpp +++ b/shared/source/compiler_interface/windows/os_compiler_cache_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -13,6 +13,7 @@ #include #include +#include namespace NEO { std::string getKnownFolderPath(REFKNOWNFOLDERID rfid) { @@ -96,5 +97,25 @@ size_t getFileSize(const std::string &path) { SysCalls::findClose(hFind); return static_cast((ffd.nFileSizeHigh * (MAXDWORD + 1)) + ffd.nFileSizeLow); } +bool isAnyIgcEnvVarSet() { + LPWCH envStrings = SysCalls::getEnvironmentStringsW(); + if (envStrings == nullptr) { + return false; + } + + for (LPWCH var = envStrings; *var != L'\0';) { + if (wcsncmp(var, L"IGC_", 4) == 0) { + SysCalls::freeEnvironmentStringsW(envStrings); + return true; + } + while (*var != L'\0') { + ++var; + } + ++var; + } + + SysCalls::freeEnvironmentStringsW(envStrings); + return false; +} } // namespace NEO \ No newline at end of file diff --git a/shared/source/os_interface/linux/sys_calls.h b/shared/source/os_interface/linux/sys_calls.h index e78baece5c..c8ea7f3d8d 100644 --- a/shared/source/os_interface/linux/sys_calls.h +++ b/shared/source/os_interface/linux/sys_calls.h @@ -59,5 +59,6 @@ long sysconf(int name); int mkfifo(const char *pathname, mode_t mode); int pidfdopen(pid_t pid, unsigned int flags); int pidfdgetfd(int pidfd, int targetfd, unsigned int flags); +char **getEnviron(); } // namespace SysCalls } // namespace NEO diff --git a/shared/source/os_interface/linux/sys_calls_linux.cpp b/shared/source/os_interface/linux/sys_calls_linux.cpp index 6e063b3a62..184c147e0e 100644 --- a/shared/source/os_interface/linux/sys_calls_linux.cpp +++ b/shared/source/os_interface/linux/sys_calls_linux.cpp @@ -34,7 +34,9 @@ namespace NEO { namespace SysCalls { - +char **getEnviron() { + return environ; +} void exit(int code) { std::exit(code); } diff --git a/shared/source/os_interface/windows/sys_calls.cpp b/shared/source/os_interface/windows/sys_calls.cpp index 2145d282d9..aede89ec3b 100644 --- a/shared/source/os_interface/windows/sys_calls.cpp +++ b/shared/source/os_interface/windows/sys_calls.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -196,6 +196,12 @@ BOOL getFileVersionInfoW(LPCWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LP BOOL verQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lpBuffer, PUINT puLen) { return ::VerQueryValueW(pBlock, lpSubBlock, lpBuffer, puLen); } +LPWCH getEnvironmentStringsW() { + return ::GetEnvironmentStringsW(); +} +BOOL freeEnvironmentStringsW(LPWCH env) { + return ::FreeEnvironmentStringsW(env); +} } // namespace SysCalls } // namespace NEO diff --git a/shared/source/os_interface/windows/sys_calls.h b/shared/source/os_interface/windows/sys_calls.h index 44f82dc416..fd43392efd 100644 --- a/shared/source/os_interface/windows/sys_calls.h +++ b/shared/source/os_interface/windows/sys_calls.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -65,7 +65,10 @@ DWORD getFileVersionInfoSizeW(LPCWSTR lptstrFilename, LPDWORD lpdwHandle); BOOL getFileVersionInfoW(LPCWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData); BOOL verQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen); DWORD getLastError(); - +extern LPWCH mockEnvStringsW; +extern BOOL mockFreeEnvStringsWResult; +LPWCH getEnvironmentStringsW(); +BOOL freeEnvironmentStringsW(LPWCH); } // namespace SysCalls } // namespace NEO diff --git a/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp b/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp index 0be5ec1310..c757008d52 100644 --- a/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp +++ b/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp @@ -555,6 +555,23 @@ int pidfdgetfd(int pid, int targetfd, unsigned int flags) { } return 0; } +char **getEnviron() { + return NEO::ULT::getCurrentEnviron(); +} } // namespace SysCalls + +namespace ULT { + +static char **mockEnviron = nullptr; + +char **getCurrentEnviron() { + return mockEnviron ? mockEnviron : environ; +} + +void setMockEnviron(char **mock) { + mockEnviron = mock; +} + +} // namespace ULT } // namespace NEO diff --git a/shared/test/common/os_interface/linux/sys_calls_linux_ult.h b/shared/test/common/os_interface/linux/sys_calls_linux_ult.h index c314dff322..d15217e695 100644 --- a/shared/test/common/os_interface/linux/sys_calls_linux_ult.h +++ b/shared/test/common/os_interface/linux/sys_calls_linux_ult.h @@ -16,6 +16,9 @@ #include #include +extern "C" { +extern char **environ; +} namespace NEO { namespace SysCalls { @@ -103,5 +106,10 @@ extern std::string dlOpenFilePathPassed; extern std::string mkfifoPathNamePassed; extern long sysconfReturn; +char **getEnviron(); } // namespace SysCalls +namespace ULT { +char **getCurrentEnviron(); +void setMockEnviron(char **mock); +} // namespace ULT } // namespace NEO diff --git a/shared/test/common/os_interface/windows/sys_calls.cpp b/shared/test/common/os_interface/windows/sys_calls.cpp index 41be708212..4f04619f2b 100644 --- a/shared/test/common/os_interface/windows/sys_calls.cpp +++ b/shared/test/common/os_interface/windows/sys_calls.cpp @@ -465,7 +465,14 @@ BOOL verQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUIN } return FALSE; } - +LPWCH mockEnvStringsW = nullptr; +BOOL mockFreeEnvStringsWResult = TRUE; +LPWCH getEnvironmentStringsW() { + return mockEnvStringsW; +} +BOOL freeEnvironmentStringsW(LPWCH) { + return mockFreeEnvStringsWResult; +} } // namespace SysCalls bool isShutdownInProgress() { @@ -475,5 +482,4 @@ bool isShutdownInProgress() { unsigned int readEnablePreemptionRegKey() { return 1; } - } // namespace NEO diff --git a/shared/test/unit_test/compiler_interface/linux/default_cl_cache_config_tests.cpp b/shared/test/unit_test/compiler_interface/linux/default_cl_cache_config_tests.cpp index 28ca21d731..3256831e96 100644 --- a/shared/test/unit_test/compiler_interface/linux/default_cl_cache_config_tests.cpp +++ b/shared/test/unit_test/compiler_interface/linux/default_cl_cache_config_tests.cpp @@ -388,4 +388,58 @@ TEST(ClCacheDefaultConfigLinuxTest, GivenNeoCachePersistentSetToZeroWhenGetDefau EXPECT_FALSE(cacheConfig.enabled); } + +TEST(ClCacheDefaultConfigLinuxTest, GivenIgcEnvVarSetOrUnsetThenCacheConfigIsEnabledOrDisabledAsExpected) { + DebugManagerStateRestore restorer; + debugManager.flags.PrintDebugMessages.set(true); + + std::unordered_map mockableEnvs; + mockableEnvs["NEO_CACHE_PERSISTENT"] = "1"; + mockableEnvs["NEO_CACHE_MAX_SIZE"] = "22"; + mockableEnvs["NEO_CACHE_DIR"] = "ult/directory/"; + + auto statMock = [](const std::string &filePath, struct stat *statbuf) noexcept { + statbuf->st_mode = S_IFDIR; + return 0; + }; + + auto buildEnviron = [](const std::unordered_map &envs, std::vector &storage) { + storage.clear(); + for (const auto &kv : envs) { + storage.push_back(kv.first + "=" + kv.second); + } + std::vector result; + for (auto &str : storage) { + result.push_back(const_cast(str.c_str())); + } + result.push_back(nullptr); + return result; + }; + + std::vector envStorage; + auto environVec = buildEnviron(mockableEnvs, envStorage); + NEO::ULT::setMockEnviron(environVec.data()); + + VariableBackup *> mockableEnvValuesBackup(&NEO::IoFunctions::mockableEnvValues, &mockableEnvs); + VariableBackup statBackup(&NEO::SysCalls::sysCallsStat, statMock); + + auto cacheConfig = NEO::getDefaultCompilerCacheConfig(); + EXPECT_TRUE(cacheConfig.enabled); + EXPECT_EQ(cacheConfig.cacheDir, "ult/directory/"); + + mockableEnvs["IGC_DEBUG"] = "1"; + environVec = buildEnviron(mockableEnvs, envStorage); + NEO::ULT::setMockEnviron(environVec.data()); + cacheConfig = NEO::getDefaultCompilerCacheConfig(); + EXPECT_FALSE(cacheConfig.enabled); + + mockableEnvs.erase("IGC_DEBUG"); + environVec = buildEnviron(mockableEnvs, envStorage); + NEO::ULT::setMockEnviron(environVec.data()); + cacheConfig = NEO::getDefaultCompilerCacheConfig(); + EXPECT_TRUE(cacheConfig.enabled); + EXPECT_EQ(cacheConfig.cacheDir, "ult/directory/"); + + NEO::ULT::setMockEnviron(nullptr); +} } // namespace NEO diff --git a/shared/test/unit_test/compiler_interface/windows/default_cl_cache_config_tests.cpp b/shared/test/unit_test/compiler_interface/windows/default_cl_cache_config_tests.cpp index f6793512bd..ac252eb57e 100644 --- a/shared/test/unit_test/compiler_interface/windows/default_cl_cache_config_tests.cpp +++ b/shared/test/unit_test/compiler_interface/windows/default_cl_cache_config_tests.cpp @@ -291,4 +291,33 @@ TEST_F(ClCacheDefaultConfigWindowsTest, GivenPrintDebugMessagesWhenCacheIsEnable EXPECT_STREQ(output.c_str(), "NEO_CACHE_PERSISTENT is enabled. Cache is located in: ult\\directory\\\n\n"); } +TEST_F(ClCacheDefaultConfigWindowsTest, GivenIgcEnvVarSetOrUnsetThenCacheConfigIsEnabledOrDisabledAsExpected) { + DebugManagerStateRestore restorer; + debugManager.flags.PrintDebugMessages.set(true); + + mockableEnvs["NEO_CACHE_PERSISTENT"] = "1"; + mockableEnvs["NEO_CACHE_MAX_SIZE"] = "22"; + mockableEnvs["NEO_CACHE_DIR"] = "ult\\directory\\"; + DWORD getFileAttributesResultMock = FILE_ATTRIBUTE_DIRECTORY; + VariableBackup pathExistsMockBackup(&SysCalls::getFileAttributesResult, getFileAttributesResultMock); + wchar_t envBlockNoIgc[] = L"NEO_CACHE_PERSISTENT=1\0NEO_CACHE_MAX_SIZE=22\0NEO_CACHE_DIR=ult\\directory\\\0\0"; + SysCalls::mockEnvStringsW = envBlockNoIgc; + + auto cacheConfig = getDefaultCompilerCacheConfig(); + EXPECT_TRUE(cacheConfig.enabled); + EXPECT_EQ(cacheConfig.cacheDir, "ult\\directory\\"); + + wchar_t envBlockWithIgc[] = L"IGC_DEBUG=1\0NEO_CACHE_PERSISTENT=1\0NEO_CACHE_MAX_SIZE=22\0NEO_CACHE_DIR=ult\\directory\\\0\0"; + SysCalls::mockEnvStringsW = envBlockWithIgc; + + cacheConfig = getDefaultCompilerCacheConfig(); + EXPECT_FALSE(cacheConfig.enabled); + + SysCalls::mockEnvStringsW = envBlockNoIgc; + + cacheConfig = getDefaultCompilerCacheConfig(); + EXPECT_TRUE(cacheConfig.enabled); + EXPECT_EQ(cacheConfig.cacheDir, "ult\\directory\\"); +} + } // namespace NEO