cgroups allow for system resources to be limited for certain user’s processes, which are defined in configuration files. This is useful e.g. if you wish to limit a compiler’s maximum memory usage and avoid it grinding the system to a halt.
Prerequisites
libcgroup-tools need to be installed
sudo yum list installed libcgroup-tools
If not installed, run
sudo yum install libcgroup-tools -y
Creating cgroups
In RHEL 7, you can list the resource controllers which are mounted by default using
lssubsys
If you are configuring any of the listed controllers, you do not need to mount them in your configuration file.
The default syntax of /etc/cgconfig.conf, the default control group configuration file, is:
/etc/cgconfig.conf
group <groupname> {
[permissions] #optional
<controller> {
<param name> = <param value>
...
}
...
}
If this is your first time configuring control groups on a system, configure the service to start at boot:
sudo systemctl enable cgconfig
Start the service:
sudo systemctl start cgconfig
Once you have created control groups, you need to modify /etc/cgrules.conf, which assigns user processes to control groups:
NB: the <process> parameter is optional
<user>:<process> <controllers> <controlgroup>
If this is the first time control groups are created on a particular system, configure the service to start at boot:
sudo systemctl enable cgred
Start the service:
sudo systemctl start cgred
Example: Limiting PyCharm memory usage to 40% of total RAM & Swap
Work out 40% of total system memory in kB:
awk '/MemTotal/{printf "%d\n", $2 * 0.4}' < /proc/meminfo
3931969
Work out 40% of total system swap in kB:
awk '/SwapTotal/{printf "%d\n", $2 * 0.4}' < /proc/meminfo
2018507
Add the two together: 3931969 + 2018507 = 5950476
Create the control group and set memory limits:
/etc/cgconfig.conf
group pycharm {
memory {
memory.limit_in_bytes = 3931969k;
memory.memsw.limit_in_bytes = 5950476k;
}
}
Start the service:
sudo systemctl start cgconfig
This will create the pycharm cgroup under /sys/fs/cgroup/memory, owned by root as we did not specify any custom permissions:
ls -l /sys/fs/cgroup/memory | grep pycharm
drwxr-xr-x 2 root root 0 Jun 1 08:27 pycharm
Assign all users’ PyCharm processes to the control group:
NB: Find out process’ path if it is not an alias. In this example pycharm ? /usr/local/bin/pycharm ? /opt/pycharm-community-2017.3.4/bin/pycharm.sh
*:pycharm memory pycharm
Start the service:
sudo systemctl start cgred
Check the cgroups are correctly configured i.e. launching pycharm populates the files in /sys/fs/cgroup/memory/pycharm:
#Before running pycharm
cat /sys/fs/cgroup/memory/pycharm/memory.usage_in_bytes
0
#Launch pycharm process
pycharm &
#Check mem usage file is populated
cat /sys/fs/cgroup/memory/pycharm/memory.usage_in_bytes
934385456
Example: Stress testing memory in a cgroup
It is a VERY good idea to stress test the defined RAM limits for a new cgroup.
This can be done by adding the stress command to the cgroup:
<user>:stress memory <groupname>
Confirm that the stress process can reach the cgroup memory limit, e.g. 40% of total RAM:
cat /sys/fs/cgroup/memory/<groupname>/memory.usage_in_bytes
0
#Start stress process
stress --vm-bytes $(awk '/MemTotal/{printf "%d\n", $2 * (40 / 100);}' < /proc/meminfo)k --vm-keep -m 1
cat /sys/fs/cgroup/memory/pycharm/memory.usage_in_bytes
3879653376
#Use CTRL+C to stop the stress process
Confirm that the stress process is killed if it tries to use more RAM than permitted e.g. 80% of RAM:
cat /sys/fs/cgroup/memory/<groupname>/memory.usage_in_bytes
0
#Start stress process and confirm it is killed using sig 9
stress --vm-bytes $(awk '/MemTotal/{printf "%d\n", $2 * (80 / 100);}' < /proc/meminfo)k --vm-keep -m 1
stress: info: [89346] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [89346] (415) <-- worker 89347 got signal 9
stress: WARN: [89346] (417) now reaping child worker processes
stress: FAIL: [89346] (451) failed run completed in 6s