Repository: opencontainers/runc
File: libcontainer/cgroups/fs2/fs2.go (Go)

Code before:
}

func (m *Manager) GetStats() (*cgroups.Stats, error) {
	var errs []error

	st := cgroups.NewStats()

	// pids (since kernel 4.5)
	if err := statPids(m.dirPath, st); err != nil {
		errs = append(errs, err)
	}
	// memory (since kernel 4.5)
	if err := statMemory(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	// io (since kernel 4.5)
	if err := statIo(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	// cpu (since kernel 4.15)
	// Note cpu.stat is available even if the controller is not enabled.
	if err := statCpu(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	// hugetlb (since kernel 5.6)
	if err := statHugeTlb(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	// rdma (since kernel 4.11)
	if err := fscommon.RdmaGetStats(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	if len(errs) > 0 && !m.config.Rootless {
		return st, fmt.Errorf("error while statting cgroup v2: %+v", errs)
	}
	return st, nil
}

func (m *Manager) Freeze(state configs.FreezerState) error {
	if m.config.Resources == nil {
		return errors.New("cannot toggle freezer: cgroups not configured for container")
	}
	if err := setFreezer(m.dirPath, state); err != nil {
		return err
	}
	m.config.Resources.Freezer = state
	return nil
}

func (m *Manager) Destroy() error {
	return cgroups.RemovePath(m.dirPath)

Review comment (performance):
@kolyshkin I think this one could be optimized. We should write their own PSI state function for `cpu`, `memory` and `io`. For example: add `statCpuPressure` in `cpu.go`, add `statMemoryPressure` in `memory.go`, add `statIOPressure` in `io.go`. Then, we can keep the code style like `statCpu`.
But this one could be done in a seperate PR if the upstream projects are very anxious to need this feature.

Code after:
}

func (m *Manager) GetStats() (*cgroups.Stats, error) {
	var errs []error

	st := cgroups.NewStats()

	// pids (since kernel 4.5)
	if err := statPids(m.dirPath, st); err != nil {
		errs = append(errs, err)
	}
	// memory (since kernel 4.5)
	if err := statMemory(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	// io (since kernel 4.5)
	if err := statIo(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	// cpu (since kernel 4.15)
	// Note cpu.stat is available even if the controller is not enabled.
	if err := statCpu(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	// PSI (since kernel 4.20).
	var err error
	if st.CpuStats.PSI, err = statPSI(m.dirPath, "cpu.pressure"); err != nil {
		errs = append(errs, err)
	}
	if st.MemoryStats.PSI, err = statPSI(m.dirPath, "memory.pressure"); err != nil {
		errs = append(errs, err)
	}
	if st.BlkioStats.PSI, err = statPSI(m.dirPath, "io.pressure"); err != nil {
		errs = append(errs, err)
	}
	// hugetlb (since kernel 5.6)
	if err := statHugeTlb(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	// rdma (since kernel 4.11)
	if err := fscommon.RdmaGetStats(m.dirPath, st); err != nil && !os.IsNotExist(err) {
		errs = append(errs, err)
	}
	if len(errs) > 0 && !m.config.Rootless {
		return st, fmt.Errorf("error while statting cgroup v2: %+v", errs)
	}
	return st, nil
}

func (m *Manager) Freeze(state configs.FreezerState) error {
	if m.config.Resources == nil {