With control groups (cgroups) you can achieve resource isolation for:
When two or more processes might use too much of a resource so the other ones will not get a fair chance, you can use cgroups to tell them: if you fight for the same resource one of you can not get more than 60% and other one no more than 30% and so on. If there is no race for the same resource, we have a single requester. He can use how much he wants until another process will try to use it.
Examples of I/O Throttling
Introduction to Linux Control Groups
Regarding scaling up when the machine is idle: if you use Completely Fair Scheduler (CFS), a cgroup can get more of the allocated CPU share if there are enough idle CPU cycles available in the system.
Redhat resource management guide:
When tasks in one cgroup are idle and are not using any CPU time, this
left-over time is collected in a global pool of unused CPU cycles.
Other cgroups are allowed to borrow CPU cycles from this pool
cpusets.txt documentation
And if a CPU run out of tasks in its runqueue, the CPU try to pull
extra tasks from other busy CPUs to help them before it is going to be
idle.
Of course it takes some searching cost to find movable tasks and/or
idle CPUs, the scheduler might not search all CPUs in the domain every
time. In fact, in some architectures, the searching ranges on events
are limited in the same socket or node where the CPU locates, while
the load balance on tick searches all.
For example, assume CPU Z is relatively far from CPU X. Even if CPU Z
is idle while CPU X and the siblings are busy, scheduler can't migrate
woken task B from X to Z since it is out of its searching range. As
the result, task B on CPU X need to wait task A or wait load balance
on the next tick. For some applications in special situation, waiting
1 tick may be too long.
Few other methods to achieve resource isolation: nice
(used for easy tweaks), cpulimit
- static resource allocation, when other CPUs are idle, shares are not borrowed to other processes.