Non-paging processes with CGroups

10th November 2017 (2 years ago)

There are situations where sometimes you want more control over your processess and the programs you run. Commonly the first tools people turn to are nice for controlling share of processor time or ionice for controlling share of disk access.

In this instance I was more interested in memory usage as the system I'm running doesn't have much. I wanted certain apps to always stay in RAM so that there would be less lag during day-to-day use. The thinking was that parts of the system that make up the desktop can go for a long time without intereaction (while the user stays within one desktop app) but when the user wishes to switch desktop or perform some other desktop function they want to do so quickly. Therefore the other applicaitons that run within should be swapped out to swap/disk more readily than the processes that make up the desktop experience.

I found out that CGroups (Linux Control Groups) should be able to control memory in this way. As a bonus, slices of CPU time can be controlled very specifically like a percentage. CGroups are what underpin a lot of the resource allocation and sharing between VPS users on shared servers.

sudo apt install cgroup-tools

Firstly, we'll create a new group called priority-processes.

cgcreate -g cpu,memory:priority-processes

Then we classify the processes we are interested in, assigning them to the new group. In this instance, I want to control X (display server), Gnome Shell (Gnome 3 desktop) and Guake (terminal emulator) processes that are already running.

cgclassify -g cpu,memory:priority-processes `pidof Xorg`
cgclassify -g cpu,memory:priority-processes `pidof gdm3`
cgclassify -g cpu,memory:priority-processes `pidof gnome-shell`
cgclassify -g cpu,memory:priority-processes `pidof /usr/bin/python2.7 /usr/bin/guake`

Here we set the swappiness of the group to 0, so it should never get swapped out. You could set this to a higher value if you just want less swappiness. Default value is commonly 60, so you should get reduces swapping as long as you have a lower number than that. More about swappiness (TODO: link)

cgset -r memory.swappiness=0 priority-processes

I also decided to bump up the share of the CPU that this group has so that if other applications are competing, these will get more. I'm not really sure if this is actually better than just setting lower nice values. 1024 is the default value.

cgset -r cpu.shares=2048 priority-processes

I'll set the nice values lower as well.

renice -n -1 `pidof Xorg`
renice -n -1 `pidof gdm3`
renice -n -1 `pidof gnome-shell`
renice -n -1 `pidof /usr/bin/python2.7 /usr/bin/guake`

Permanant configurations

sudo cgconfigparser -l /etc/cgconfig.conf
sudo apt install cgmanager

Systemd

For services that are started by systemd, it is easy to add cgroup options to their config file. These files are usually stored in /lib/systemd/system. For example, under the [Service] section you can add the line CPUQuota=50%.

Please leave a comment if you find these notes helpful and have found a use for CGroups. I'm still experimenting with Cgroup settings to try and find the best combinations.

https://wiki.debian.org/Hugepages https://wiki.archlinux.org/index.php/Cgroups https://www.cloudsigma.com/howto-cgroups/

http://stackoverflow.com/questions/578137/can-i-tell-linux-not-to-swap-out-a-particular-processes-memory http://unix.stackexchange.com/questions/10214/how-to-set-per-process-swapiness-for-linux#10227 http://superuser.com/questions/283819/how-to-tame-linux-responsiveness-memory-and-paging http://stackoverflow.com/questions/12520499/linux-how-to-lock-the-pages-of-a-process-in-memory