Skip to content

Commit 9cbf150

Browse files
Pavel Harbanaucodebot
authored andcommitted
fix assertion when isolated cpus are used together with manual thread affinities
1 parent 18d1f53 commit 9cbf150

File tree

5 files changed

+53
-9
lines changed

5 files changed

+53
-9
lines changed

apps/gnb/gnb_appconfig_cli11_schema.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,6 +1842,17 @@ static void configure_cli11_hal_args(CLI::App& app, optional<hal_appconfig>& con
18421842
app.add_option("--eal_args", config->eal_args, "EAL configuration parameters used to initialize DPDK");
18431843
}
18441844

1845+
static void validate_cpu_range(const os_sched_affinity_bitmask& allowed_cpus_mask,
1846+
const os_sched_affinity_bitmask& mask,
1847+
const std::string& name)
1848+
{
1849+
for (unsigned i = 0; i != mask.size(); ++i) {
1850+
if (mask.test(i) && !allowed_cpus_mask.test(i)) {
1851+
report_error("CPU core {} selected in '{}' option doesn't belong to isolated cpuset.", i, name);
1852+
}
1853+
}
1854+
}
1855+
18451856
static error_type<std::string> is_valid_cpu_index(unsigned cpu_idx)
18461857
{
18471858
unsigned nof_cpus = compute_host_nof_hardware_threads();
@@ -2036,6 +2047,26 @@ static void configure_cli11_affinity_args(CLI::App& app, cpu_affinities_appconfi
20362047
parsing_isolated_cpus_fcn(config, value, "isolated_cpus");
20372048
},
20382049
"CPU cores isolated for gNB application");
2050+
2051+
// Callback function for validating that thread affinities do use allowed set of CPUs in case the 'isolated_cpus'
2052+
// option was specified.
2053+
auto validate_isolation = [parsing_fcn](CLI::App& cli_app, cpu_affinities_appconfig& cfg) {
2054+
unsigned isol_cpus_option_count = cli_app.count("--isolated_cpus");
2055+
if (!isol_cpus_option_count) {
2056+
return;
2057+
}
2058+
os_sched_affinity_bitmask isol_cpus_bitmask;
2059+
parsing_fcn(isol_cpus_bitmask, cfg.isol_cpus.value().isolated_cpus, "isolated_cpus");
2060+
2061+
validate_cpu_range(isol_cpus_bitmask, cfg.l1_dl_cpu_cfg.mask, "l1_dl_cpus");
2062+
validate_cpu_range(isol_cpus_bitmask, cfg.l1_ul_cpu_cfg.mask, "l1_ul_cpus");
2063+
validate_cpu_range(isol_cpus_bitmask, cfg.l2_cell_cpu_cfg.mask, "l2_cell_cpus");
2064+
validate_cpu_range(isol_cpus_bitmask, cfg.ru_cpu_cfg.mask, "ru_cpus");
2065+
validate_cpu_range(isol_cpus_bitmask, cfg.low_priority_cpu_cfg.mask, "low_priority_cpus");
2066+
};
2067+
2068+
// Post-parsing callback for the case when both manual pinning and isolated_cpus were used.
2069+
app.callback([&]() { validate_isolation(app, config); });
20392070
}
20402071

20412072
static void configure_cli11_upper_phy_threads_args(CLI::App& app, upper_phy_threads_appconfig& config)

apps/gnb/gnb_os_sched_affinity_manager.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct gnb_os_sched_affinity_config {
5656
/// Affinity mask.
5757
os_sched_affinity_bitmask mask;
5858
/// Thread pinning policy.
59-
gnb_sched_affinity_mask_policy pinning_policy = gnb_sched_affinity_mask_policy::round_robin;
59+
gnb_sched_affinity_mask_policy pinning_policy = gnb_sched_affinity_mask_policy::mask;
6060
};
6161

6262
/// \brief Scheduler affinity mask manager.
@@ -101,7 +101,7 @@ class gnb_os_sched_affinity_manager
101101
last_pos_used = (pos < 0) ? 0 : pos + 1;
102102
}
103103

104-
return os_sched_affinity_bitmask(pos);
104+
return os_sched_affinity_bitmask(mask.size(), pos);
105105
}
106106

107107
private:

include/srsran/support/unique_thread.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ struct os_sched_affinity_bitmask {
9999

100100
explicit os_sched_affinity_bitmask(size_t cpu_idx) : cpu_bitset(compute_host_nof_hardware_threads()) { set(cpu_idx); }
101101

102+
os_sched_affinity_bitmask(size_t bitset_size, size_t cpu_idx) : cpu_bitset(bitset_size) { set(cpu_idx); }
103+
102104
size_t size() const { return cpu_bitset.size(); }
103105

104106
void set(size_t cpu_idx) { cpu_bitset.set(cpu_idx); }

lib/support/sysinfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ void cleanup_cgroups()
134134
std::string housekeeping_cgroup_path = "/sys/fs/cgroup/housekeeping";
135135
std::string root_cgroup_path = "/sys/fs/cgroup/cgroup.procs";
136136

137+
struct stat sysfs_info;
138+
if (::stat("/sys/fs/cgroup", &sysfs_info) < 0) {
139+
return;
140+
}
141+
137142
struct stat info;
138143
if (::stat(housekeeping_cgroup_path.c_str(), &info) == 0) {
139144
move_procs_between_cgroups(root_cgroup_path, housekeeping_cgroup_path + "/cgroup.procs");
@@ -155,4 +160,5 @@ void cleanup_cgroups()
155160
if (cgroup_changed) {
156161
std::this_thread::sleep_for(100ms);
157162
}
163+
move_to_cgroup("/sys/fs/cgroup");
158164
}

lib/support/unique_thread.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,24 @@ static bool thread_set_param(pthread_t t, os_thread_realtime_priority prio)
4040
return true;
4141
}
4242

43-
static bool thread_set_affinity(pthread_t t, const os_sched_affinity_bitmask& bitmap)
43+
static bool thread_set_affinity(pthread_t t, const os_sched_affinity_bitmask& bitmap, const std::string& name)
4444
{
45-
cpu_set_t cpuset;
46-
CPU_ZERO(&cpuset);
45+
cpu_set_t* cpusetp = CPU_ALLOC(bitmap.size());
46+
size_t cpuset_size = CPU_ALLOC_SIZE(bitmap.size());
47+
CPU_ZERO_S(cpuset_size, cpusetp);
48+
4749
for (size_t i = 0; i < bitmap.size(); ++i) {
4850
if (bitmap.test(i)) {
49-
CPU_SET(i, &cpuset);
51+
CPU_SET_S(i, cpuset_size, cpusetp);
5052
}
5153
}
52-
if (pthread_setaffinity_np(t, sizeof(cpu_set_t), &cpuset) != 0) {
53-
perror("pthread_setaffinity_np");
54+
int ret;
55+
if ((ret = pthread_setaffinity_np(t, cpuset_size, cpusetp)) != 0) {
56+
fmt::print("Couldn't set affinity for {} thread. Cause: '{}'\n", name, strerror(ret));
57+
CPU_FREE(cpusetp);
5458
return false;
5559
}
60+
CPU_FREE(cpusetp);
5661
return true;
5762
}
5863

@@ -153,7 +158,7 @@ std::thread unique_thread::make_thread(const std::string& name,
153158
thread_set_param(tself, prio);
154159
}
155160
if (cpu_mask.any()) {
156-
thread_set_affinity(tself, cpu_mask);
161+
thread_set_affinity(tself, cpu_mask, name);
157162
}
158163
#endif
159164

0 commit comments

Comments
 (0)