mirror of
https://github.com/kata-containers/cgroups-rs.git
synced 2026-08-05 02:13:23 +00:00
cpu,cpuacct,cpuset: add first docs
Signed-off-by: Levente Kurusa <lkurusa@acm.org>
This commit is contained in:
28
src/cpu.rs
28
src/cpu.rs
@@ -1,17 +1,30 @@
|
||||
/* CPU controller */
|
||||
//! This module contains the implementation of the `cpu` cgroup subsystem.
|
||||
//!
|
||||
//! See the Kernel's documentation for more information about this subsystem, found at:
|
||||
//! [Documentation/scheduler/sched-design-CFS.txt](https://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt)
|
||||
//! paragraph 7 ("GROUP SCHEDULER EXTENSIONS TO CFS").
|
||||
use std::path::PathBuf;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use {CpuResources, Controllers, Controller, Resources, ControllIdentifier, Subsystem};
|
||||
|
||||
/// A controller that allows controlling the `cpu` subsystem of a Cgroup.
|
||||
///
|
||||
/// In essence, it allows gathering information about how much the tasks inside the control group
|
||||
/// are using the CPU and creating rules that limit their usage. Note that this crate does not yet
|
||||
/// support managing realtime tasks.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CpuController{
|
||||
base: PathBuf,
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
/// The current state of the control group and its processes.
|
||||
#[derive(Debug)]
|
||||
pub struct Cpu {
|
||||
/// Reports CPU time statistics.
|
||||
///
|
||||
/// Corresponds the `cpu.stat` file in `cpu` control group.
|
||||
pub stat: String,
|
||||
}
|
||||
|
||||
@@ -56,6 +69,7 @@ impl<'a> From<&'a Subsystem> for &'a CpuController {
|
||||
}
|
||||
|
||||
impl CpuController {
|
||||
/// Contructs a new `CpuController` with `oroot` serving as the root of the control group.
|
||||
pub fn new(oroot: PathBuf) -> Self {
|
||||
let mut root = oroot;
|
||||
root.push(Self::controller_type().to_string());
|
||||
@@ -64,6 +78,8 @@ impl CpuController {
|
||||
path: root,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns CPU time statistics based on the processes in the control group.
|
||||
pub fn cpu(self: &Self) -> Cpu {
|
||||
Cpu {
|
||||
stat: self.open_path("cpu.stat", false).and_then(|mut file| {
|
||||
@@ -74,18 +90,28 @@ impl CpuController {
|
||||
}
|
||||
}
|
||||
|
||||
/// Configures the CPU bandwidth (in relative relation to other control groups and this control
|
||||
/// group's parent).
|
||||
///
|
||||
/// For example, setting control group `A`'s `shares` to `100`, and control group `B`'s
|
||||
/// `shares` to `200` ensures that control group `B` receives twice as much as CPU bandwidth.
|
||||
/// (Assuming both `A` and `B` are of the same parent)
|
||||
pub fn set_shares(self: &Self, shares: u64) {
|
||||
self.open_path("cpu.shares", true).and_then(|mut file| {
|
||||
file.write_all(shares.to_string().as_ref()).ok()
|
||||
});
|
||||
}
|
||||
|
||||
/// Specify a period (when using the CFS scheduler) of time in microseconds for how often this
|
||||
/// control group's access to the CPU should be reallocated.
|
||||
pub fn set_cfs_period(self: &Self, us: u64) {
|
||||
self.open_path("cpu.cfs_period_us", true).and_then(|mut file| {
|
||||
file.write_all(us.to_string().as_ref()).ok()
|
||||
});
|
||||
}
|
||||
|
||||
/// Specify a quota (when using the CFS scheduler) of time in microseconds for which all tasks
|
||||
/// in this control group can run during one period (see: `set_cfs_period()`).
|
||||
pub fn set_cfs_quota(self: &Self, us: u64) {
|
||||
self.open_path("cpu.cfs_quota_us", true).and_then(|mut file| {
|
||||
file.write_all(us.to_string().as_ref()).ok()
|
||||
|
||||
@@ -1,24 +1,51 @@
|
||||
/* cpuacct controller */
|
||||
//! This module contains the implementation of the `cpuacct` cgroup subsystem.
|
||||
//!
|
||||
//! See the Kernel's documentation for more information about this subsystem, found at:
|
||||
//! [Documentation/cgroup-v1/cpuacct.txt](https://www.kernel.org/doc/Documentation/cgroup-v1/cpuacct.txt)
|
||||
use std::path::PathBuf;
|
||||
use std::io::{Read, Write};
|
||||
use std::fs::File;
|
||||
|
||||
use {Controllers, Resources, Subsystem, ControllIdentifier, Controller};
|
||||
|
||||
/// A controller that allows controlling the `cpuacct` subsystem of a Cgroup.
|
||||
///
|
||||
/// In essence, this control group provides accounting (hence the name `cpuacct`) for CPU usage of
|
||||
/// the tasks in the control group.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CpuAcctController {
|
||||
base: PathBuf,
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
/// Represents the statistics retrieved from the control group.
|
||||
pub struct CpuAcct {
|
||||
/// Divides the time used by the tasks into `user` time and `system` time.
|
||||
pub stat: String,
|
||||
/// Total CPU time (in nanoseconds) spent by the tasks.
|
||||
pub usage: u64,
|
||||
/// Total CPU time (in nanoseconds) spent by the tasks, broken down by CPU and by whether the
|
||||
/// time spent is `user` time or `system` time.
|
||||
///
|
||||
/// An example is as follows:
|
||||
/// ```
|
||||
/// cpu user system
|
||||
/// 0 8348363768 0
|
||||
/// 1 8324369100 0
|
||||
/// 2 8598185449 0
|
||||
/// 3 8648262473 0
|
||||
/// ```
|
||||
pub usage_all: String,
|
||||
/// CPU time (in nanoseconds) spent by the tasks, broken down by each CPU.
|
||||
/// Times spent in each CPU are separated by a space.
|
||||
pub usage_percpu: String,
|
||||
/// As for `usage_percpu`, but the `system` time spent.
|
||||
pub usage_percpu_sys: String,
|
||||
/// As for `usage_percpu`, but the `user` time spent.
|
||||
pub usage_percpu_user: String,
|
||||
/// CPU time (in nanoseconds) spent by the tasks that counted for `system` time.
|
||||
pub usage_sys: u64,
|
||||
/// CPU time (in nanoseconds) spent by the tasks that counted for `user` time.
|
||||
pub usage_user: u64,
|
||||
}
|
||||
|
||||
@@ -59,6 +86,8 @@ fn read_u64_from(mut file: File) -> Option<u64> {
|
||||
}
|
||||
|
||||
impl CpuAcctController {
|
||||
|
||||
/// Contructs a new `CpuAcctController` with `oroot` serving as the root of the control group.
|
||||
pub fn new(oroot: PathBuf) -> Self {
|
||||
let mut root = oroot;
|
||||
root.push(Self::controller_type().to_string());
|
||||
@@ -67,6 +96,8 @@ impl CpuAcctController {
|
||||
path: root,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gathers the statistics that are available in the control group into a `CpuAcct` structure.
|
||||
pub fn cpuacct(self: &Self) -> CpuAcct {
|
||||
CpuAcct {
|
||||
stat: self.open_path("cpuacct.stat", false)
|
||||
@@ -110,6 +141,8 @@ impl CpuAcctController {
|
||||
.unwrap_or(0),
|
||||
}
|
||||
}
|
||||
|
||||
/// Reset the statistics the kernel has gathered about the control group.
|
||||
pub fn reset(self: &Self) {
|
||||
self.open_path("cpuacct.usage", true).and_then(|mut file| {
|
||||
file.write_all(b"0").ok()
|
||||
|
||||
@@ -1,30 +1,73 @@
|
||||
/* cpuset controller */
|
||||
//! This module contains the implementation of the `cpuset` cgroup subsystem.
|
||||
//!
|
||||
//! See the Kernel's documentation for more information about this subsystem, found at:
|
||||
//! [Documentation/cgroup-v1/cpusets.txt](https://www.kernel.org/doc/Documentation/cgroup-v1/cpusets.txt)
|
||||
use std::path::PathBuf;
|
||||
use std::io::{Read, Write};
|
||||
use std::fs::File;
|
||||
|
||||
use {CpuResources, Resources, Controller, ControllIdentifier, Subsystem, Controllers};
|
||||
|
||||
/// A controller that allows controlling the `cpuset` subsystem of a Cgroup.
|
||||
///
|
||||
/// In essence, this controller is responsible for restricting the tasks in the control group to a
|
||||
/// set of CPUs and/or memory nodes.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CpuSetController {
|
||||
base: PathBuf,
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
/// The current state of the `cpuset` controller for this control group.
|
||||
pub struct CpuSet {
|
||||
/// If true, no other control groups can share the CPUs listed in the `cpus` field.
|
||||
pub cpu_exclusive: bool,
|
||||
/// The list of CPUs the tasks of the control group can run on. This is a comma-separated list
|
||||
/// with dashes between numbers representing ranges.
|
||||
pub cpus: String,
|
||||
/// The list of CPUs that the tasks can effectively run on. This removes the list of CPUs that
|
||||
/// the parent (and all of its parents) cannot run on from the `cpus` field of this control
|
||||
/// group.
|
||||
pub effective_cpus: String,
|
||||
/// The list of memory nodes that the tasks can effectively use. This removes the list of nodes that
|
||||
/// the parent (and all of its parents) cannot use from the `mems` field of this control
|
||||
/// group.
|
||||
pub effective_mems: String,
|
||||
/// If true, no other control groups can share the memory nodes listed in the `mems` field.
|
||||
pub mem_exclusive: bool,
|
||||
/// If true, the control group is 'hardwalled'. Kernel memory allocations (except for a few
|
||||
/// minor exceptions) are made from the memory nodes designated in the `mems` field.
|
||||
pub mem_hardwall: bool,
|
||||
/// If true, whenever `mems` is changed via `set_mems()`, the memory stored on the previous
|
||||
/// nodes are migrated to the new nodes selected by the new `mems`.
|
||||
pub memory_migrate: bool,
|
||||
/// Running average of the memory pressured faced by the tasks in the control group.
|
||||
pub memory_pressure: u64,
|
||||
/// This field is only at the root control group and controls whether the kernel will compute
|
||||
/// the memory pressure for control groups or not.
|
||||
pub memory_pressure_enabled: Option<bool>,
|
||||
/// If true, filesystem buffers are spread across evenly between the nodes specified in `mems`.
|
||||
pub memory_spread_page: bool,
|
||||
/// If true, kernel slab caches for file I/O are spread across evenly between the nodes
|
||||
/// specified in `mems`.
|
||||
pub memory_spread_slab: bool,
|
||||
/// The list of memory nodes the tasks of the control group can use. This is a comma-separated list
|
||||
/// with dashes between numbers representing ranges.
|
||||
pub mems: String,
|
||||
/// If true, the kernel will attempt to rebalance the load between the CPUs specified in the
|
||||
/// `cpus` field of this control group.
|
||||
pub sched_load_balance: bool,
|
||||
/// Represents how much work the kernel should do to rebalance this cpuset.
|
||||
///
|
||||
/// | `sched_load_balance` | Effect |
|
||||
/// | -------------------- | ------ |
|
||||
/// | -1 | Use the system default value |
|
||||
/// | 0 | Only balance loads periodically |
|
||||
/// | 1 | Immediately balance the load across tasks on the same core |
|
||||
/// | 2 | Immediately balance the load across cores in the same CPU package |
|
||||
/// | 4 | Immediately balance the load across CPUs on the same node |
|
||||
/// | 5 | Immediately balance the load between CPUs even if the system is NUMA |
|
||||
/// | 6 | Immediately balance the load between all CPUs |
|
||||
pub sched_relax_domain_level: u64,
|
||||
|
||||
}
|
||||
@@ -74,6 +117,7 @@ fn read_u64_from(mut file: File) -> Option<u64> {
|
||||
}
|
||||
|
||||
impl CpuSetController {
|
||||
/// Contructs a new `CpuSetController` with `oroot` serving as the root of the control group.
|
||||
pub fn new(oroot: PathBuf) -> Self {
|
||||
let mut root = oroot;
|
||||
root.push(Self::controller_type().to_string());
|
||||
@@ -83,6 +127,8 @@ impl CpuSetController {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the statistics gathered by the kernel for this control group. See the struct for
|
||||
/// more information on what information this entails.
|
||||
pub fn cpuset(self: &Self) -> CpuSet {
|
||||
CpuSet {
|
||||
cpu_exclusive: {
|
||||
@@ -166,6 +212,8 @@ impl CpuSetController {
|
||||
}
|
||||
}
|
||||
|
||||
/// Control whether the CPUs selected via `set_cpus()` should be exclusive to this control
|
||||
/// group or not.
|
||||
pub fn set_cpu_exclusive(self: &Self, b: bool) {
|
||||
self.open_path("cpuset.cpu_exclusive", true).and_then(|mut file| {
|
||||
if b {
|
||||
@@ -176,6 +224,8 @@ impl CpuSetController {
|
||||
});
|
||||
}
|
||||
|
||||
/// Control whether the memory nodes selected via `set_memss()` should be exclusive to this control
|
||||
/// group or not.
|
||||
pub fn set_mem_exclusive(self: &Self, b: bool) {
|
||||
self.open_path("cpuset.mem_exclusive", true).and_then(|mut file| {
|
||||
if b {
|
||||
@@ -186,18 +236,30 @@ impl CpuSetController {
|
||||
});
|
||||
}
|
||||
|
||||
/// Set the CPUs that the tasks in this control group can run on.
|
||||
///
|
||||
/// Syntax is a comma separated list of CPUs, with an additional extension that ranges can
|
||||
/// be represented via dashes.
|
||||
pub fn set_cpus(self: &Self, cpus: &String) {
|
||||
self.open_path("cpuset.cpus", true).and_then(|mut file| {
|
||||
file.write_all(cpus.as_ref()).ok()
|
||||
});
|
||||
}
|
||||
|
||||
/// Set the memory nodes that the tasks in this control group can use.
|
||||
///
|
||||
/// Syntax is the same as with `set_cpus()`.
|
||||
pub fn set_mems(self: &Self, mems: &String) {
|
||||
self.open_path("cpuset.mems", true).and_then(|mut file| {
|
||||
file.write_all(mems.as_ref()).ok()
|
||||
});
|
||||
}
|
||||
|
||||
/// Controls whether the control group should be "hardwalled", i.e., whether kernel allocations
|
||||
/// should exclusively use the memory nodes set via `set_mems()`.
|
||||
///
|
||||
/// Note that some kernel allocations, most notably those that are made in interrupt handlers
|
||||
/// may disregard this.
|
||||
pub fn set_hardwall(self: &Self, b: bool) {
|
||||
self.open_path("cpuset.mem_hardwall", true).and_then(|mut file| {
|
||||
if b {
|
||||
@@ -208,6 +270,8 @@ impl CpuSetController {
|
||||
});
|
||||
}
|
||||
|
||||
/// Controls whether the kernel should attempt to rebalance the load between the CPUs specified in the
|
||||
/// `cpus` field of this control group.
|
||||
pub fn set_load_balancing(self: &Self, b: bool) {
|
||||
self.open_path("cpuset.sched_load_balance", true).and_then(|mut file| {
|
||||
if b {
|
||||
@@ -218,12 +282,17 @@ impl CpuSetController {
|
||||
});
|
||||
}
|
||||
|
||||
/// Contorl how much effort the kernel should invest in rebalacing the control group.
|
||||
///
|
||||
/// See @CpuSet 's similar field for more information.
|
||||
pub fn set_rebalance_relax_domain_level(self: &Self, i: i64) {
|
||||
self.open_path("cpuset.sched_relax_domain_level", true).and_then(|mut file| {
|
||||
file.write_all(i.to_string().as_ref()).ok()
|
||||
});
|
||||
}
|
||||
|
||||
/// Control whether when using `set_mems()` the existing memory used by the tasks should be
|
||||
/// migrated over to the now-selected nodes.
|
||||
pub fn set_memory_migration(self: &Self, b: bool) {
|
||||
self.open_path("cpuset.memory_migrate", true).and_then(|mut file| {
|
||||
if b {
|
||||
@@ -234,6 +303,8 @@ impl CpuSetController {
|
||||
});
|
||||
}
|
||||
|
||||
/// Control whether filesystem buffers should be evenly split across the nodes selected via
|
||||
/// `set_mems()`.
|
||||
pub fn set_memory_spread_page(self: &Self, b: bool) {
|
||||
self.open_path("cpuset.memory_spread_page", true).and_then(|mut file| {
|
||||
if b {
|
||||
@@ -244,6 +315,8 @@ impl CpuSetController {
|
||||
});
|
||||
}
|
||||
|
||||
/// Control whether the kernel's slab cache for file I/O should be evenly split across the
|
||||
/// nodes selected via `set_mems()`.
|
||||
pub fn set_memory_spread_slab(self: &Self, b: bool) {
|
||||
self.open_path("cpuset.memory_spread_slab", true).and_then(|mut file| {
|
||||
if b {
|
||||
@@ -254,6 +327,11 @@ impl CpuSetController {
|
||||
});
|
||||
}
|
||||
|
||||
/// Control whether the kernel should collect information to calculate memory pressure for
|
||||
/// control groups.
|
||||
///
|
||||
/// Note: This is a no-operation if the control group referred by `self` is not the root
|
||||
/// control group.
|
||||
pub fn set_enable_memory_pressure(self: &Self, b: bool) {
|
||||
/* XXX: this file should only be present in the root cpuset cg */
|
||||
self.open_path("cpuset.memory_pressure_enabled", true).and_then(|mut file| {
|
||||
|
||||
Reference in New Issue
Block a user