CFS Hard limits - v1
Subsystems (2)
cover CFS Hard limits - v1
Hi,
RFC on Hard limits feature for CFS group scheduler was posted earlier at
http://lkml.org/lkml/2009/6/4/24. This is the next RFC post with patches.
During the previous post, the need for hard limits feature was acknowledged. Also it was mentioned that guarantees would also be desirable. This post just addresses the limits part and there is no intention to address the guarantees problem with this patchset.
This patchset has seen some very light testing and I believe that there will be bugs in it. However if you feel brave enough, this patchset could be tried on 2.6.31-rc7!
Features TODO
-------------
- Runtime borrowing isn't implemented yet, plan to add it in subsequent posts.
- Bandwidth inheritence support (long term, not under consideration currently)
- This implementation doesn't work for user group scheduler. Since user group scheduler will eventually go away, I don't plan to work on this.
Implementation TODO
-------------------
- This patchset has seen very minimal testing. I need to test this under more test scenarios.
- I have been testing this on a 8 CPU box. Need to see how this behaves on a bigger box.
- Need to run performance tests and regression tests for benchmarks on bigger machines.
- It is possible to share some of the bandwidth handling code with RT, but the intention of this post is to show the changes associated with hard limits. Hence the sharing/cleanup will be done down the line when this patchset itself becomes more accepatable.
- When a dequeued entity is enqueued back, I don't change its vruntime. The entity might get undue advantage due to its old (lower) vruntime. Need to address this.
This set has the following patches:
1/7 sched: Rename sched_rt_period_mask() and use it in CFS also 2/7 sched: Maintain aggregated tasks count in cfs_rq at each hierarchy level 3/7 sched: Bandwidth initialization for fair task groups
4/7 sched: Enforce hard limits by throttling
5/7 sched: Unthrottle the throttled tasks
6/7 sched: Add throttle time statistics to /proc/sched_debug
7/7 sched: Hard limits documentation
Documentation/scheduler/sched-cfs-hard-limits.txt | 52 +++ include/linux/sched.h | 7 init/Kconfig | 13 kernel/sched.c | 346 +++++++++++++++++++- kernel/sched_debug.c | 21 + kernel/sched_fair.c | 268 +++++++++++++++ kernel/sched_rt.c | 19 - 7 files changed, 703 insertions(+), 23 deletions(-)
Regards,
Bharata.
RFC PATCH 1/7 1/7 sched: Rename sched_rt_period_mask() and use it in CFS also
sched: Rename sched_rt_period_mask() and use it in CFS also.
From: Bharata B Rao <[email protected]>
sched_rt_period_mask() is needed in CFS also. Rename it to a generic name and move it to kernel/sched.c. No functionality change in this patch.
--- kernel/sched.c | 23 +++++++++++++++++++++++ kernel/sched_rt.c | 19 +------------------ 2 files changed, 24 insertions(+), 18 deletions(-)
kernel/sched.c +23 -0
@@ -1732,6 +1732,29 @@ static void cfs_rq_set_shares(struct cfsstatic void calc_load_account_active (struct rq *this_rq); + +#if defined(CONFIG_RT_GROUP_SCHED ) || defined(CONFIG_FAIR_GROUP_SCHED ) + +#ifdef CONFIG_SMP +static inline const struct cpumask *sched_bw_period_mask (void ) +{ +return cpu_rq (smp_processor_id ())->rd->span; +} +#else /* !CONFIG_SMP */ +static inline const struct cpumask *sched_bw_period_mask (void ) +{ +return cpu_online_mask; +} +#endif /* CONFIG_SMP */ + +#else +static inline const struct cpumask *sched_bw_period_mask (void ) +{ +return cpu_online_mask; +} + +#endif +#include "sched_stats.h" #include "sched_idletask.c" #include "sched_fair.c"
kernel/sched_rt.c +1 -18
@@ -222,18 +222,6 @@ static int rt_se_boosted(struct sched_rtreturn p->prio != p->normal_prio; } -#ifdef CONFIG_SMP -static inline const struct cpumask *sched_rt_period_mask (void ) -{ -return cpu_rq (smp_processor_id ())->rd->span; -} -#else -static inline const struct cpumask *sched_rt_period_mask (void ) -{ -return cpu_online_mask; -} -#endif -static inline struct rt_rq *sched_rt_period_rt_rq (struct rt_bandwidth *rt_b,int cpu) {
@@ -283,11 +271,6 @@ static inline int rt_rq_throttled(structreturn rt_rq->rt_throttled; } -static inline const struct cpumask *sched_rt_period_mask (void ) -{ -return cpu_online_mask; -} -static inline struct rt_rq *sched_rt_period_rt_rq (struct rt_bandwidth *rt_b,int cpu) {
@@ -505,7 +488,7 @@ static int do_sched_rt_period_timer(struif (!rt_bandwidth_enabled () || rt_b->rt_runtime ==RUNTIME_INF )return 1 ; - span =sched_rt_period_mask (); + span =sched_bw_period_mask ();for_each_cpu (i, span) {int enqueue =0 ;struct rt_rq *rt_rq =sched_rt_period_rt_rq (rt_b, i);
RFC PATCH 2/7 sched: Maintain aggregated tasks count in cfs_rq at each hierarchy level
In reply to Bharata B Raosched: Maintain aggregated tasks count in cfs_rq at each hierarchy level
From: Bharata B Rao <[email protected]>
This patch adds a counter to cfs_rq (->nr_tasks_running) to record the aggregated tasks count at each level in the task group hierarchy. This is needed by later hard limit patches where it is required to know how many tasks go off the rq when a throttled group entity is dequeued.
--- kernel/sched.c | 4 ++++ kernel/sched_debug.c | 2 ++ kernel/sched_fair.c | 23 +++++++++++++++++++++++ 3 files changed, 29 insertions(+)
kernel/sched.c +4 -0
@@ -477,6 +477,10 @@ struct cfs_rq {unsigned long rq_weight;#endif #endif +/* +* Number of tasks at this heirarchy. +*/ +unsigned long nr_tasks_running; };/* Real-Time classes' related field in a runqueue: */
kernel/sched_debug.c +2 -0
@@ -214,6 +214,8 @@ void print_cfs_rq(struct seq_file *m, in#ifdef CONFIG_SMP SEQ_printf (m," .%-30s: %lu\n" ,"shares" , cfs_rq->shares);#endif +SEQ_printf (m," .%-30s: %ld\n" ,"nr_tasks_running" , + cfs_rq->nr_tasks_running);print_cfs_group_stats (m, cpu, cfs_rq->tg);#endif }
kernel/sched_fair.c +23 -0
@@ -243,6 +243,27 @@ find_matching_se(struct sched_entity **s#endif /* CONFIG_FAIR_GROUP_SCHED */ +static void add_cfs_rq_tasks_running (struct sched_entity *se, +unsigned long count) +{ +struct cfs_rq *cfs_rq; + +for_each_sched_entity (se) { + cfs_rq =cfs_rq_of (se); + cfs_rq->nr_tasks_running += count; + } +} + +static void sub_cfs_rq_tasks_running (struct sched_entity *se, +unsigned long count) +{ +struct cfs_rq *cfs_rq; + +for_each_sched_entity (se) { + cfs_rq =cfs_rq_of (se); + cfs_rq->nr_tasks_running -= count; + } +}/************************************************************** * Scheduling class tree data structure manipulation methods:
@@ -969,6 +990,7 @@ static void enqueue_task_fair(struct rq wakeup =1 ; } +add_cfs_rq_tasks_running (&p->se,1 );hrtick_update (rq); }
@@ -991,6 +1013,7 @@ static void dequeue_task_fair(struct rq sleep =1 ; } +sub_cfs_rq_tasks_running (&p->se,1 );hrtick_update (rq); }
RFC PATCH 3/7 sched: Bandwidth initialization for fair task groups
In reply to Bharata B Raosched: Bandwidth initialization for fair task groups.
From: Bharata B Rao <[email protected]>
Introduce the notion of hard limiting for CFS groups by bringing in the concept of runtime and period for them. Add cgroup files to control runtime and period.
--- init/Kconfig | 13 ++ kernel/sched.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 292 insertions(+)
init/Kconfig +13 -0
@@ -456,6 +456,19 @@ config FAIR_GROUP_SCHED depends on GROUP_SCHED default GROUP_SCHED +config CFS_HARD_LIMITS + bool "Hard Limits for CFS Group Scheduler" + depends on EXPERIMENTAL + depends on FAIR_GROUP_SCHED + default n + help + This option enables hard limiting of CPU time obtained by + a fair task group. Use this if you want to throttle a group of tasks + based on its CPU usage. For more details refer to + Documentation/scheduler/sched-cfs-hard-limits.txt + + Say N if unsure. + config RT_GROUP_SCHED bool "Group scheduling for SCHED_RR/FIFO" depends on EXPERIMENTAL
kernel/sched.c +279 -0
339 lines not on this page · raw message
Re: [RFC v1 PATCH 3/7] sched: Bandwidth initialization for fair task groups
Review
Quoted 4 lines · Bharata B Rao
(quoted diff) +4
-0+config CFS_HARD_LIMITS + bool "Hard Limits for CFS Group Scheduler" + depends on EXPERIMENTAL + depends on FAIR_GROUP_SCHED
Shouldn't depend also on CGROUPS and CGROUP_SCHED? without them hard limits can't be defined, right?
--- init/Kconfig | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
init/Kconfig +1 -1
@@ -459,7 +459,7 @@ config FAIR_GROUP_SCHED config CFS_HARD_LIMITS bool "Hard Limits for CFS Group Scheduler" depends on EXPERIMENTAL - depends on FAIR_GROUP_SCHED + depends on FAIR_GROUP_SCHED && CGROUPS && CGROUP_SCHED default n help This option enables hard limiting of CPU time obtained by
Re: [RFC v1 PATCH 3/7] sched: Bandwidth initialization for fair task groups
Quoted 8 lines · Andrea Righi
Review
Quoted 4 lines · Bharata B Rao
(quoted diff) +4
-0+config CFS_HARD_LIMITS + bool "Hard Limits for CFS Group Scheduler" + depends on EXPERIMENTAL + depends on FAIR_GROUP_SCHEDShouldn't depend also on CGROUPS and
CGROUP_SCHED? without them hard limits can't be defined, right?
Right, but do we need to explicitly mention CGROUPS as dependency since CGROUP_SCHED is already dependent on it ?
Quoted 11 lines
Signed-off-by Andrea Righi <[email protected]>--- init/Kconfig | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)init/Kconfig +0
-0
init/Kconfig config FAIR_GROUP_SCHED · line 465
Quoted 8 lines
init/Kconfig +1
-1@@ -459,7 +459,7 @@ config FAIR_GROUP_SCHED config CFS_HARD_LIMITS bool "Hard Limits for CFS Group Scheduler" depends on EXPERIMENTAL - depends on FAIR_GROUP_SCHED + depends on FAIR_GROUP_SCHED && CGROUPS && CGROUP_SCHED default n help This option enables hard limiting of CPU time obtained by
Thanks for looking at the patches.
Regards,
Bharata.
Re: [RFC v1 PATCH 3/7] sched: Bandwidth initialization for fair task groups
Quoted 10 lines · Bharata B Rao
Quoted 8 lines · Andrea Righi
Review
Quoted 4 lines · Bharata B Rao
(quoted diff) +4
-0+config CFS_HARD_LIMITS + bool "Hard Limits for CFS Group Scheduler" + depends on EXPERIMENTAL + depends on FAIR_GROUP_SCHEDShouldn't depend also on CGROUPS and
CGROUP_SCHED? without them hard limits can't be defined, right?
Quoted 2 lines
Right, but do we need to explicitly mention CGROUPS as dependency since
CGROUP_SCHEDis already dependent on it ?
Correct, CGROUP_SCHED is enough.
Thanks,
-Andrea
Signature · 2 lines
Andrea Righi - Develer s.r.l http://www.develer.com
RFC PATCH 4/7 sched: Enforce hard limits by throttling
In reply to Bharata B Raosched: Enforce hard limits by throttling.
From: Bharata B Rao <[email protected]>
Throttle the task-groups which exceed the runtime allocated to them. Throttled group entities are removed from the run queue.
--- include/linux/sched.h | 1 kernel/sched.c | 32 ++++++++++ kernel/sched_debug.c | 2 kernel/sched_fair.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 177 insertions(+), 4 deletions(-)
include/linux/sched.h +1 -0
@@ -1124,6 +1124,7 @@ struct sched_entity {u64 nr_failed_migrations_affine;u64 nr_failed_migrations_running;u64 nr_failed_migrations_hot; +u64 nr_failed_migrations_throttled;u64 nr_forced_migrations;u64 nr_forced2_migrations;
kernel/sched.c +31 -1
@@ -1580,6 +1580,7 @@ update_group_shares_cpu(struct task_grou } } +static inline int cfs_rq_throttled (struct cfs_rq *cfs_rq);/* * Re-compute the task group their per cpu shares over the given domain. * This needs to be done in a bottom-up fashion because the rq weight of a
@@ -1597,9 +1598,11 @@ static int tg_shares_up(struct task_grou* If there are currently no tasks on the cpu pretend there * is one of average load so that when a new task gets to * run here it will not get delayed by group starvation. +* Also if the group is throttled on this cpu, pretend that +* it has no tasks. */ weight = tg->cfs_rq[i]->load.weight; -if (!weight) +if (!weight ||cfs_rq_throttled (tg->cfs_rq[i])) weight =NICE_0_LOAD ; tg->cfs_rq[i]->rq_weight = weight;
@@ -1623,6 +1626,7 @@ static int tg_shares_up(struct task_grou* Compute the cpu's hierarchical load factor for each task group. * This needs to be done in a top-down fashion because the load of a child * group is a fraction of its parents load. +* A throttled group's h_load is set to 0. */ static int tg_load_down (struct task_group *tg,void *data) {
@@ -1631,6 +1635,8 @@ static int tg_load_down(struct task_grouif (!tg->parent) { load =cpu_rq (cpu)->load.weight; + }else if (cfs_rq_throttled (tg->cfs_rq[cpu])) { + load =0 ; }else { load = tg->parent->cfs_rq[cpu]->h_load; load *= tg->cfs_rq[cpu]->shares;
@@ -1808,6 +1814,8 @@ static inline u64 global_cfs_runtime(voireturn RUNTIME_INF ; } +int task_group_throttled (struct task_group *tg,int cpu); +static inline int cfs_bandwidth_enabled (struct task_group *tg) {return tg->hard_limit_enabled;
@@ -1892,7 +1900,18 @@ static void init_cfs_hard_limits(structreturn ; } +int task_group_throttled (struct task_group *tg,int cpu) +{ +return 0 ; +} +#endif /* CONFIG_CFS_HARD_LIMITS */ + +#else /* CONFIG_FAIR_GROUP_SCHED */ +int task_group_throttled (struct task_group *tg,int cpu) +{ +return 0 ; +}#endif /* CONFIG_FAIR_GROUP_SCHED */ #include "sched_stats.h"
@@ -3364,6 +3383,7 @@ int can_migrate_task(struct task_struct* 1) running (obviously), or * 2) cannot be migrated to this CPU due to cpus_allowed, or * 3) are cache-hot on their current CPU. +* 4) end up in throttled task groups on this CPU. */ if (!cpumask_test_cpu (this_cpu, &p->cpus_allowed)) {schedstat_inc (p, se.nr_failed_migrations_affine);
@@ -3377,6 +3397,16 @@ int can_migrate_task(struct task_struct }/* +* Don't migrate the task if +* - it belongs to a group which is throttled on this_cpu or +* - it belongs to a group whose hierarchy is throttled on this_cpu +*/ +if (task_group_throttled (task_group (p), this_cpu)) { +schedstat_inc (p, se.nr_failed_migrations_throttled); +return 0 ; + } + +/* * Aggressive migration if: * 1) task is cache cold, or * 2) too many balance attempts have failed.
kernel/sched_debug.c +2 -0
@@ -417,6 +417,7 @@ void proc_sched_show_task(struct task_stP (se.nr_failed_migrations_affine);P (se.nr_failed_migrations_running);P (se.nr_failed_migrations_hot); +P (se.nr_failed_migrations_throttled);P (se.nr_forced_migrations);P (se.nr_forced2_migrations);P (se.nr_wakeups);
@@ -491,6 +492,7 @@ void proc_sched_set_task(struct task_str p->se.nr_failed_migrations_affine =0 ; p->se.nr_failed_migrations_running =0 ; p->se.nr_failed_migrations_hot =0 ; + p->se.nr_failed_migrations_throttled =0 ; p->se.nr_forced_migrations =0 ; p->se.nr_forced2_migrations =0 ; p->se.nr_wakeups =0 ;
kernel/sched_fair.c +143 -3
197 lines not on this page · raw message
RFC PATCH 5/7 sched: Unthrottle the throttled tasks
In reply to Bharata B Raosched: Unthrottle the throttled tasks.
From: Bharata B Rao <[email protected]>
Refresh runtimes when group's bandwidth period expires. Unthrottle any throttled groups at that time. Refreshing runtimes is driven through a periodic timer.
--- kernel/sched.c | 8 +++++ kernel/sched_fair.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+)
kernel/sched.c +8 -0
@@ -1815,6 +1815,7 @@ static inline u64 global_cfs_runtime(voi }int task_group_throttled (struct task_group *tg,int cpu); +void do_sched_cfs_period_timer (struct cfs_bandwidth *cfs_b);static inline int cfs_bandwidth_enabled (struct task_group *tg) {
@@ -1830,6 +1831,7 @@ static enum hrtimer_restart sched_cfs_pestruct cfs_bandwidth *cfs_b = container_of(timer, struct cfs_bandwidth, cfs_period_timer); +do_sched_cfs_period_timer (cfs_b);hrtimer_add_expires_ns (timer,ktime_to_ns (cfs_b->cfs_period));return HRTIMER_RESTART ; }
@@ -10536,6 +10538,12 @@ int tg_set_hard_limit_enabled(struct tasstart_cfs_bandwidth (tg); }else {destroy_cfs_bandwidth (tg); +/* +* Hard limiting is being disabled for this group. +* Refresh runtimes and put the throttled entities +* of the group back onto runqueue. +*/ +do_sched_cfs_period_timer (&tg->cfs_bandwidth); tg->hard_limit_enabled =0 ; }spin_unlock_irq (&tg->cfs_bandwidth.cfs_runtime_lock);
kernel/sched_fair.c +79 -0
91 lines not on this page · raw message
RFC PATCH 6/7 sched: Add throttle time statistics to /proc/sched_debug
In reply to Bharata B Raosched: Add throttle time statistics to /proc/sched_debug
From: Bharata B Rao <[email protected]>
With hard limits, provide stats about throttle time, throttle count and max throttle time for group sched entities in /proc/sched_debug Throttle stats are collected only for group entities.
--- include/linux/sched.h | 6 ++++++ kernel/sched_debug.c | 17 ++++++++++++++++- kernel/sched_fair.c | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-)
include/linux/sched.h +6 -0
@@ -1137,6 +1137,12 @@ struct sched_entity {u64 nr_wakeups_affine_attempts;u64 nr_wakeups_passive;u64 nr_wakeups_idle; +#ifdef CONFIG_CFS_HARD_LIMITS +u64 throttle_start; +u64 throttle_max; +u64 throttle_count; +u64 throttle_sum; +#endif #endif #ifdef CONFIG_FAIR_GROUP_SCHED
kernel/sched_debug.c +16 -1
@@ -80,6 +80,11 @@ static void print_cfs_group_stats(structPN (se->wait_max);PN (se->wait_sum);P (se->wait_count); +#ifdef CONFIG_CFS_HARD_LIMITS +PN (se->throttle_max); +PN (se->throttle_sum); +P (se->throttle_count); +#endif #endif P (se->load.weight);#undef PN
@@ -216,6 +221,16 @@ void print_cfs_rq(struct seq_file *m, in#endif SEQ_printf (m," .%-30s: %ld\n" ,"nr_tasks_running" , cfs_rq->nr_tasks_running); +#ifdef CONFIG_CFS_HARD_LIMITS +spin_lock_irqsave (&rq->lock, flags); +SEQ_printf (m," .%-30s: %d\n" ,"cfs_throttled" , + cfs_rq->cfs_throttled); +SEQ_printf (m," .%-30s: %Ld.%06ld\n" ,"cfs_time" , +SPLIT_NS (cfs_rq->cfs_time)); +SEQ_printf (m," .%-30s: %Ld.%06ld\n" ,"cfs_runtime" , +SPLIT_NS (cfs_rq->cfs_runtime)); +spin_unlock_irqrestore (&rq->lock, flags); +#endif print_cfs_group_stats (m, cpu, cfs_rq->tg);#endif }
@@ -312,7 +327,7 @@ static int sched_debug_show(struct seq_fu64 now =ktime_to_ns (ktime_get ());int cpu; -SEQ_printf (m,"Sched Debug Version: v0.09, %s %.*s\n" , +SEQ_printf (m,"Sched Debug Version: v0.10, %s %.*s\n" ,init_utsname ()->release, (int )strcspn (init_utsname ()->version," " ),init_utsname ()->version);
kernel/sched_fair.c +20 -0
@@ -188,6 +188,23 @@ find_matching_se(struct sched_entity **s#ifdef CONFIG_CFS_HARD_LIMITS +static inline void update_stats_throttle_start (struct cfs_rq *cfs_rq, +struct sched_entity *se) +{ +schedstat_set (se->throttle_start,rq_of (cfs_rq)->clock); +} + +static inline void update_stats_throttle_end (struct cfs_rq *cfs_rq, +struct sched_entity *se) +{ +schedstat_set (se->throttle_max,max (se->throttle_max, +rq_of (cfs_rq)->clock - se->throttle_start)); +schedstat_set (se->throttle_count, se->throttle_count +1 ); +schedstat_set (se->throttle_sum, se->throttle_sum + +rq_of (cfs_rq)->clock - se->throttle_start); +schedstat_set (se->throttle_start,0 ); +} +static inline int cfs_rq_throttled (struct cfs_rq *cfs_rq) {return cfs_rq->cfs_throttled;
@@ -217,6 +234,7 @@ static void sched_cfs_runtime_exceeded(sif (cfs_rq->cfs_time > cfs_rq->cfs_runtime) { cfs_rq->cfs_throttled =1 ; +update_stats_throttle_start (cfs_rq, se);resched_task (tsk_curr); } }
@@ -314,6 +332,8 @@ void do_sched_cfs_period_timer(struct cfspin_lock_irqsave (&rq->lock, flags); cfs_rq->cfs_time =0 ;if (cfs_rq_throttled (cfs_rq)) { +update_rq_clock (rq); +update_stats_throttle_end (cfs_rq, se); cfs_rq->cfs_throttled =0 ;enqueue_throttled_entity (rq, se); }
RFC PATCH 7/7 sched: Hard limits documentation
In reply to Bharata B Raosched: Hard limits documentation
From: Bharata B Rao <[email protected]>
Documentation for hard limits feature.
--- Documentation/scheduler/sched-cfs-hard-limits.txt | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/scheduler/sched-cfs-hard-limits.txt
Documentation/scheduler/sched-cfs-hard-limits.txt new file +52 -0
@@ -0,0 +1,52 @@ +CPU HARD LIMITS FOR CFS GROUPS +============================== + +1. Overview +2. Interface +3. Examples + +1. Overview +----------- + +CFS is a proportional share scheduler which tries to divide the CPU time +proportionately between tasks or groups of tasks (task group/cgroup) depending +on the priority/weight of the task or shares assigned to groups of tasks. +In CFS, a task/task group can get more than its share of CPU if there are +enough idle CPU cycles available in the system, due to the work conserving +nature of the scheduler. However in certain scenarios (like pay-per-use), +it is desirable not to provide extra time to a group even in the presence +of idle CPU cycles. This is where hard limiting can be of use. + +Hard limits for task groups can be set by specifying how much CPU runtime a +group can consume within a given period. If the group consumes more CPU time +than the runtime in a given period, it gets throttled. None of the tasks of +the throttled group gets to run until the runtime of the group gets refreshed +at the beginning of the next period. + +2. Interface +------------ + +Hard limit feature adds 3 cgroup files for CFS group scheduler: + +cfs_runtime_us: Hard limit for the group in microseconds. + +cfs_period_us: Time period in microseconds within which hard limits is +enforced. + +cfs_hard_limit: The control file to enable or disable hard limiting for the +group. + +A group gets created with default values for runtime and period and with +hard limit disabled. Each group can set its own values for runtime and period +independent of other groups in the system. + +3. Examples +----------- + +# mount -t cgroup -ocpu none /cgroups/ +# cd /cgroups +# mkdir 1 +# cd 1/ +# echo 250000 > cfs_runtime_us /* set a 250ms runtime or limit */ +# echo 500000 > cfs_period_us /* set a 500ms period */ +# echo 1 > cfs_hard_limit /* enable hard limiting for group 1/ */