Automatic system tuning daemon: tuned
=====================================
Concept:
--------
- Monitoring plugins for different sources (cpu, disk, network, sound, memory)
- Each monitoring plugin has a getLoad() method that returns a value between 0 - 100
- Tuning plugins for different targets (cpu, disk, network, sound,
memory etc) and modes (power or performance)
- Each plugin can set various weights for any monitoring source (0 - 100)
- Each tuning plugin has a setTuning(load) method
- Tuning will be based on accumulated load*weight for each target
Diagram:
--------
[Mon-P] [Mon-P] [Mon-P]
\ | /
\ | /
\ | /
\ | /
\ | /
[tuned]
/ | \
/ | \
/ | \
/ | \
/ | \
[Tune-P] [Tune-P] [Tune-P]
tuned:
-------
- Is the main interface and aggregator
- Acts as a "middleware"
- Only general functionality. Specific hw/mon functionality only in plugins
- Has a list of all mon and pm plugins
- Monitoring interval is configurable (1 wakeup per interval to reduce # of
wakeups)
- Weights for each Mon can be set for each Tune plugin
- Default weight is 0
- Aggreated load: mon-p.getLoad() * tune-p.weights[mon-p] / 100. If all weights
together are 100 then this will be a balanced and normalized load
- Accumulated weights per tune plugin can be > 100 or < 100. Need to decide
whether to automatically normalize it or not
/* - Tuning aggressivness can be specified from 0 to 100. 0 == no PM, 100 means
always fully tune even under full load. Configurable globally for all tuning
plugins and/or individually */
- Tuning modes should follow the system/user settings for power management of
the currently running GUI (e.g. presentation mode etc)
- all fooLoad() methods always return a hash like this: {cat -> {devname -> {subcat = load}}}
to support multiple devices per monitor (e.g. disks, network cards)
- Optional parameters for fooLoad() calls: category, subcategory and devname
- Each plugin can be completely disabled.
- External interfaces to allow requests for monitoring applications
Monitor plugins:
----------------
- Monitor plugins can be based on any source. E.g. collectd or stap scripts
- Each plugins needs to register to tuned via registerMonitorPlugin()
- Each plugins has it's own configuration. Only external interface to tuned
is getLoad() (which returns a list of tuples, see tuned)
- Each plugin needs to be in a specific category
- Examples of categories that can be monitored:
o CPU
o Disk IO
o Network IO
o Memory IO
o USB
o Graphics
o External input (keyboard/mouse)
- Subcategories possible:
o Input
o Output
o Blocksize
- Should avoid disk/network io to prevent unecessary wakeups
Tuning plugins:
---------------
- Tuning plugins will be HW specific
- Each plugins needs to register to tuned via registerTuningPlugin()
- Blacklists for know problems with HW
- There are 2 types of tuning plugins:
o Power
o Performance
- Each plugin has to define it's own policy for handling the different
levels of aggregated load
- Each plugin has an interface called setTuning(load) where load is the aggreated
load for that tuning plugin modified by the specific or overall level of
tuning aggressiveness
- Several levels of aggressiveness: none, low, medium, high, max
- Parts that can be tuned:
o CPU
o Disk IO
o Network IO
o Memory IO
o USB
o Graphics
o External input (keyboard/mouse)
Example:
--------
monitoring plugin for disk io: Montiors either via /proc or other means the IO
for all disks in the system.
getLoad() returns something like: {"DISK" : {"sda" : {"READ" : 0.24, "WRITE" :
0.01, "SIZE" : 0.31}}}
This means that sda would be at 24% of it's known peak load in regard to
reads, at 1% in regard to writes and at 31% in regard to blocksizes.
Based on that information a tuning plugin for disk io could now decide to do
the following:
load = tuned.getLoad("DISK")
for devnames in load["DISK"].keys():
devnode = load["DISK"][devname]
# Spin down after 30s and max powersave if device isn't in use
if (devnode["WRITE"] == 0.0 and devnode["READ"] == 0.0) {
hdparm -S5 /dev/devname
hdparm -B1 /dev/devname
# If no write and little reads: Allow drive to spin down after 5m
# and max powersave.
} elseif (devnode["WRITE"] == 0.0 and devnode["READ"] <= 0.05) {
hdparm -S60 /dev/devname
hdparm -B1 /dev/devname
# If write are done or more reads don't allow disk to spindown
# and raise powersave mode to medium range
} else {
hdparm -S0 /dev/devname
hdparm -B128 /dev/devname
}