Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-s…
Browse files Browse the repository at this point in the history
…ched

* git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched:
  sched: rt-group: refure unrunnable tasks
  sched: rt-group: clean up the ifdeffery
  sched: rt-group: make rt groups scheduling configurable
  sched: rt-group: interface
  sched: rt-group: deal with PI
  sched: fix incorrect irq lock usage in normalize_rt_tasks()
  sched: fair-group: separate tg->shares from task_group_lock
  hrtimer: more hrtimer_init_sleeper() fallout.
  • Loading branch information
Linus Torvalds committed Feb 13, 2008
2 parents d7ab95f + b68aa23 commit 3174ffa
Show file tree
Hide file tree
Showing 9 changed files with 576 additions and 209 deletions.
59 changes: 59 additions & 0 deletions Documentation/sched-rt-group.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@


Real-Time group scheduling.

The problem space:

In order to schedule multiple groups of realtime tasks each group must
be assigned a fixed portion of the CPU time available. Without a minimum
guarantee a realtime group can obviously fall short. A fuzzy upper limit
is of no use since it cannot be relied upon. Which leaves us with just
the single fixed portion.

CPU time is divided by means of specifying how much time can be spent
running in a given period. Say a frame fixed realtime renderer must
deliver 25 frames a second, which yields a period of 0.04s. Now say
it will also have to play some music and respond to input, leaving it
with around 80% for the graphics. We can then give this group a runtime
of 0.8 * 0.04s = 0.032s.

This way the graphics group will have a 0.04s period with a 0.032s runtime
limit.

Now if the audio thread needs to refill the DMA buffer every 0.005s, but
needs only about 3% CPU time to do so, it can do with a 0.03 * 0.005s
= 0.00015s.


The Interface:

system wide:

/proc/sys/kernel/sched_rt_period_ms
/proc/sys/kernel/sched_rt_runtime_us

CONFIG_FAIR_USER_SCHED

/sys/kernel/uids/<uid>/cpu_rt_runtime_us

or

CONFIG_FAIR_CGROUP_SCHED

/cgroup/<cgroup>/cpu.rt_runtime_us

[ time is specified in us because the interface is s32; this gives an
operating range of ~35m to 1us ]

The period takes values in [ 1, INT_MAX ], runtime in [ -1, INT_MAX - 1 ].

A runtime of -1 specifies runtime == period, ie. no limit.

New groups get the period from /proc/sys/kernel/sched_rt_period_us and
a runtime of 0.

Settings are constrained to:

\Sum_{i} runtime_{i} / global_period <= global_runtime / global_period

in order to keep the configuration schedulable.
2 changes: 1 addition & 1 deletion include/linux/cgroup_subsys.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ SUBSYS(ns)

/* */

#ifdef CONFIG_FAIR_CGROUP_SCHED
#ifdef CONFIG_CGROUP_SCHED
SUBSYS(cpu_cgroup)
#endif

Expand Down
18 changes: 12 additions & 6 deletions include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ struct user_struct {
struct hlist_node uidhash_node;
uid_t uid;

#ifdef CONFIG_FAIR_USER_SCHED
#ifdef CONFIG_USER_SCHED
struct task_group *tg;
#ifdef CONFIG_SYSFS
struct kobject kobj;
Expand Down Expand Up @@ -973,7 +973,7 @@ struct sched_rt_entity {
unsigned long timeout;
int nr_cpus_allowed;

#ifdef CONFIG_FAIR_GROUP_SCHED
#ifdef CONFIG_RT_GROUP_SCHED
struct sched_rt_entity *parent;
/* rq on which this entity is (to be) queued: */
struct rt_rq *rt_rq;
Expand Down Expand Up @@ -1541,8 +1541,6 @@ extern unsigned int sysctl_sched_child_runs_first;
extern unsigned int sysctl_sched_features;
extern unsigned int sysctl_sched_migration_cost;
extern unsigned int sysctl_sched_nr_migrate;
extern unsigned int sysctl_sched_rt_period;
extern unsigned int sysctl_sched_rt_ratio;
#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP)
extern unsigned int sysctl_sched_min_bal_int_shares;
extern unsigned int sysctl_sched_max_bal_int_shares;
Expand All @@ -1552,6 +1550,8 @@ int sched_nr_latency_handler(struct ctl_table *table, int write,
struct file *file, void __user *buffer, size_t *length,
loff_t *ppos);
#endif
extern unsigned int sysctl_sched_rt_period;
extern int sysctl_sched_rt_runtime;

extern unsigned int sysctl_sched_compat_yield;

Expand Down Expand Up @@ -2027,16 +2027,22 @@ extern int sched_mc_power_savings, sched_smt_power_savings;

extern void normalize_rt_tasks(void);

#ifdef CONFIG_FAIR_GROUP_SCHED
#ifdef CONFIG_GROUP_SCHED

extern struct task_group init_task_group;

extern struct task_group *sched_create_group(void);
extern void sched_destroy_group(struct task_group *tg);
extern void sched_move_task(struct task_struct *tsk);
#ifdef CONFIG_FAIR_GROUP_SCHED
extern int sched_group_set_shares(struct task_group *tg, unsigned long shares);
extern unsigned long sched_group_shares(struct task_group *tg);

#endif
#ifdef CONFIG_RT_GROUP_SCHED
extern int sched_group_set_rt_runtime(struct task_group *tg,
long rt_runtime_us);
extern long sched_group_rt_runtime(struct task_group *tg);
#endif
#endif

#ifdef CONFIG_TASK_XACCT
Expand Down
23 changes: 17 additions & 6 deletions init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -311,25 +311,36 @@ config CPUSETS

Say N if unsure.

config FAIR_GROUP_SCHED
bool "Fair group CPU scheduler"
config GROUP_SCHED
bool "Group CPU scheduler"
default y
help
This feature lets CPU scheduler recognize task groups and control CPU
bandwidth allocation to such task groups.

config FAIR_GROUP_SCHED
bool "Group scheduling for SCHED_OTHER"
depends on GROUP_SCHED
default y

config RT_GROUP_SCHED
bool "Group scheduling for SCHED_RR/FIFO"
depends on EXPERIMENTAL
depends on GROUP_SCHED
default n

choice
depends on FAIR_GROUP_SCHED
depends on GROUP_SCHED
prompt "Basis for grouping tasks"
default FAIR_USER_SCHED
default USER_SCHED

config FAIR_USER_SCHED
config USER_SCHED
bool "user id"
help
This option will choose userid as the basis for grouping
tasks, thus providing equal CPU bandwidth to each user.

config FAIR_CGROUP_SCHED
config CGROUP_SCHED
bool "Control groups"
depends on CGROUPS
help
Expand Down
5 changes: 4 additions & 1 deletion kernel/rtmutex.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,9 +630,12 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state,
set_current_state(state);

/* Setup the timer, when timeout != NULL */
if (unlikely(timeout))
if (unlikely(timeout)) {
hrtimer_start(&timeout->timer, timeout->timer.expires,
HRTIMER_MODE_ABS);
if (!hrtimer_active(&timeout->timer))
timeout->task = NULL;
}

for (;;) {
/* Try to acquire the lock: */
Expand Down
Loading

0 comments on commit 3174ffa

Please sign in to comment.