about summary refs log tree commit diff
path: root/library/std
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-12-28 22:22:18 +0100
committerGitHub <noreply@github.com>2022-12-28 22:22:18 +0100
commit2dd2fb728e61a6e7912e1e2818407625ad806bb9 (patch)
tree0ce7e04d8cc2e0c10601a13db280fa68fba8fe48 /library/std
parentd91432832e585f641976037eca8ee7aa2a7d346d (diff)
parent04f1ead55243c895da7c3703e2daca319f381124 (diff)
downloadrust-2dd2fb728e61a6e7912e1e2818407625ad806bb9.tar.gz
rust-2dd2fb728e61a6e7912e1e2818407625ad806bb9.zip
Rollup merge of #104493 - adamncasey:cgroupzeroperiod, r=m-ou-se
available_parallelism: Gracefully handle zero value cfs_period_us

There seem to be some scenarios where the cgroup cpu quota field `cpu.cfs_period_us` can contain `0`. This field is used to determine the "amount" of parallelism suggested by the function `std::thread::available_parallelism`

A zero value of this field cause a panic when `available_parallelism()` is invoked. This issue was detected by the call from binaries built by `cargo test`. I really don't feel like `0` is a good value for `cpu.cfs_period_us`, but I also don't think applications should panic if this value is seen.

This panic started happening with rust 1.64.0.

This case is gracefully handled by other projects which read this information: [num_cpus](https://github.com/seanmonstar/num_cpus/blob/e437b9d9083d717692e35d917de8674a7987dd06/src/linux.rs#L207-L210), [ninja](https://github.com/ninja-build/ninja/pull/2174/files), [dotnet](https://github.com/dotnet/runtime/blob/c4341d45acca3ea662cd8d71e7d71094450dd045/src/coreclr/pal/src/misc/cgroup.cpp#L481-L483)

Before this change, running `cargo test` in environments configured as described above would trigger this panic:
```
$ RUST_BACKTRACE=1 cargo test
    Finished test [unoptimized + debuginfo] target(s) in 3.55s
     Running unittests src/main.rs (target/debug/deps/x-9a42e145aca2934d)
thread 'main' panicked at 'attempt to divide by zero', library/std/src/sys/unix/thread.rs:546:70
stack backtrace:
   0: rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::panicking::panic
   3: std::sys::unix::thread::cgroups::quota
   4: std::sys::unix::thread::available_parallelism
   5: std::thread::available_parallelism
   6: test::helpers::concurrency::get_concurrency
   7: test::console::run_tests_console
   8: test::test_main
   9: test::test_main_static
  10: x::main
             at ./src/main.rs:1:1
  11: core::ops::function::FnOnce::call_once
             at /tmp/rust-1.64-1.64.0-1/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: test failed, to rerun pass '--bin x'
```

I've tested this change in an environment which has the bad (questionable?) setup and rebuilding the test executable against a fixed std library fixes the panic.
Diffstat (limited to 'library/std')
-rw-r--r--library/std/src/sys/unix/thread.rs4
1 files changed, 2 insertions, 2 deletions
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index d847f2775ab..b251949bda2 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -505,7 +505,7 @@ mod cgroups {
                     let limit = raw_quota.next()?;
                     let period = raw_quota.next()?;
                     match (limit.parse::<usize>(), period.parse::<usize>()) {
-                        (Ok(limit), Ok(period)) => {
+                        (Ok(limit), Ok(period)) if period > 0 => {
                             quota = quota.min(limit / period);
                         }
                         _ => {}
@@ -565,7 +565,7 @@ mod cgroups {
                 let period = parse_file("cpu.cfs_period_us");
 
                 match (limit, period) {
-                    (Some(limit), Some(period)) => quota = quota.min(limit / period),
+                    (Some(limit), Some(period)) if period > 0 => quota = quota.min(limit / period),
                     _ => {}
                 }