Skip to content

Commit 033885c

Browse files
fix(sysman): fixes multithread access issue with FDCache
Related-To: NEO-9720 Signed-off-by: Kulkarni, Ashwin Kumar <[email protected]> Source: a064388
1 parent d99bff4 commit 033885c

File tree

6 files changed

+72
-8
lines changed

6 files changed

+72
-8
lines changed

level_zero/sysman/source/shared/linux/sysman_fs_access_interface.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2023 Intel Corporation
2+
* Copyright (C) 2023-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -45,6 +45,7 @@ void FdCacheInterface::eraseLeastUsedEntryFromCache() {
4545
}
4646

4747
int FdCacheInterface::getFd(std::string file) {
48+
std::unique_lock<std::mutex> lock(fdMutex);
4849
int fd = -1;
4950
if (fdMap.find(file) == fdMap.end()) {
5051
fd = NEO::SysCalls::open(file.c_str(), O_RDONLY);
@@ -550,4 +551,4 @@ bool SysFsAccessInterface::isRootUser() {
550551
}
551552

552553
} // namespace Sysman
553-
} // namespace L0
554+
} // namespace L0

level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2023 Intel Corporation
2+
* Copyright (C) 2023-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -13,6 +13,7 @@
1313

1414
#include <map>
1515
#include <memory>
16+
#include <mutex>
1617
#include <vector>
1718

1819
namespace L0 {
@@ -31,6 +32,7 @@ class FdCacheInterface {
3132
std::map<std::string, std::pair<int, uint32_t>> fdMap = {};
3233

3334
private:
35+
std::mutex fdMutex{};
3436
void eraseLeastUsedEntryFromCache();
3537
};
3638

@@ -142,4 +144,4 @@ class SysFsAccessInterface : protected FsAccessInterface {
142144
};
143145

144146
} // namespace Sysman
145-
} // namespace L0
147+
} // namespace L0

level_zero/sysman/test/unit_tests/sources/linux/test_sysman.cpp

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020-2023 Intel Corporation
2+
* Copyright (C) 2020-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -257,6 +257,35 @@ TEST(FdCacheTest, GivenValidFdCacheWhenCallingGetFdOnSameFileThenVerifyCacheIsUp
257257
EXPECT_EQ(pFdCache->fdMap.end(), pFdCache->fdMap.find("mockfile9.txt"));
258258
}
259259

260+
TEST(FdCacheTest, GivenValidFdCacheWhenCallingGetFdOnMultipleFilesManyTimesThenVerifyCacheIsUpdatedCorrectly) {
261+
262+
class MockFdCache : public FdCacheInterface {
263+
public:
264+
using FdCacheInterface::fdMap;
265+
};
266+
267+
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
268+
return 1;
269+
});
270+
271+
std::unique_ptr<MockFdCache> pFdCache = std::make_unique<MockFdCache>();
272+
std::string fileName = {};
273+
for (auto i = 0; i < L0::Sysman::FdCacheInterface::maxSize; i++) {
274+
fileName = "mockfile" + std::to_string(i) + ".txt";
275+
int j = i + 1;
276+
while (j--) {
277+
EXPECT_LE(0, pFdCache->getFd(fileName));
278+
}
279+
}
280+
281+
// replace a least referred file and add new file
282+
fileName = "mockfile100.txt";
283+
EXPECT_LE(0, pFdCache->getFd(fileName));
284+
285+
// Verify cache doesn't have an element that is accessed less number of times.
286+
EXPECT_EQ(pFdCache->fdMap.end(), pFdCache->fdMap.find("mockfile0.txt"));
287+
}
288+
260289
TEST(FdCacheTest, GivenValidFdCacheWhenClearingCacheThenVerifyProperFdsAreClosedAndCacheIsUpdatedProperly) {
261290

262291
class MockFdCache : public FdCache {

level_zero/tools/source/sysman/linux/fs_access.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020-2023 Intel Corporation
2+
* Copyright (C) 2020-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -46,6 +46,7 @@ void FdCache::eraseLeastUsedEntryFromCache() {
4646
}
4747

4848
int FdCache::getFd(std::string file) {
49+
std::unique_lock<std::mutex> lock(fdMutex);
4950
int fd = -1;
5051
if (fdMap.find(file) == fdMap.end()) {
5152
fd = NEO::SysCalls::open(file.c_str(), O_RDONLY);

level_zero/tools/source/sysman/linux/fs_access.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020-2023 Intel Corporation
2+
* Copyright (C) 2020-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -18,6 +18,7 @@
1818
#include <list>
1919
#include <map>
2020
#include <memory>
21+
#include <mutex>
2122
#include <sstream>
2223
#include <string>
2324
#include <sys/stat.h>
@@ -41,6 +42,7 @@ class FdCache {
4142
std::map<std::string, std::pair<int, uint32_t>> fdMap = {};
4243

4344
private:
45+
std::mutex fdMutex{};
4446
void eraseLeastUsedEntryFromCache();
4547
};
4648

level_zero/tools/test/unit_tests/sources/sysman/linux/test_sysman.cpp

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020-2023 Intel Corporation
2+
* Copyright (C) 2020-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -540,6 +540,35 @@ TEST(FdCacheTest, GivenValidFdCacheWhenClearingCacheThenVerifyProperFdsAreClosed
540540
delete pFdCache;
541541
}
542542

543+
TEST(FdCacheTest, GivenValidFdCacheWhenCallingGetFdOnMultipleFilesManyTimesThenVerifyCacheIsUpdatedCorrectly) {
544+
545+
class MockFdCache : public FdCache {
546+
public:
547+
using FdCache::fdMap;
548+
};
549+
550+
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
551+
return 1;
552+
});
553+
554+
std::unique_ptr<MockFdCache> pFdCache = std::make_unique<MockFdCache>();
555+
std::string fileName = {};
556+
for (auto i = 0; i < L0::FdCache::maxSize; i++) {
557+
fileName = "mockfile" + std::to_string(i) + ".txt";
558+
int j = i + 1;
559+
while (j--) {
560+
EXPECT_LE(0, pFdCache->getFd(fileName));
561+
}
562+
}
563+
564+
// replace a least referred file and add new file
565+
fileName = "mockfile100.txt";
566+
EXPECT_LE(0, pFdCache->getFd(fileName));
567+
568+
// Verify cache doesn't have an element that is accessed less number of times.
569+
EXPECT_EQ(pFdCache->fdMap.end(), pFdCache->fdMap.find("mockfile0.txt"));
570+
}
571+
543572
TEST_F(SysmanDeviceFixture, GivenSysfsAccessClassAndUnsignedIntegerWhenCallingReadThenSuccessIsReturned) {
544573

545574
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {

0 commit comments

Comments
 (0)