Commit 6f505b16 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

sched: rt group scheduling

Extend group scheduling to also cover the realtime classes. It uses the time
limiting introduced by the previous patch to allow multiple realtime groups.

The hard time limit is required to keep behaviour deterministic.

The algorithms used make the realtime scheduler O(tg), linear scaling wrt the
number of task groups. This is the worst case behaviour I can't seem to get out
of, the avg. case of the algorithms can be improved, I focused on correctness
and worst case.

[ akpm@linux-foundation.org: move side-effects out of BUG_ON(). ]
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent fa85ae24
...@@ -130,12 +130,13 @@ extern struct group_info init_groups; ...@@ -130,12 +130,13 @@ extern struct group_info init_groups;
.normal_prio = MAX_PRIO-20, \ .normal_prio = MAX_PRIO-20, \
.policy = SCHED_NORMAL, \ .policy = SCHED_NORMAL, \
.cpus_allowed = CPU_MASK_ALL, \ .cpus_allowed = CPU_MASK_ALL, \
.nr_cpus_allowed = NR_CPUS, \
.mm = NULL, \ .mm = NULL, \
.active_mm = &init_mm, \ .active_mm = &init_mm, \
.rt = { \ .rt = { \
.run_list = LIST_HEAD_INIT(tsk.rt.run_list), \ .run_list = LIST_HEAD_INIT(tsk.rt.run_list), \
.time_slice = HZ, }, \ .time_slice = HZ, \
.nr_cpus_allowed = NR_CPUS, \
}, \
.ioprio = 0, \ .ioprio = 0, \
.tasks = LIST_HEAD_INIT(tsk.tasks), \ .tasks = LIST_HEAD_INIT(tsk.tasks), \
.ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children), \ .ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children), \
......
...@@ -934,6 +934,15 @@ struct sched_rt_entity { ...@@ -934,6 +934,15 @@ struct sched_rt_entity {
struct list_head run_list; struct list_head run_list;
unsigned int time_slice; unsigned int time_slice;
unsigned long timeout; unsigned long timeout;
int nr_cpus_allowed;
#ifdef CONFIG_FAIR_GROUP_SCHED
struct sched_rt_entity *parent;
/* rq on which this entity is (to be) queued: */
struct rt_rq *rt_rq;
/* rq "owned" by this entity/group: */
struct rt_rq *my_q;
#endif
}; };
struct task_struct { struct task_struct {
...@@ -978,7 +987,6 @@ struct task_struct { ...@@ -978,7 +987,6 @@ struct task_struct {
unsigned int policy; unsigned int policy;
cpumask_t cpus_allowed; cpumask_t cpus_allowed;
int nr_cpus_allowed;
#ifdef CONFIG_PREEMPT_RCU #ifdef CONFIG_PREEMPT_RCU
int rcu_read_lock_nesting; int rcu_read_lock_nesting;
......
...@@ -1246,7 +1246,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, ...@@ -1246,7 +1246,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
* parent's CPU). This avoids alot of nasty races. * parent's CPU). This avoids alot of nasty races.
*/ */
p->cpus_allowed = current->cpus_allowed; p->cpus_allowed = current->cpus_allowed;
p->nr_cpus_allowed = current->nr_cpus_allowed; p->rt.nr_cpus_allowed = current->rt.nr_cpus_allowed;
if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed) || if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed) ||
!cpu_online(task_cpu(p)))) !cpu_online(task_cpu(p))))
set_task_cpu(p, smp_processor_id()); set_task_cpu(p, smp_processor_id());
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment