cgroups: add res_counter_write_u64() API

Extend the resource counter API with a mirror of res_counter_read_u64() to
make it handy to update a resource counter value from a cgroup subsystem
u64 value file.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Wenzhang <wenzhang.zzy@alibaba-inc.com>
Reviewed-by: Zhi Yong Wu <zhiyong.wzy@alibaba-inc.com>
cgroups: new resource counter inheritance API

Provide an API to inherit a counter value from a parent.  This can be
useful to implement cgroup.clone_children on a resource counter.

Still the resources of the children are limited by those of the parent, so
this is only to provide a default setting behaviour when clone_children is
set.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Wenzhang <wenzhang.zzy@alibaba-inc.com>
Reviewed-by: Zhi Yong Wu <zhiyong.wzy@alibaba-inc.com>
cgroups: ability to stop res charge propagation on bounded ancestor

Moving a task from a cgroup to another may require to substract its
resource charge from the old cgroup and add it to the new one.

For this to happen, the uncharge/charge propagation can just stop when we
reach the common ancestor for the two cgroups.  Further the performance
reasons, we also want to avoid to temporarily overload the common
ancestors with a non-accurate resource counter usage if we charge first
the new cgroup and uncharge the old one thereafter.  This is going to be a
requirement for the coming kcounter subsystem.

To solve this, provide a pair of new API that can charge/uncharge a
resource counter until we reach a given ancestor.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Wenzhang <wenzhang.zzy@alibaba-inc.com>
Reviewed-by: Zhi Yong Wu <zhiyong.wzy@alibaba-inc.com>
cgroups: add res counter common ancestor searching

Add a new API to find the common ancestor between two resource counters.
This includes the passed resource counter themselves.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Wenzhang <wenzhang.zzy@alibaba-inc.com>
Reviewed-by: Zhi Yong Wu <zhiyong.wzy@alibaba-inc.com>
res_counter: allow charge failure pointer to be null

So that callers of res_counter_charge() don't have to create and pass this
pointer even if they aren't interested in it.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Wenzhang <wenzhang.zzy@alibaba-inc.com>
Reviewed-by: Zhi Yong Wu <zhiyong.wzy@alibaba-inc.com>
cgroups: pull up res counter charge failure interpretation to caller

res_counter_charge() always returns -ENOMEM when the limit is reached and
the charge thus can't happen.

However it's up to the caller to interpret this failure and return the
appropriate error value.  The nproc counter of kcounter subsystem will need to
report the user that a fork() has been cancelled because of some limit reached,
not because we are too short on memory.

Fix this by returning -1 when res_counter_charge() fails.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Wenzhang <wenzhang.zzy@alibaba-inc.com>
Reviewed-by: Zhi Yong Wu <zhiyong.wzy@alibaba-inc.com>
cgroups: allow subsystems to cancel a fork

Let the subsystem's fork callback return an error value so that they can cancel
a fork.  This is going to be used by the kcounter subsystem to implement the
nproc limit.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Wenzhang <wenzhang.zzy@alibaba-inc.com>
Reviewed-by: Zhi Yong Wu <zhiyong.wzy@alibaba-inc.com>
cgroups: Add a kcounter subsystem

Add a new subsystem to limit usage of various types of resource
for a cgroup, by enforcing a upper bound upon the corresponding
resource counter. It behaves like the counterpart of user land
ulimit in the scope of a cgroup.

Currently nproc counter is the only consumer of kcounter
framework. For nproc counter, the user can set an upper bound
limit that is checked every time a task forks in a cgroup or is
moved into a cgroup with that subsystem binded.

The primary goal is to protect against forkbombs that explode
inside a container. The traditional NR_PROC rlimit is not
efficient in that case because if we run containers in parallel
under the same user, one of these could starve all the others
by spawning a high number of tasks close to the user wide limit.

This is a prevention against forkbombs, so it's not deemed to
cure the effects of a forkbomb when the system is in a state
where it's not responsive. It's aimed at preventing from ever
reaching that state and stop the spreading of tasks early.
While defining the limit on the allowed number of tasks, it's
up to the user to find the right balance between the resource
its containers may need and what it can afford to provide.

As it's totally dissociated from the rlimit NR_PROC, both
can be complementary: the cgroup nproc counter can set an upper
bound per container and the rlmit can be an upper bound on the
overall set of containers.

Also nproc counter can be used to kill all the tasks in a cgroup
without races against concurrent forks, by setting the limit of
tasks to 0, any further forks can be rejected. This is a good
way to kill a forkbomb in a container, or simply kill any container
without the need to retry an unbound number of times.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Wenzhang <wenzhang.zzy@alibaba-inc.com>
Reviewed-by: Zhi Yong Wu <zhiyong.wzy@alibaba-inc.com>
Merge pull request #64 from danielzhou82/ai-kcounter

Add kcounter cgroup subsys