Skip to content

Commit 92273b3

Browse files
authored
[backport] Add support for cgroupv2. (dmlc#9651) (dmlc#9656)
1 parent e824b18 commit 92273b3

File tree

2 files changed

+59
-15
lines changed

2 files changed

+59
-15
lines changed

src/common/threading_utils.cc

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,23 @@
33
*/
44
#include "threading_utils.h"
55

6-
#include <fstream>
7-
#include <string>
6+
#include <algorithm> // for max
7+
#include <exception> // for exception
8+
#include <filesystem> // for path, exists
9+
#include <fstream> // for ifstream
10+
#include <string> // for string
811

9-
#include "xgboost/logging.h"
12+
#include "common.h" // for DivRoundUp
1013

11-
namespace xgboost {
12-
namespace common {
13-
int32_t GetCfsCPUCount() noexcept {
14+
namespace xgboost::common {
15+
/**
16+
* Modified from
17+
* github.com/psiha/sweater/blob/master/include/boost/sweater/hardware_concurrency.hpp
18+
*
19+
* MIT License: Copyright (c) 2016 Domagoj Šarić
20+
*/
21+
std::int32_t GetCGroupV1Count(std::filesystem::path const& quota_path,
22+
std::filesystem::path const& peroid_path) {
1423
#if defined(__linux__)
1524
// https://bugs.openjdk.java.net/browse/JDK-8146115
1625
// http://hg.openjdk.java.net/jdk/hs/rev/7f22774a5f42
@@ -31,15 +40,56 @@ int32_t GetCfsCPUCount() noexcept {
3140
}
3241
};
3342
// complete fair scheduler from Linux
34-
auto const cfs_quota(read_int("/sys/fs/cgroup/cpu/cpu.cfs_quota_us"));
35-
auto const cfs_period(read_int("/sys/fs/cgroup/cpu/cpu.cfs_period_us"));
43+
auto const cfs_quota(read_int(quota_path.c_str()));
44+
auto const cfs_period(read_int(peroid_path.c_str()));
3645
if ((cfs_quota > 0) && (cfs_period > 0)) {
3746
return std::max(cfs_quota / cfs_period, 1);
3847
}
3948
#endif // defined(__linux__)
4049
return -1;
4150
}
4251

52+
std::int32_t GetCGroupV2Count(std::filesystem::path const& bandwidth_path) noexcept(true) {
53+
std::int32_t cnt{-1};
54+
#if defined(__linux__)
55+
namespace fs = std::filesystem;
56+
57+
std::int32_t a{0}, b{0};
58+
59+
auto warn = [] { LOG(WARNING) << "Invalid cgroupv2 file."; };
60+
try {
61+
std::ifstream fin{bandwidth_path, std::ios::in};
62+
fin >> a;
63+
fin >> b;
64+
} catch (std::exception const&) {
65+
warn();
66+
return cnt;
67+
}
68+
if (a > 0 && b > 0) {
69+
cnt = std::max(common::DivRoundUp(a, b), 1);
70+
}
71+
#endif // defined(__linux__)
72+
return cnt;
73+
}
74+
75+
std::int32_t GetCfsCPUCount() noexcept {
76+
namespace fs = std::filesystem;
77+
fs::path const bandwidth_path{"/sys/fs/cgroup/cpu.max"};
78+
auto has_v2 = fs::exists(bandwidth_path);
79+
if (has_v2) {
80+
return GetCGroupV2Count(bandwidth_path);
81+
}
82+
83+
fs::path const quota_path{"/sys/fs/cgroup/cpu/cpu.cfs_quota_us"};
84+
fs::path const peroid_path{"/sys/fs/cgroup/cpu/cpu.cfs_period_us"};
85+
auto has_v1 = fs::exists(quota_path) && fs::exists(peroid_path);
86+
if (has_v1) {
87+
return GetCGroupV1Count(quota_path, peroid_path);
88+
}
89+
90+
return -1;
91+
}
92+
4393
std::int32_t OmpGetNumThreads(std::int32_t n_threads) {
4494
// Don't use parallel if we are in a parallel region.
4595
if (omp_in_parallel()) {
@@ -54,5 +104,4 @@ std::int32_t OmpGetNumThreads(std::int32_t n_threads) {
54104
n_threads = std::max(n_threads, 1);
55105
return n_threads;
56106
}
57-
} // namespace common
58-
} // namespace xgboost
107+
} // namespace xgboost::common

src/common/threading_utils.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,6 @@ inline std::int32_t OmpGetThreadLimit() {
253253
* \brief Get thread limit from CFS.
254254
*
255255
* This function has non-trivial overhead and should not be called repeatly.
256-
*
257-
* Modified from
258-
* github.com/psiha/sweater/blob/master/include/boost/sweater/hardware_concurrency.hpp
259-
*
260-
* MIT License: Copyright (c) 2016 Domagoj Šarić
261256
*/
262257
std::int32_t GetCfsCPUCount() noexcept;
263258

0 commit comments

Comments
 (0)