Forum

Full Version: Managing process priority.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
A few weeks ago I was asked to make little guide on CPU/IO priorities handling. I'm not an expert in the field so if you find something overly complex or incorrect (I will surely try to avoid the last) please tell me!
The idea behind this is fairly simple, have downloads running on background and whenever you must use xbmc make sure that it get's most of the kernel scheduler attention. I manage to do that by simply altering the process CPU and I/O(Input/Output) priority.

Introduction
The utilities Nice and Ionice manage the priority of a given process and its hard drive(I/O) priorities respectively.

Nice
CPU priorities are handled according to a number which defaults to 0 and whose values range from -20(Maximum priority) to 19(Minimum priority), a few system specific processes default to high priorities. You can see all of this using the top utility:
Terminal
xbian@Raspberry ~ $ top
top - 20:31:25 up 7 min, 1 user, load average: 1.21, 2.45, 1.37
Tasks: 90 total, 1 running, 89 sleeping, 0 stopped, 0 zombie
%Cpu(s): 21.4 us, 6.8 sy, 5.2 ni, 66.3 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
KiB Mem: 382820 total, 319176 used, 63644 free, 32092 buffers
KiB Swap: 127996 total, 0 used, 127996 free, 124272 cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2483 xbian 20 -5 310m 45m 15m S 26.0 12.3 1:59.86 xbmc.bin
2856 xbian 20 0 6284 1464 1052 R 1.3 0.4 0:00.66 top
2213 sabnzbd 30 10 178m 11m 1864 S 1.0 3.2 0:04.03 SABnzbd.py
29 root 1 -19 0 0 0 S 0.7 0.0 0:01.85 VCHIQ-0
42 root 20 0 0 0 0 S 0.3 0.0 0:09.95 mmcqd/0
2195 couchpot 30 10 114m 42m 5004 S 0.3 11.4 2:51.66 python
2383 sickbear 30 10 191m 25m 3496 S 0.3 6.9 0:17.63 python
2458 transmis 30 10 33496 3360 2440 S 0.3 0.9 0:02.01 transmission-da

I'm also running sabnzbd,sickbeard,transmission and couchpotato each with its own user, so you will notice yours different.
The column that indicates the nice value is the one called NI. Notice that I give my downloads a low priority (10) than default (0) and Xbmc a higher one (-5).

Ionice
Harddrive access priority is divided in 3 scheduling classes:

-Realtime: Highest priority and subdivided in 8 priority levels with 0 being the highest one. Should be used with care as it can easily make your raspberry pi unresponsive.

-Best-effort:This is the default class, it's also subdivided in 8 levels same as Realtime. The priority level is dynamically adjusted according to the CPU priority (nice level) by the following formula: io_priority = (cpu_nice + 20) / 5.

-Idle: A process under this class only gets disk time when no other higher priority process is using it.

Changing startup priority
Now, this is how I have set it all up.
All download related processes have its priority set up at 10 so that they have a lower priority than default. Thanks to it, whenever I run another processes on my Raspberry Pi it gets more CPU, for example if I wish to run apt-get update the downloads would throttle down until it finishes.
The other way around for Xbmc, I have its priority set up at -5 so that it always has a little higher priority and it doesn't stutter if someone is using Xbmc while I'm running commands on the background.

If you want to keep it simple, you could just make Xbmc have a higher priority and leave the downloads at the default one, depending on your case that could prove enough, to do it you must change this file:
Terminal
xbian@Raspberry ~ $ sudo nano /etc/init.d/xbmc
Change this bit:
PHP Code:
do_start()
{
        if [ $(
ps -grep xbmc.bin wc -l) -eq 0 ]; then
                start
-stop-daemon -c xbian -u xbian --start --quiet --pidfile $
                echo $(
start-stop-daemon -c xbian -u xbian ---start --$
        
fi

Adding the option -N -5 to the start-stop-daemon:
PHP Code:
do_start()
{
        if [ $(
ps -grep xbmc.bin wc -l) -eq 0 ]; then
                start
-stop-daemon -c xbian -u xbian --start --quiet --pidfile $
                echo $(
start-stop-daemon ---c xbian -u xbian ---start --$
        
fi

That would change xbmc nice level to -5, and its ionice best-effort value to io_priority = (cpu_nice + 20) / 5=3, higher than the default value of 4.
To test that it works, restart the service:
Terminal
xbian@Raspberry ~ $ sudo service xbmc restart
and check with the top utility that its nice level has changed to -5.
If you want to also change its ionice level manually, just add this:
PHP Code:
do_start()
{
        if [ $(
ps -grep xbmc.bin wc -l) -eq 0 ]; then
                start
-stop-daemon -c xbian -u xbian --start --quiet --pidfile $
                echo $(
start-stop-daemon ---I best-effort:-c xbian -u xbian ---start --$
        
fi

That would also set best-effort scheduler with priority 2.

If that doesn't prove enough, lower downloads priority, you should do the same change for each process init script (sabnzbd, couchpotato, sickbeard, transmission...) note that only transmission and sabnzbd are I/O intensive, the other ones rely only on CPU.

Well, that's it! if somebody knows an easier way just tell it! This is the easiest I found, although I have done it different, all my download related processes are under the same group and I have set that groups default priority to 10 (modifying /etc/security/limits.conf) but it's a little bit more complicated and the only real advantage is that I can easily change all the priorities.

Here are a couple of links with more information regarding nice and ionice utilities.
http://www.nixtutor.com/linux/changing-priority-on-linux-processes/
http://man.he.net/man8/start-stop-daemon
http://linux.die.net/man/1/ionice

Sorry if I misspelled something, english is not my native language. Undecided
Thanks for this, I'm already doing something like this but in an other way, but this seems to be a better solution. Now I'm using scripts containing these kind of lines:
Code:
sudo nice -n 15 /etc/init.d/nzbget start >/dev/null 2>&1 &

To add info: You can also change the priority of existing processes using renice, for instance for changing the priority of samba:
Code:
sudo renice 10 `pgrep smbd`
sudo renice 10 `pgrep nmbd`

Also, I have been told that you have to run the following before these priorities will have any effect, don't know if this is (still) true.
Code:
sudo sysctl kernel.sched_autogroup_enabled=0
(13th May, 2013 11:17 PM)Fred Wrote: [ -> ]Thanks for this, I'm already doing something like this but in an other way, but this seems to be a better solution. Now I'm using scripts containing these kind of lines:
Code:
sudo nice -n 15 /etc/init.d/nzbget start >/dev/null 2>&1 &

To add info: You can also change the priority of existing processes using renice, for instance for changing the priority of samba:
Code:
sudo renice 10 `pgrep smbd`
sudo renice 10 `pgrep nmbd`

Also, I have been told that you have to run the following before these priorities will have any effect, don't know if this is (still) true.
Code:
sudo sysctl kernel.sched_autogroup_enabled=0

Without the kernel.sched_autogroup_enabled it wont work.If you want to work without problems and you need to resize the swap otherwise you got problems with out of memory closeups. (i have 512Mb for swap on my RPI 512).
Trinket thanks a lot for sharing this! I will figure out how to do this for Flexget: it runs every 3 hours via cron.
(14th May, 2013 11:10 PM)zilexa Wrote: [ -> ]Trinket thanks a lot for sharing this! I will figure out how to do this for Flexget: it runs every 3 hours via cron.

If you start it with cron, just add what Fred wrote to the cron command:
Code:
nice -n 15 /usr/bin/flexget [commands]...
If you just increase the nice value (15 for example) you won't need sudo, it's only needed if increasing priority.
Thanks! It's working Smile

Perhaps this should be changed in XBian by default for process XBMC and also for any application installed via XBian Config?
Trinket thanks a lot for sharing this! I will figure out how to do this for Flexget: it runs every 3 hours via cron???



___________________
waleeed
Reference URL's