I am surprised at how many people complain about IO responsiveness while multitasking, but have never heard of ionice(1). Most intermediate-level Linux users have heard of, or know how to use, the nice command. Well, ionice is like nice for the disk (nice on most Linux kernels only affects the CPU scheduler. So, a large copy operation with the maximum niceness can still ruin disk response times to a process on highest priority.)
The best usecase for using ionice to improve performance is when you need to do two classes of tasks at once: The ones that don’t use much disk IO but demand fast response, and the ones that do a LOT of disk IO but don’t need it done urgently.
For example, think of some of the time-consuming things you want to do in the background, like:
- Downloading a torrent on a fast internet link that creates a great deal of disk seeking.
- Copy a huge file between two locations
- Perform a system backup
- Install your latest set up system updates
Most of the time, you really don’t care how fast (within reason) these tasks take, as long as your desktop applications don’t lag like hell! This is where ionice comes to the rescue. You can, in effect, tell Linux to only give disk access to these programs when nothing else wants it.
The command for doing this is sudo ionice -c3 -ppid, where pid is the numeric Process ID of the task you want to reschedule. You can find this number by looking at your GNOME or KDE process list viewer (also called System Monitor), or via top, ps -aux, and other command line tools. The -c3 part places the process in the idle scheduling class. You can read the ionice(1) man page for more cool things you can do with ionice.
Now, one trick you might find handy is rescheduling an entire parent shell to idle class, so that all commands executed from that shell are idle priority. You can get this from the $$ shell variable in bash and sh. For example:
jdong@severance:~$ echo $$
This output means that my current bash shell is process id 29033. If I want to switch the whole shell to idle disk priority, I would run:
jdong@severance:~$ sudo ionice -c3 -p$$
And there we go! Everything I do in this shell is now idle priority. Let’s apply this trick to other case. Ubuntu and other distributions like to run disk-intensive scripts like updatedb every night at midnight. If you’re a night owl like me and use your computer at these hours, this can be terribly irritating. Well, ionice to the rescue! Open up /etc/cron.daily/slocate, and add the following bolded line:
ionice -c3 -p$$
if [ -x /usr/bin/slocate ]
And now, updatedb will no longer lag your productive midnight computing activities!
Now of course, there are a couple gotchas with ionice:
- It only works on kernels 2.6.13 and later using the CFQ IO scheduler. Kernels 2.6.17 (Ubuntu Edgy) and later, plus most versions of Redhat/Fedora-based distributions , will use the CFQ IO scheduler by default. You can check what scheduler is running by running cat /sys/block/[sh]d[a-z]*/queue/scheduler. The word outlined in [brackets] is currently selected. Use the boot parameter elevator=cfq in grub/menu.lst to set cfq as default.
- Idle priority is VERY cautious about marking block devices idle. If your foreground tasks are using disk, then your background tasks will become noticeably slower, as they get blocked from touching the disks until Linux knows for sure your foreground tasks have all had a chance at the disk. Most of the times, you don’t care about this anyway, but don’t run a torrent in non-idle class and expect a 20GB copy to finish till the torrent’s done!
- Please be careful fooling around with other ionice options, particularly the realtime class. You can easily set a process to receive the disk’s full attention and freeze your system. I’m not responsible for any hard reboots you have due to this.
- Some filesystems, particularly reiserfs and XFS, are very unfriendly at hogging the disk while performing metadata operations (such as creating or deleting files). Even ionice may not save you from noticeable disk IO lag during heavy metadata activities.