Skip to content

Instantly share code, notes, and snippets.

@rsms
Last active December 1, 2022 04:08
Show Gist options
  • Save rsms/5f9899fb4a7dcce0ca2479a27af55130 to your computer and use it in GitHub Desktop.
Save rsms/5f9899fb4a7dcce0ca2479a27af55130 to your computer and use it in GitHub Desktop.
Example of limiting how much CPU a process can use in linux with cgroup2
#!/bin/sh
set -e
# Documentation and guides:
# https://docs.kernel.org/admin-guide/cgroup-v2.html
# https://lore.kernel.org/lkml/20160812221742.GA24736@cmpxchg.org/T/
# https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/managing_monitoring_and_updating_the_kernel/using-cgroups-v2-to-control-distribution-of-cpu-time-for-applications_managing-monitoring-and-updating-the-kernel
# remove if already exists
[ -e /sys/fs/cgroup/test1 ] && rmdir /sys/fs/cgroup/test1
# create and add cpu control
# (alt with cgroup-tools: cgcreate -g cpu:/test1)
mkdir /sys/fs/cgroup/test1
echo "+cpu" >> /sys/fs/cgroup/test1/cgroup.subtree_control
# set CPU limit
# The maximum bandwidth limit. It’s in the following format:
# $MAX $PERIOD
# which indicates that the group may consume upto $MAX in each $PERIOD duration.
# "max" for $MAX indicates no limit. If only one number is written, $MAX is updated.
#
# The first value is the allowed time quota in microseconds for which
# all processes collectively in a child group can run during one
# period. The second value specifies the length of the period.
#
# During a single period, when processes in a control group collectively
# exhaust the time specified by this quota, they are throttled for the
# remainder of the period and not allowed to run until the next
# period.
#
# This command sets CPU time distribution controls so that all processes
# collectively in the /sys/fs/cgroup/test1 child group can run on the CPU
# for only 0.2 seconds of every 1 second. That is, one fifth of each second.
#
echo "200000 1000000" > /sys/fs/cgroup/test1/cpu.max
# We can now add processes to the test1 cgroup with
#echo "$PID" > /sys/fs/cgroup/test1/cgroup.procs
# We can find out what cgroup a proccess belongs to:
#cat /proc/$PID/cgroup
# If cgroup-tools is installed, use it to spawn a process in test1:
# [alpine:] apk add cgroup-tools stress-ng
# You'll see something like this:
# - first run: bogo ops/s (real time) 5009.96
# - second run: bogo ops/s (real time) 260.88
# Indicating that the second run was limited in CPU usage.
#
if command -v cgexec >/dev/null && command -v stress-ng >/dev/null; then
echo "#—————————————————————————————————————————————————"
echo "# Running stress-ng freely (no cgroup)"
echo "stress-ng --cpu 4 --timeout 4s --metrics-brief"
echo "#—————————————————————————————————————————————————"
stress-ng --cpu 4 --timeout 4s --metrics-brief
echo "#—————————————————————————————————————————————————"
echo "# Running stress-ng in cgroup test1"
echo "cgexec -g cpu:test1 stress-ng --cpu 4 --timeout 4s --metrics-brief"
echo "#—————————————————————————————————————————————————"
cgexec -g cpu:test1 stress-ng --cpu 4 --timeout 4s --metrics-brief
[ -n "$NO_RM_CGROUP" ] || rmdir /sys/fs/cgroup/test1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment