Cgroups are the generalized feature for grouping tasks. The actual resource tracking and limits are implemented by subsystems. A hierarchy is a set of subsystems mounted together. For instance, if the memory and devices subsystems are mounted together under /sys/fs/cgroups/set1, then any task which is in "/child1" will be subject to the corresponding limits of both subsystems.
Each set of mounted subsystems consittutes a 'hierarchy'. With exceptions, cgroups which are children of "/child1" will be subject to all limits placed on "/child1", and their resource usage will be accounted to "/child1".
The existing subsystems include:
cpusets: fascilitate assigning a set of CPUS and memory nodes to cgroups. Tasks in a cpuset cgroup may only be scheduled on CPUS assigned to that cpuset.
blkio : limits per-cgroup block io.
cpuacct : provides per-cgroup cpu usage accounting.
devices : controls the ability of tasks to create or use devices nodes using either a blacklist or whitelist.
freezer : provides a way to 'freeze' and 'thaw' whole cgroups. Tasks in the cgroup will not be scheduled while they are frozen.
hugetlb : fascilitates limiting hugetlb usage per cgroup.
memory : allows memory, kernel memory, and swap usage to be tracked and limited.
net_cls : provides an interface for tagging packets based on the sender cgroup. These tags can then be used by tc (traffic controller) to assign priorities.
net_prio : allows setting network traffic priority on a per-cgroup basis.
cpu : enables setting of scheduling preferences on per-cgroup basis.
perf_event : enables per-cpu mode to monitor only threads in certain cgroups.
In addition, named cgroups can be created with no bound subsystems for the sake of process tracking. As an example, systemd does this to track services and user sessions.